1,循环链表的初始化
定义一个头结点和尾指针的方式,头结点在这里是用来连接 第一个结点和最后一个结点的结点
1 #include<stdio.h>
2 #include<stdlib.h>
3
4 typedef struct Link {
5 int data;
6 struct node* next;
7 }link;
8
9 link* head_node; //声明一个头结点
10 link* ptail; //声明一个尾指针
11
12 link* initLink() //初始化循环链表
13 {
14 link* new_node;
15 head_node = (link*)malloc(sizeof(link));
16 ptail = head_node; //尾指针指向头结点
17
18 //初始化创建10个结点的循环链表
19 for (int i = 0; i < 10; i++)
20 {
21 link* new_node = (link*)malloc(sizeof(link));
22 ptail->next = new_node;//把新节点接到链表上去,相当于head_node->next = new_node,但这里不能使用head_node->next,而是使用ptail->next,因为头结点不能动
23
24 new_node->data = i;//给新申请的结点赋值
25 new_node->next = head_node; //新申请的结点是尾结点,指针域指向头结点,构成尾连接头的单向循环
26
27 ptail = new_node;//尾指针后移指向新节点
28 }
29 //printf("头结点中的数据是:%d\n", head_node->data); //-842150451,头结点中没有值,头结点只是连接第一个结点和尾结点的结点
30 return head_node;
31 }
32 void showLink(link* headNode) //输出循环链表的所有元素
33 {
34 link* tmp = headNode->next;//tmp是指针类型,值是头结点的指针域中保存的值,所以tmp指针指向头结点的下一个结点
35 while (tmp != headNode){ //tmp指针从头结点的下一个结点开始后移,直到指向头结点(此时已经遍历一遍循环链表)
36 printf(" %d ", tmp->data);//打印出tmp所指向结点的数据,tmp指向某个结点的写法是tmp=node,因此tmp->data,就等于是node->data,tmp->data可以打印出所指向结点的数据
37 tmp = tmp->next;//tmp指针后移
38 }
39 printf("\n");
40 }
41
42
43 void main()
44 {
45 head_node = initLink(); //获取初始化后的头结点
46 printf("初始化后的链表是:\n");
47 showLink(head_node);
48 }

