前言:
(单向)链表的基本介绍
链表是在物理上(内存空间)非连续,非顺序的一种数据结构
- 在C语言中,简单来说,是用
结构体
和指针
来实现链表(linkNode)结构的。- 结构体:节点
- 指针:箭头(负责链接两个节点)
接下来,通过一个题目(涉及到链表的全部基础操作),来学习链表的基础操作!
目录
Part1:题目描述
题目描述:
输入文件的第一行有两个整数n,q,分别表示初始链表中元素个数和对链表操作的次数,第二行有n个整数,表示初始链表的元素,保证这些数字不超过int表示的取值范围。接下来q行,每行可能为如下两个操作之一:
1 a b表示在第a个元素后面插入值为b的元素,
2 a表示将链表中第a个元素删除,如果a大于当时链表长度,则忽略此操作
输入说明
输入第一行是2个整数数字,表示n和q;第二行是n个整数,其间用一个半角空格间隔;接下来有q行数字,以1开头表示插入操作,以2开头表示删除操作。
输出说明
输出有1行,表示操作后的链表的所有结点的数据,数字间用一个半角空格间隔。若链表为空,输出”空”。
输入样例
3 3
1 2 3
1 1 4
1 2 5
2 2
输出样例
1 5 2 3
Part2:结构体重命名
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node* next;
}NODE;
Part3:主函数部分
int main()
{
int num_node = 0, num_oprt = 0;
scanf("%d %d", &num_node, &num_oprt);
NODE* head = create_linklist(num_node);//创建链表
for (int i = 0; i < num_oprt; i++)
{
int way_oprt = 0;
scanf("%d", &way_oprt);
switch (way_oprt)
{
case 1:
{
int pos = 0;
int data = 0;
scanf("%d %d", &pos, &data);
if (pos > num_node) {
break;
}
else {
head = insert_node(head, pos, data);
}
break;
}
case 2:
{
int pos = 0;
scanf("%d", &pos);
if (pos > num_node)
{
break;
}
else
{
delete_node(head, pos);
}
break;
}
}
}
if (head == NULL)
printf("空");
else
print_linklist(head);
return 0;
}
Part4:创建链表函数实现:create_linklist()
struct node* create_linklist(int n)//创建n个结点的链表,返回表头
{
NODE *head = NULL, * q = NULL, * p = NULL;
for (int i = 0; i < n; i++)
{
p = (NODE*)malloc(sizeof(NODE));
scanf("%d", &p->data);
if (i == 0)
{
head = p;
}
else
{
q->next = p;
}
q = p;
}
p->next = NULL;
return head;
}
Part5:插入/增加节点:insert_node()
struct node* insert_node(struct node* head, int pos, int data)//在以head为头的链表中第post的位置插入数据data,返回表头
{
NODE* p = head, * q = head;
NODE* new_node = (NODE*)malloc(sizeof(NODE));
new_node->data = data;
for (int i = 1; i <= pos; i++)//循环结束后q指向的是第pos个,p指向的是第pos个的后一个
{
q = p;
p = p->next;
}
if (p == NULL)
{
p->next = new_node;
new_node->next = NULL;
}
else
{
q->next = new_node;
new_node->next = p;
}
return head;
}
Part6:删除节点-delete_node()
struct node* delete_node(struct node* head, int pos)//在以head为头的链表中删除第post的位置的结点,返回表头
{
NODE* q = head, * p = head;
if (pos == 1)
return head->next;
for (int i = 2; i <= pos; i++)//这里要稍微注意一下:使循环结束后,q指向的是第pos个前,p指向的是第pos个
{
q = p;
p = p->next;
}
if (p == NULL)
{
q->next = NULL;
}
else
{
q->next = p->next;
free(p);
}
return head;
}
Part7:打印链表
void print_linklist(struct node* head)//输出以head为头的链表的所有结点数据
{
NODE* p = head;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
Part8:完整代码复现
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node* next;
}NODE;
struct node* create_linklist(int n)//创建n个结点的链表,返回表头
{
NODE *head = NULL, * q = NULL, * p = NULL;
for (int i = 0; i < n; i++)
{
p = (NODE*)malloc(sizeof(NODE));
scanf("%d", &p->data);
if (i == 0)
{
head = p;
}
else
{
q->next = p;
}
q = p;
}
p->next = NULL;
return head;
}
struct node* insert_node(struct node* head, int pos, int data)//在以head为头的链表中第post的位置插入数据data,返回表头
{
NODE* p = head, * q = head;
NODE* new_node = (NODE*)malloc(sizeof(NODE));
new_node->data = data;
for (int i = 1; i <= pos; i++)//循环结束后q指向的是第pos个,p指向的是第pos个的后一个
{
q = p;
p = p->next;
}
if (p == NULL)
{
p->next = new_node;
new_node->next = NULL;
}
else
{
q->next = new_node;
new_node->next = p;
}
return head;
}
struct node* delete_node(struct node* head, int pos)//在以head为头的链表中删除第post的位置的结点,返回表头
{
NODE* q = head, * p = head;
if (pos == 1)
return head->next;
for (int i = 2; i <= pos; i++)//这里要稍微注意一下:使循环结束后,q指向的是第pos个前,p指向的是第pos个
{
q = p;
p = p->next;
}
if (p == NULL)
{
q->next = NULL;
}
else
{
q->next = p->next;
free(p);
}
return head;
}
void print_linklist(struct node* head)//输出以head为头的链表的所有结点数据
{
NODE* p = head;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
int main()
{
int num_node = 0, num_oprt = 0;
scanf("%d %d", &num_node, &num_oprt);
NODE* head = create_linklist(num_node);//创建链表
for (int i = 0; i < num_oprt; i++)
{
int way_oprt = 0;
scanf("%d", &way_oprt);
switch (way_oprt)
{
case 1:
{
int pos = 0;
int data = 0;
scanf("%d %d", &pos, &data);
if (pos > num_node) {
break;
}
else {
head = insert_node(head, pos, data);
}
break;
}
case 2:
{
int pos = 0;
scanf("%d", &pos);
if (pos > num_node)
{
break;
}
else
{
delete_node(head, pos);
}
break;
}
}
}
if (head == NULL)
printf("空");
else
print_linklist(head);
return 0;
}
Part9:细节
💫1,typedef重定义后不用再像之前一样单独声明结构体类型了(否则会重定义)
💫2,case语句中如果有定义或者声明局部变量需要加大括号(语法规定)
💫3,在删除、插入函数中处理结点时要格外小心两个指针q和p循环结束后所指向的位置。
原创不易,如果对你有所帮助,还请三连+关注!我是瑶瑶子,持续输出优质文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/142474.html