循环链表区别于单链表的地点就是:未节点的next是头节点地址,所以在节点操作中,涉及到plink->next判断是否为NULL的地方改为判断是否等于plink_header即可。
链表遍历函数中:
while(plink_view->next !=plink_header)
{
printf("%s,%s
",plink_view->num,plink->name);
plink_view=plink_view->next; //指针后移
}
链表数据长度函数中:
while(plink_length->next !=plink_header)
{
length++;
plink_length=plink_length->next; //指针后移
}
1#include <stdio.h>
2 #include <malloc.h>
3 #include <stdlib.h>
4 #include <memory.h>
5
6 //定义学生信息节点
7 typedef struct student_info_node_def
8 {
9 char num[32];//学号
10 char name[32]; //姓名
11 struct student_info_node_def *last; //前指针
12 struct student_info_node_def *next; //后指针
13 }student;
14
15 void list_view(student *plink_header)
16 {
17 student *plink_view=plink_header;
18 //剔除头节点,没有数据
19 plink_view=plink_view->next;
20 while(plink_view->next !=plink_header)
21 {
22 printf("%s,%s
",plink_view->num,plink_view->name);
23 plink_view=plink_view->next; //指针后移
24 }
25 }
26
27 int list_length(student* plink_header)
28 {
29 int length=0;
30 student *plink_length=plink_header;
31 while(plink_length->next !=plink_header)
32 {
33 length++;
34 plink_length=plink_length->next; //指针后移
35 }
36 printf("length=%d
",length);
37 return length;
38 }
39
40 void list_clear(student* plink_header)
41 {
42 printf("是否清空?(1/0):");
43 int order=2;
44 scanf("%d",&order);
45 if(order==1)
46 {
47 plink_header=NULL;
48 printf("完成清空");
49 }
50 else
51 printf("未进行清空操作
");
52 }
53
54 void list_rm(student *plink_header)
55 {
56 printf("是否销毁链表?(1/0):");
57 int ask=2;
58 scanf("%d",&ask);
59 if(ask==1)
60 {
61 free(plink_header);
62 printf("完成销毁");
63 }
64 else
65 printf("未进行销毁操作
");
66 }
67
68 void list_insert(student* plink_header)
69 {
70 //获取链表长度
71 int length=list_length(plink_header);
72 //在第n个节点后插入新节点
73 //1.在哪个节点后插入?
74 int i,n=0;
75 printf("输入插入的位置:");
76 scanf("%d",&n);
77 //2.新节点内容:
78 student *plink_new=(student*)malloc(sizeof(student));
79 sprintf(plink_new->num,"学号%03d",n+11);
80 sprintf(plink_new->name,"姓名%03d",n+11);
81 plink_new->next=NULL;
82 //3.移动链表指针到第n个位置处
83 if((n>0)&&(plink_header !=NULL)) //只有当插入位置合理并且链表存在时,插入操作才合理
84 {
85 student *plink_opt=plink_header;
86 if(n<length) //情况1.插入位置在length之内
87 {
88 for(i=0;i<n-1;i++)
89 {
90 plink_opt=plink_opt->next;
91 }
92 plink_new->next=plink_opt->next;
93 plink_opt->next=plink_new;
94 }
95 if(n>=length) //情况2.插入位置在length之外
96 {
97 for(i=0;i<length;i++)
98 {
99 plink_opt=plink_opt->next;
100 }
101 plink_opt->next=plink_new;
102 }
103 }
104 }
105
106
107 void list_watch(student* plink_header)
108 {
109 int length=list_length(plink_header);
110 int i=0;
111 student *plink_point=plink_header;
112 printf("给出一个查看的节点号(小于%d的值):",length);
113 int point=0;
114 scanf("%d",&point);
115 if((point>0)&&(point<length))
116 {
117 for(i=0;i<point;i++)
118 {
119 plink_point=plink_point->next;
120 }
121 printf("%s,%s
",plink_point->num,plink_point->name);
122 }
123 }
124
125 void list_cancel(student *plink_header)
126 {
127 int length=list_length(plink_header);
128 printf("给出删除节点号:");
129 int i,n=0;
130 scanf("%d",&n);
131 if((n>0)&&(n<=length))
132 {
133 student *plink_cnl=plink_header;
134 for(i=0;i<n-1;i++)
135 {
136 plink_cnl=plink_cnl->next;
137 }
138 plink_cnl->next=plink_cnl->next->next;
139
140 }
141 }
142
143 int main()
144 {
145 /***********************************/
146 //创建头节点
147 int i=0;
148 student *plink_header;
149 plink_header=(student*)malloc(sizeof(student)); //为节点分配空间
150 plink_header->next=NULL; //初始化节点指针
151 /*********************************/
152 //创建新节点
153 student *plink=plink_header;
154 for(;i<8;i++)
155 {
156 student *pnew=NULL;
157 pnew=(student*)malloc(sizeof(student));
158 memset(pnew,0,sizeof(student));
159 sprintf(pnew->num,"学号%03d",i+1);
160 sprintf(pnew->name,"姓名%03d",i+1);
161 pnew->next=NULL;
162 //新节点连接前一个节点
163 plink->next=pnew;
164 plink=pnew;
165 }
166 //链表尾节点指向头节点,从而构成循环链表
167 plink->next=plink_header;
168 /************************************/
169
170 //链表遍历
171 list_view(plink_header);
172
173 /************************************/
174
175 //求链表长度
176 int length=list_length(plink_header);
177
178 /************************************/
179
180 //获取第n个节点上的数据
181 list_watch(plink_header);
182
183 //清空链表
184 list_clear(plink_header);
185
186 //销毁链表
187 list_rm(plink_header);
188
189 //插入节点
190 list_insert(plink_header);
191
192 //遍历链表
193 list_view(plink_header);
194
195 //加入节点之后链表的长度
196 length=list_length(plink_header);
197
198 //删除第n个节点
199 list_cancel(plink_header);
200
201 //遍历链表
202 list_view(plink_header);
203
204 //求链表长度
205 list_length(plink_header);
206 return 0;
207 }