2,删除指定位置处的结点
4 #include<stdio.h>
5 #include<stdlib.h>
6
7 typedef struct Link {
8 int data;
9 struct node* next;
10 }link;
11
12 link* head_node; //声明一个头结点
13 link* ptail; //声明一个尾指针
14
15 link* initLink() //初始化循环链表
16 {
17 link* new_node;
18 head_node = (link*)malloc(sizeof(link));
19 ptail = head_node; //尾指针指向头结点
20
21 //初始化创建10个结点的循环链表
22 for (int i = 0; i < 10; i++)
23 {
24 link* new_node = (link*)malloc(sizeof(link));
25 ptail->next = new_node;//把新节点接到链表上去,相当于head_node->next = new_node,但这里不能使用head_node->next,而是使用ptail->next,因为头结点不能动
26
27 new_node->data = i;//给新申请的结点赋值
28 new_node->next = head_node; //新申请的结点是尾结点,指针域指向头结点,构成尾连接头的单向循环
29
30 ptail = new_node;//尾指针后移指向新节点
31 }
32 //printf("头结点中的数据是:%d\n", head_node->data); //-842150451,头结点中没有值,头结点只是连接第一个结点和尾结点的结点
33 return head_node;
34 }
35
36
37 void showLink(link* headNode) //输出循环链表的所有元素
38 {
39 link* tmp = headNode->next;//tmp是指针类型,值是头结点的指针域中保存的值,所以tmp指针指向头结点的下一个结点
40 while (tmp != headNode){ //tmp指针从头结点的下一个结点开始后移,直到指向头结点(此时已经遍历一遍循环链表)
41 printf(" %d ", tmp->data);//打印出tmp所指向结点的数据,tmp指向某个结点的写法是tmp=node,因此tmp->data,就等于是node->data,tmp->data可以打印出所指向结点的数据
42 tmp = tmp->next;//tmp指针后移
43 }
44 printf("\n");
45 }
46
47
48
49 //删除位置num处的节点
50 void delNode(link* headNode, int num)
51 {
52 link* p, * q; //p,q 是两个link型的指针
53 p = headNode->next;//把头结点的指针域赋给p,p就指向头结点的下一个结点(第一个结点)
54 int j = 0; //计数器
55 while (p != headNode) //p不指向头结点的情况下
56 {
57 j++;
58 p = p->next; //p从指向第一个结点开始后移,while循环遍历一次可以知道表的长度(j的值)
59 }
60 if (num<1 || num>j) // 删除的结点是大于等于1,小于等于表长
61 {
62 printf("删除位置出错\n");
63 return -1;
64 }
65
66 p = headNode; //p重新指向头结点
67 link* r;
68 for (j = 1; j < num; j++) {
69 p = p->next;
70 } //j=num时会结束for循环,此时p指向了第num-1个结点
71 q = p->next;//q是第num个结点,是p的下一个结点
72 r = q;
73 p->next = r->next; //删除q结点后,通过 r 把链表再接回去
74 free(q);
75 76 }
77
78
79
80 void main()
81 {
82 head_node = initLink(); //获取初始化后的头结点
83 printf("初始化后的链表是:\n");
84 showLink(head_node);
85
86 printf("删除第四个结点后的链表是:\n");
87 delNode(head_node, 4);
88 showLink(head_node);
89
90 }
3,查询指定位置处的结点的下一个结点
#include<stdio.h>
#include<stdlib.h>
typedef struct Link {
int data;
struct node* next;
}link;
link* head_node; //声明一个头结点
link* ptail; //声明一个尾指针
link* initLink() //初始化循环链表
{
link* new_node;
head_node = (link*)malloc(sizeof(link));
ptail = head_node; //尾指针指向头结点
//初始化创建10个结点的循环链表
for (int i = 0; i < 10; i++)
{
link* new_node = (link*)malloc(sizeof(link));
ptail->next = new_node;//把新节点接到链表上去,相当于head_node->next = new_node,但这里不能使用head_node->next,而是使用ptail->next,因为头结点不能动
new_node->data = i;//给新申请的结点赋值
new_node->next = head_node; //新申请的结点是尾结点,指针域指向头结点,构成尾连接头的单向循环
ptail = new_node;//尾指针后移指向新节点
}
//printf("头结点中的数据是:%d\n", head_node->data); //-842150451,头结点中没有值,头结点只是连接第一个结点和尾结点的结点
return head_node;
}
void showLink(link* headNode) //输出循环链表的所有元素
{
link* tmp = headNode->next;//tmp是指针类型,值是头结点的指针域中保存的值,所以tmp指针指向头结点的下一个结点
while (tmp != headNode){ //tmp指针从头结点的下一个结点开始后移,直到指向头结点(此时已经遍历一遍循环链表)
printf(" %d ", tmp->data);//打印出tmp所指向结点的数据,tmp指向某个结点的写法是tmp=node,因此tmp->data,就等于是node->data,tmp->data可以打印出所指向结点的数据
tmp = tmp->next;//tmp指针后移
}
printf("\n");
}
//根据数据返回该处的结点
link* queryNode(link* headNode, int num) {
link* tmp = headNode->next;
while (tmp != headNode) {
if (tmp->data == num) {
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
void main()
{
head_node = initLink(); //获取初始化后的头结点
printf("初始化后的链表是:\n");
showLink(head_node);
link* node = queryNode(head_node, 4)->next;
printf("第4个结点的下一个结点是:%d\n",node->data);
}

4,删除指定位置处的前驱结点
将 上面删除指定位置结点的方法 改用一些即可
#include<stdio.h>
#include<stdlib.h>
typedef struct Link {
int data;
struct node* next;
}link;
link* head_node; //声明一个头结点
link* ptail; //声明一个尾指针
link* initLink() //初始化循环链表
{
link* new_node;
head_node = (link*)malloc(sizeof(link));
ptail = head_node; //尾指针指向头结点
//初始化创建10个结点的循环链表
for (int i = 0; i < 10; i++)
{
link* new_node = (link*)malloc(sizeof(link));
ptail->next = new_node;//把新节点接到链表上去,相当于head_node->next = new_node,但这里不能使用head_node->next,而是使用ptail->next,因为头结点不能动
new_node->data = i;//给新申请的结点赋值
new_node->next = head_node; //新申请的结点是尾结点,指针域指向头结点,构成尾连接头的单向循环
ptail = new_node;//尾指针后移指向新节点
}
//printf("头结点中的数据是:%d\n", head_node->data); //-842150451,头结点中没有值,头结点只是连接第一个结点和尾结点的结点
return head_node;
}
void showLink(link* headNode) //输出循环链表的所有元素
{
link* tmp = headNode->next;//tmp是指针类型,值是头结点的指针域中保存的值,所以tmp指针指向头结点的下一个结点
while (tmp != headNode){ //tmp指针从头结点的下一个结点开始后移,直到指向头结点(此时已经遍历一遍循环链表)
printf(" %d ", tmp->data);//打印出tmp所指向结点的数据,tmp指向某个结点的写法是tmp=node,因此tmp->data,就等于是node->data,tmp->data可以打印出所指向结点的数据
tmp = tmp->next;//tmp指针后移
}
printf("\n");
}
//删除指定结点处的的前驱结点
void delPrior(link* headNode, int num) {
link* p, * q; //p,q 是两个link型的指针
p = headNode->next;//把头结点的指针域赋给p,p就指向头结点的下一个结点(第一个结点)
int j = 0; //计数器
while (p != headNode) //p不指向头结点的情况下
{
j++;
p = p->next; //p从指向第一个结点开始后移,while循环遍历一次可以知道表的长度(j的值)
}
if (num<2 || num>j+1) // 删除的结点是大于等于1,小于等于表长
{
printf("删除位置出错\n");
return -1;
}
p = headNode; //p重新指向头结点
link* r;
for (j = 1; j < num-1; j++) {
p = p->next;
} //j=num时会结束for循环,此时p指向了第num-1个结点
q = p->next;//q是第num个结点,是p的下一个结点
r = q;
p->next = r->next; //删除q结点后,通过 r 把链表再接回去
free(q);
}
void main()
{
head_node = initLink(); //获取初始化后的头结点
printf("初始化后的链表是:\n");
showLink(head_node);
printf("删除第4个结点的前驱结点后的链表是:\n");
delPrior(head_node,4);
showLink(head_node);
}

来源:https://www.cnblogs.com/shanlu0000/p/12508249.html