经典算法_链表

1 创建一个链表,包含在尾部插入数据、删除所有结点(清空链表)、逆转链表、排序、统计结点个数、查找、修改的函数。

头文件linknode.h

源文件

源文件main.c

源文件linknode.c

2 创建一个静态链表,实现增加、删除、修改功能

3 创建一个动态链表,实现增加、删除、修改功能

4 创建一个链式栈,实现十进制转换为二进制

头文件stacklinknode.h

源文件

源文件main.c

源文件stacklinknode.h

5 创建一个链队列,实现优先队列

头文件Queue.h

源文件

源文件main.c

源文件Queue.c

1 创建一个链表,包含在尾部插入数据、删除所有结点(清空链表)、逆转链表、排序、统计结点个数、查找、修改的函数。

头文件linknode.h

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 struct student
 5 {
 6     int num;
 7     float score;
 8     struct student *pNext;
 9 };
10 
11 typedef struct student ST;
12 
13 void add(ST **phead, int inum, float iscore);//函数声明,传入头结点的地址,然后插入
14 
15 void showall(ST *head);//传递头结点,显示所有数据
16 
17 ST *rev(ST *head);//实现链表逆转
18 
19 void sort(ST *head, char ch);//ch == '>' 从大到小排序,ch == '<' 从小到大排序,选择排序法不适合,采用冒泡
20 
21 int getnum(ST *head);//获取结点个数
22 
23 ST *search(ST *head, int num);//根据编号查找结点
24 
25 void change(ST *head, int oldnum, int newnum);//查找oldnum,修改为newnum
26 
27 ST *HeadInsert(ST *head, int num, int inum, float iscore);//根据结点,在结点前面插入
28 
29 ST *BackInsert(ST *head, int num, int inum, float iscore);//根据结点,在结点后面插入
30 
31 ST *delete(ST *head, int num);//传入头结点,删除结点的编号,返回头结点

 

源文件main.c

  1 #define _CRT_SECURE_NO_WARNINGS
  2 
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include "linknode.h"
  6 
  7 main1()//清空链表
  8 {
  9     struct student *head = NULL;//头结点指针
 10 
 11     add(&head, 1, 70);
 12     add(&head, 2, 80);
 13     add(&head, 3, 90);
 14     add(&head, 4, 91);
 15     add(&head, 5, 92);
 16 
 17     showall(head);
 18 
 19     head = freeall(head);
 20 
 21     printf("删除以后
");
 22     showall(head);
 23 
 24     system("pause");
 25 }
 26 
 27 main2()//逆转链表
 28 {
 29     struct student *head = NULL;//头结点指针
 30 
 31     add(&head, 1, 70);
 32     add(&head, 2, 80);
 33     add(&head, 3, 90);
 34     add(&head, 4, 91);
 35     add(&head, 5, 92);
 36 
 37     printf("逆转链表前
");
 38     showall(head);
 39 
 40     head = rev(head);//逆转链表
 41     
 42     printf("逆转链表后
");
 43     showall(head);
 44 
 45     system("pause");
 46 }
 47 
 48 main3()//排序
 49 {
 50     struct student *head = NULL;//头结点指针
 51 
 52     add(&head, 10, 70);
 53     add(&head, 2, 80);
 54     add(&head, 30, 90);
 55     add(&head, 4, 91);
 56     add(&head, 50, 92);
 57 
 58     printf("排序前
");
 59     showall(head);
 60 
 61     sort(head, '>');
 62 
 63     printf("排序>后
");
 64     showall(head);
 65     
 66     sort(head, '<');
 67 
 68     printf("排序<后
");
 69     showall(head);
 70 
 71     system("pause");
 72 }
 73 
 74 main4()//统计结点个数
 75 {
 76     struct student *head = NULL;//头结点指针
 77 
 78     add(&head, 1, 70);
 79     add(&head, 2, 80);
 80     add(&head, 3, 90);
 81     add(&head, 4, 91);
 82     add(&head, 5, 92);
 83 
 84     showall(head);
 85 
 86     printf("%d
", getnum(head));//统计结点个数
 87 
 88     system("pause");
 89 }
 90 
 91 main5()//查找
 92 {
 93     struct student *head = NULL;//头结点指针
 94 
 95     add(&head, 1, 70);
 96     add(&head, 2, 80);
 97     add(&head, 3, 90);
 98     add(&head, 4, 91);
 99     add(&head, 5, 92);
100 
101     showall(head);
102 
103     ST *psearch = search(head, 3);
104 
105     printf("%d,%f
", psearch->num, psearch->score);
106 
107     system("pause");
108 }
109 
110 main6()//修改
111 {
112     struct student *head = NULL;//头结点指针
113 
114     add(&head, 1, 70);
115     add(&head, 2, 80);
116     add(&head, 3, 90);
117     add(&head, 4, 91);
118     add(&head, 5, 92);
119 
120     printf("修改前
");
121     showall(head);
122 
123     change(head, 3, 30);
124 
125     printf("修改后
");
126     showall(head);
127 
128     system("pause");
129 }
130 
131 main7()//根据结点,在结点前面、后面插入
132 {
133     struct student *head = NULL;//头结点指针
134 
135     add(&head, 1, 70);
136     add(&head, 2, 80);
137     add(&head, 3, 90);
138     add(&head, 4, 91);
139     add(&head, 5, 92);
140 
141     printf("在结点前面插入前
");
142     showall(head);
143 
144     head = HeadInsert(head, 2, 20, 90.0);
145 
146     printf("在结点前面插入后
");
147     showall(head);
148 
149     printf("在结点后面插入前
");
150     showall(head);
151 
152     head = BackInsert(head, 1, 100, 100.9);
153 
154     printf("在结点后面插入后
");
155     showall(head);
156 
157     system("pause");
158 }
159 
160 main()//传入头结点,删除结点的编号,返回头结点
161 {
162     struct student *head = NULL;//头结点指针
163 
164     add(&head, 1, 70);
165     add(&head, 2, 80);
166     add(&head, 3, 90);
167     add(&head, 4, 91);
168     add(&head, 5, 92);
169 
170     printf("删除结点前
");
171     showall(head);
172 
173     head = delete(head, 3);//删除中间值
174 
175     printf("删除结点后
");
176     showall(head);
177 
178     head = delete(head, 1);//删除第一个
179 
180     printf("删除结点后
");
181     showall(head);
182 
183     head = delete(head, 5);//删除最后一个
184 
185     printf("删除结点后
");
186     showall(head);
187 
188     system("pause");
189 }

 

源文件linknode.c

  1 #include "linknode.h"
  2 
  3 void add(ST **phead, int inum, float iscore)//函数声明,传入头结点的地址,然后插入
  4 {
  5     if (*phead == NULL)
  6     {
  7         ST *newnode = (ST *)malloc(sizeof(ST));//分配内存
  8         if (newnode == NULL)
  9         {
 10             printf("内存分配失败");
 11             return;
 12         }
 13         newnode->num = inum;//结点初始化
 14         newnode->score = iscore;
 15         newnode->pNext = NULL;
 16 
 17         *phead = newnode;//让头指针指向这个结点
 18     }
 19     else
 20     {
 21         //链表不为空,尾部插入
 22         ST *p = *phead;//指向头结点
 23         while (p->pNext != NULL)//循环到最后一个结点的地址
 24         {
 25             p = p->pNext;
 26         }
 27         ST *newnode = (ST *)malloc(sizeof(ST));//分配内存
 28         newnode->num = inum;//结点初始化
 29         newnode->score = iscore;
 30         newnode->pNext = NULL;
 31 
 32         p->pNext = newnode;//链接上
 33     }
 34 }
 35 
 36 void showall(ST *head)//传递头结点,显示所有数据
 37 {
 38     while (head != NULL)//判断指针是否指向为空
 39     {
 40         printf("num=%d,score=%f,%x,%x
", head->num, head->score, head, head->pNext);
 41         head = head->pNext;//指针不断向前循环
 42     }
 43 }
 44 
 45 void *freeall(ST *head)//删除所有结点
 46 {
 47     ST *p1, *p2;
 48     p1 = p2 = NULL;
 49     p1 = head;//头结点
 50 
 51     while (p1->pNext != NULL)//循环遍历所有的结点
 52     {
 53         p2 = p1->pNext;//p2为p1下一个结点
 54         p1->pNext = p2->pNext;//p1存储了p2的下一个结点的地址
 55         free(p2);
 56         printf("
");
 57         showall(head);//显示删除的中间状态
 58     }
 59 
 60     free(head);
 61 
 62     return NULL;
 63 }
 64 
 65 ST *rev(ST *head)
 66 {
 67     ST *p1, *p2, *p3;
 68     p1 = p2 = p3 = NULL;
 69 
 70     if ((head == NULL) || (head->pNext == NULL))//如果只有一个结点,或者链表为空
 71     {
 72         return head;//返回头结点
 73     }
 74 
 75     p1 = head;
 76     p2 = head->pNext;
 77 
 78     while (p2 != NULL)//从第二个到最后一个结点进行循环
 79     {
 80         p3 = p2->pNext;//布局3个结点
 81         p2->pNext = p1;//指向前面一个结点
 82         p1 = p2;//指针向前移动,从第二个到最后一个结点全部指向前面的结点
 83         p2 = p3;
 84     }
 85 
 86     head->pNext = NULL;//代表链表的结束,设置第一个结点指向为空
 87     head = p1;//指向最后一个结点
 88 
 89     return head;//副本机制,改变的head并不会生效,需要返回值赋值生效
 90 }
 91 
 92 void sort(ST *head, char ch)
 93 {
 94     if (ch == '>')
 95     {
 96         for (ST *p1 = head;p1 != NULL;p1 = p1->pNext)//必须用冒泡,必须遍历所有链表,数组可以规避一些无意义的,但是链表必须全部刷一遍
 97         {
 98             for (ST *p2 = head;p2 != NULL;p2 = p2->pNext)
 99             {
100                 if (p1->num < p2->num)
101                 {
102                     ST temp;
103                     temp.num = p1->num;
104                     p1->num = p2->num;
105                     p2->num = temp.num;
106 
107                     temp.score = p1->score;
108                     p1->score = p2->score;
109                     p2->score = temp.score;
110                 }
111             }
112         }
113     }
114     else if (ch == '<')
115     {
116         for (ST *p1 = head;p1 != NULL;p1 = p1->pNext)
117         {
118             for (ST *p2 = head;p2 != NULL;p2 = p2->pNext)
119             {
120                 if (p1->num > p2->num)
121                 {
122                     ST temp;
123                     temp.num = p1->num;
124                     p1->num = p2->num;
125                     p2->num = temp.num;
126 
127                     temp.score = p1->score;
128                     p1->score = p2->score;
129                     p2->score = temp.score;
130                 }
131             }
132         }
133     }
134 }
135 
136 int getnum(ST *head)
137 {
138     int i = 0;
139 
140     while (head != NULL)//判断指针是否指向为空
141     {
142         i++;
143         head = head->pNext;//指针不断向前循环
144     }
145 
146     return i;//统计个数
147 }
148 
149 ST *search(ST *head, int num)//根据编号查找结点
150 {
151     while (head != NULL)//判断指针是否指向为空
152     {
153         if (head->num == num)
154         {
155             return head;//返回当前结点的指针地址
156         }
157         head = head->pNext;//指针不断向前循环
158     }
159 
160     return NULL;//找不到,返回NULL
161 }
162 
163 void change(ST *head, int oldnum, int newnum)//查找oldnum,修改为newnum
164 {
165     ST *psearch = search(head, oldnum);//调用查找函数
166     
167     if (psearch == NULL)
168     {
169         printf("没有找到
");
170     }
171     else
172     {
173         psearch->num = newnum;
174         printf("修改成功
");
175     }
176 }
177 
178 ST *HeadInsert(ST *head, int num, int inum, float iscore)//根据结点,在结点前面插入
179 {
180     ST *p1, *p2;
181     p1 = p2 = NULL;
182     p1 = head;//从头结点开始
183 
184     while (p1 != NULL)//一直循环到最后一个结点
185     {
186         if (p1->num == num)//判断相等
187         {
188             break;
189         }
190         else
191         {
192             p2 = p1;//记录当前结点
193             p1 = p1->pNext;//循环到下一个结点
194         }
195     }
196 
197     if (head == p1)
198     {
199         ST *newnode = (ST *)malloc(sizeof(ST));//分配内存
200         newnode->num = inum;//初始化结点
201         newnode->score = iscore;
202         newnode->pNext = head;//指向第一个结点
203         head = newnode;//newnode成为第一个结点
204     }
205     else
206     {
207         ST *newnode = (ST *)malloc(sizeof(ST));//分配内存
208         newnode->num = inum;//初始化结点
209         newnode->score = iscore;
210         newnode->pNext = p1;//新结点指向p1
211         p2->pNext = newnode;//指向新结点
212     }
213 
214     return head;
215 }
216 
217 ST *BackInsert(ST *head, int num, int inum, float iscore)//根据结点,在结点后面插入
218 {
219     ST *p1, *p2;
220     p1 = p2 = NULL;
221     p1 = head;//从头结点开始
222 
223     while (p1 != NULL)//一直循环到最后一个结点
224     {
225         if (p1->num == num)//判断相等
226         {
227             break;
228         }
229         else
230         {
231             p1 = p1->pNext;//循环到下一个结点
232         }
233     }
234 
235     if (p1->pNext == NULL)//最后一个结点
236     {
237         ST *newnode = (ST *)malloc(sizeof(ST));//分配内存
238         newnode->num = inum;//初始化结点
239         newnode->score = iscore;
240         newnode->pNext = NULL;//指针域此时为空,代表最后一个结点
241         p1->pNext = newnode;//指向新开辟的结点
242     }
243     else
244     {
245         p2 = p1->pNext;//记录下一个结点的位置
246         ST *newnode = (ST *)malloc(sizeof(ST));//分配内存
247         newnode->num = inum;//初始化结点
248         newnode->score = iscore;
249         newnode->pNext = p2;//链接下一个结点
250         p1->pNext = newnode;//指向新结点
251     }
252 
253     return head;
254 }
255 
256 ST *delete(ST *head, int num)//传入头结点,删除结点的编号,返回头结点
257 {
258     ST *p1, *p2;
259     p1 = p2 = NULL;
260     p1 = head;//从头结点开始循环
261 
262     while (p1 != NULL)
263     {
264         if (p1->num == num)//判断是否相等
265         {
266             break;
267         }
268         else
269         {
270             p2 = p1;//记录当前结点
271             p1 = p1->pNext;//继续往后循环
272         }
273     }
274 
275     if (p1 == head)//要删除的在头结点
276     {
277         head = p1->pNext;//跳过头结点
278         free(p1);//释放第一个结点
279     }
280     else
281     {
282         p2->pNext = p1->pNext;//跳过p1
283         free(p1);//释放
284     }
285 
286     return head;
287 }

 

2 创建一个静态链表,实现增加、删除、修改功能

 1 #define _CRT_SECURE_NO_WARNINGS
 2 
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 
 6 struct Node
 7 {
 8     int num;
 9     struct Node *pNext;
10 };
11 
12 //链表增加,删除,修改,不需要移动,直接操作
13 //查询与修改,无法像数组定位位置,需要用循环的方式来定位,查找与修改相对麻烦
14 
15 main()
16 {
17     struct Node *p = NULL;//存储指针的开头
18     struct Node n1, n2, n3, n4, n5;
19     
20     n1.num = 1;
21     n2.num = 2;
22     n3.num = 3;
23     n4.num = 4;
24     n5.num = 5;
25     
26     p = &n1;//串联结构体
27     n1.pNext = &n2;
28     n2.pNext = &n3;
29     n3.pNext = &n4;
30     n4.pNext = &n5;
31     n5.pNext = NULL;
32 
33     struct Node *px = p;//创建一个指针副本,保存头结点的地址
34 
35     printf("删除前
");
36     while (p != NULL)//为空,指针访问结束
37     {
38         printf("num=%d,%x
", p->num, p);//访问数据
39         p = p->pNext;//指针往后移动
40     }
41     
42     //删除,删除某个结点
43     n2.pNext = &n4;//实现了删除n3结点,链表的删除非常方便,不需要移动
44 
45     p = px;
46     printf("删除,删除某个结点
");
47     while (p != NULL)//为空,指针访问结束
48     {
49         printf("num=%d,%x
", p->num, p);//访问数据
50         p = p->pNext;//指针往后移动
51     }
52 
53     //增加,尾部插入
54     struct Node n6;
55     n6.num = 6;
56     n6.pNext = NULL;//链接起来
57 
58     n5.pNext = &n6;
59 
60     p = px;
61     printf("增加,尾部插入
");
62     while (p != NULL)//为空,指针访问结束
63     {
64         printf("num=%d,%x
", p->num, p);//访问数据
65         p = p->pNext;//指针往后移动
66     }
67 
68     //增加,2-4之间插入一个10
69     struct Node n7;//插入不需要移动,改变指向即可
70     n7.num = 10;
71     
72     n2.pNext = &n7;
73     n7.pNext = &n4;
74 
75     p = px;
76     printf("增加,2-4之间插入一个10
");
77     while (p != NULL)//为空,指针访问结束
78     {
79         printf("num=%d,%x
", p->num, p);//访问数据
80         p = p->pNext;//指针往后移动
81     }
82 
83     //修改,把10改成8
84     p = px;
85     printf("修改,把10改成8
");
86     while (p != NULL)//为空,指针访问结束
87     {
88         if (p->num == 10)
89         {
90             p->num = 8;
91         }
92         printf("num=%d,%x
", p->num, p);//访问数据
93         p = p->pNext;//指针往后移动
94     }
95 
96     system("pause");
97 }

3 创建一个动态链表,实现增加、删除、修改功能

  1 #define _CRT_SECURE_NO_WARNINGS
  2 
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 
  6 struct Node
  7 {
  8     int num;
  9     struct Node *pNext;
 10 };
 11 
 12 //动态链表,删除、插入非常容易,不需要移动
 13 //查询、修改,非常麻烦,无法像数组,需要循环遍历所有的结点
 14 
 15 main()
 16 {
 17     struct Node *p = NULL;//头指针
 18     struct Node *p1, *p2, *p3, *p4, *p5;//创建5个结点指针
 19 
 20     p1 = (struct Node *)malloc(sizeof(struct Node));//分配内存
 21     p2 = (struct Node *)malloc(sizeof(struct Node));
 22     p3 = (struct Node *)malloc(sizeof(struct Node));
 23     p4 = (struct Node *)malloc(sizeof(struct Node));
 24     p5 = (struct Node *)malloc(sizeof(struct Node));
 25 
 26     p1->num = 1;//初始化结点数据
 27     p2->num = 2;
 28     p3->num = 3;
 29     p4->num = 4;
 30     p5->num = 5;
 31 
 32     p = p1;//进行链接
 33     p1->pNext = p2;
 34     p2->pNext = p3;
 35     p3->pNext = p4;
 36     p4->pNext = p5;
 37     p5->pNext = NULL;
 38 
 39     struct Node *px = p;//副本指针
 40 
 41     while (p != NULL)
 42     {
 43         printf("num=%d
", p->num);
 44         p = p->pNext;
 45     }
 46 
 47     //修改
 48     p = px;
 49     printf("修改,修改以后
");
 50     while (p != NULL)
 51     {
 52         if (p->num == 3)
 53         {
 54             p->num = 30;
 55         }
 56         printf("num=%d
", p->num);
 57         p = p->pNext;
 58     }
 59 
 60     //删除
 61     p2->pNext = p4;
 62     free(p3);
 63 
 64     p = px;
 65     printf("删除,删除以后
");
 66     while (p != NULL)
 67     {
 68         printf("num=%d
", p->num);
 69         p = p->pNext;
 70     }
 71 
 72     //插入,尾部插入
 73     struct Node *p6;
 74     p6 = (struct Node *)malloc(sizeof(struct Node));
 75     p6->num = 6;
 76     p6->pNext = NULL;
 77 
 78     p5->pNext = p6;//尾部插入
 79 
 80     p = px;
 81     printf("插入,尾部插入
");
 82     while (p != NULL)
 83     {
 84         printf("num=%d
", p->num);
 85         p = p->pNext;
 86     }
 87 
 88     //插入,中间插入
 89     struct Node *p10;
 90     p10 = (struct Node *)malloc(sizeof(struct Node));
 91     p10->num = 10;
 92     p10->pNext = p4;
 93 
 94     p2->pNext = p10;
 95 
 96     p = px;
 97     printf("插入,中间插入
");
 98     while (p != NULL)
 99     {
100         printf("num=%d
", p->num);
101         p = p->pNext;
102     }
103 
104     system("pause");
105 }

4 创建一个链式栈,实现十进制转换为二进制

头文件stacklinknode.h

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 struct stacknode
 5 {
 6     int num;
 7     int data;
 8     struct stacknode *pNext;//指针域
 9 };
10 
11 typedef struct stacknode StackNode;//简写
12 
13 StackNode *init(StackNode *phead);//初始化
14 
15 StackNode *push(StackNode *phead, int num, int data);//进栈,增加头结点,返回头结点
16 
17 StackNode *printfall(StackNode *phead);//全部打印
18 
19 StackNode *pop(StackNode *phead, StackNode *poutdata);//出栈
20 
21 StackNode *freeall(StackNode *phead);//清空

源文件

源文件main.c

 1 #define _CRT_SECURE_NO_WARNINGS
 2 
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 #include "stacklinknode.h"
 6 
 7 main1()
 8 {
 9     StackNode *phead = NULL;//创建一个链式栈的头结点
10 
11     phead = init(phead);//设置栈为空
12 
13     phead = push(phead, 1, 1);
14     phead = push(phead, 2, 11);
15     phead = push(phead, 3, 111);
16     phead = push(phead, 4, 1111);
17     phead = push(phead, 5, 11111);
18 
19     printf("进栈以后
");
20     printfall(phead);//全部打印
21 
22     printf("清空以后
");
23     phead = freeall(phead);
24     printfall(phead);//全部打印
25 
26     //while (phead->pNext != NULL)
27     //{
28     //    printf("出栈
");
29     //    StackNode *pout = (StackNode *)malloc(sizeof(StackNode));
30     //    phead = pop(phead, pout);
31     //    printf("出栈以后
");
32     //    printfall(phead);//全部打印
33     //    printf("出栈以后的数据%d,%d
", pout->num, pout->data);
34     //}
35 
36     system("pause");
37 }
38 
39 main()
40 {
41     int num;
42     scanf("%d", &num);
43     printf("num=%d
", num);
44     StackNode *phead = NULL;//创建一个链式栈的头结点
45     
46     while (num)//进栈
47     {
48         phead = push(phead, num % 2, 0);
49         num /= 2;
50     }
51 
52     while (phead != NULL)//出栈
53     {
54         StackNode *pout = (StackNode *)malloc(sizeof(StackNode));
55         phead = pop(phead, pout);
56 
57         printf("%d", pout->num);
58     }
59 
60     system("pause");
61 }

源文件stacklinknode.c

 1 #include "stacklinknode.h"
 2 
 3 StackNode *init(StackNode *phead)//初始化
 4 {
 5     return NULL;
 6 }
 7 
 8 StackNode *push(StackNode *phead, int num, int data)//进栈,增加头结点,返回头结点
 9 {
10     StackNode *pnewnode = (StackNode *)malloc(sizeof(StackNode));
11 
12     pnewnode->num = num;
13     pnewnode->data = data;
14     pnewnode->pNext = NULL;//开辟结点并赋值
15     
16     if (phead == NULL)//空链表,直接连接上
17     {
18         phead = pnewnode;//连接一个结点
19     }
20     else
21     {
22         StackNode *p = phead;
23         while (p->pNext != NULL)
24         {
25             p = p->pNext;//一直向前
26         }
27         p->pNext = pnewnode;//插入
28     }
29 
30     return phead;
31 }
32 
33 StackNode *printfall(StackNode *phead)//全部打印
34 {
35     if (phead == NULL)
36     {
37         return NULL;
38     }
39     else
40     {
41         printf("%d,%d,%x,%x
", phead->num, phead->pNext, phead, phead->pNext);
42         printfall(phead->pNext);
43     }
44 }
45 
46 StackNode *pop(StackNode *phead, StackNode *poutdata)//出栈
47 {
48     if (phead == NULL)//已经没有元素
49     {
50         return NULL;
51     }
52     else if (phead->pNext == NULL)//只有一个结点
53     {
54         poutdata->num = phead->num;//取出数据
55         poutdata->data = phead->data;
56         free(phead);
57         phead = NULL;
58         return NULL;
59     }
60     else
61     {
62         StackNode *p = phead;//建立指针,返回指针
63         while (p->pNext->pNext != NULL)
64         {
65             p = p->pNext;//循环到倒数第二个结点
66         }
67         poutdata->num = p->pNext->num;//取出数据
68         poutdata->data = p->pNext->data;
69         free(p->pNext);
70         p->pNext = NULL;
71     }
72 }
73 
74 StackNode *freeall(StackNode *phead)//清空,算法思想:先把p1后面的结点删除,最后把p1删除
75 {
76     if (phead == NULL)
77     {
78         return NULL;
79     }
80     else
81     {
82         StackNode *p1 = NULL, *p2 = NULL;
83         p1 = phead;//头结点
84         
85         while (p1->pNext != NULL)
86         {
87             p2 = p1->pNext;//保存下一个结点
88             p1->pNext = p2->pNext;//跳过p2
89             free(p2);
90         }
91 
92         free(phead);
93 
94         return NULL;
95     }
96 }

5 创建一个链队列,实现优先队列

链队列比一般队列的好处,没有范围限制。

头文件Queue.h

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 struct queue
 5 {
 6     int num;
 7     int high;//优先级
 8     struct queue *pNext;//存储下一个结点的地址
 9 };
10 
11 typedef struct queue QUEUDE;//简化队列
12 
13 QUEUDE *init(QUEUDE *queueA);//初始化
14 QUEUDE *EnQueue(QUEUDE *queueA, int num, int high);//顺序入队
15 QUEUDE *DeQuedu(QUEUDE *queueA, QUEUDE *pout);//顺序出队
16 QUEUDE *freeall(QUEUDE *queueA);//清空
17 QUEUDE *insertEnQuedu(QUEUDE *queueA, int num, int high);//队列插入,采用插入排序,不要用冒泡排序,原因:优先级相同,也可能会交换
18 void printall(QUEUDE *queueA);//打印所有数据,递归

源文件

源文件main.c

 1 #define _CRT_SECURE_NO_WARNINGS
 2 
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 #include "Queue.h"
 6 
 7 main()
 8 {
 9     QUEUDE *phead = NULL;//创建头结点
10     phead = init(phead);//初始化
11 
12     phead = insertEnQuedu(phead, 1, 3);
13     printall(phead);//打印所有数据,递归
14     printf("
");
15 
16     phead = insertEnQuedu(phead, 2, 12);
17     printall(phead);//打印所有数据,递归
18     printf("
");
19 
20     phead = insertEnQuedu(phead, 3, 3);
21     printall(phead);//打印所有数据,递归
22     printf("
");
23 
24     phead = insertEnQuedu(phead, 4, 14);
25     printall(phead);//打印所有数据,递归
26     printf("
");
27 
28     phead = insertEnQuedu(phead, 5, 5);
29     printall(phead);//打印所有数据,递归
30     printf("
");
31 
32     phead = insertEnQuedu(phead, 6, 16);
33     printall(phead);//打印所有数据,递归
34     printf("
");
35 
36     phead = insertEnQuedu(phead, 7, 0);
37     printall(phead);//打印所有数据,递归
38     printf("
");
39 
40     phead = insertEnQuedu(phead, 8, 0);
41     printall(phead);//打印所有数据,递归
42     printf("
");
43 
44     phead = insertEnQuedu(phead, 9, 1);
45     printall(phead);//打印所有数据,递归
46     printf("
");
47 
48     phead = insertEnQuedu(phead, 10, 0);
49     printall(phead);//打印所有数据,递归
50     printf("
");
51 
52     phead = insertEnQuedu(phead, 11, 16);
53     printall(phead);//打印所有数据,递归
54     printf("
");
55 
56     phead = insertEnQuedu(phead, 111, 19);
57     printall(phead);//打印所有数据,递归
58     printf("
");
59 
60     //while (phead != NULL)//出队
61     //{
62     //    QUEUDE *ptemp = (QUEUDE *)malloc(sizeof(QUEUDE));
63     //    phead = DeQuedu(phead, ptemp);
64     //    printf("出队一次
");
65     //    printall(phead);//打印所有数据,递归
66     //    printf("出队的是%d,%d
", ptemp->num, ptemp->high);
67     //}
68     
69     system("pause");
70 }

源文件Queue.c

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include "Queue.h"
  4 
  5 QUEUDE *init(QUEUDE *queueA)//初始化
  6 {
  7     return NULL;
  8 }
  9 
 10 QUEUDE *EnQueue(QUEUDE *queueA, int num, int high)//顺序入队
 11 {
 12     QUEUDE *pnewnode = (QUEUDE *)malloc(sizeof(QUEUDE));//分配内存
 13     pnewnode->num = num;
 14     pnewnode->high = high;
 15     pnewnode->pNext = NULL;
 16 
 17     if (queueA == NULL)//链表为空
 18     {
 19         queueA = pnewnode;
 20         return queueA;
 21     }
 22     else
 23     {
 24         QUEUDE *p = queueA;//头结点
 25         while (p->pNext != NULL)//确定要插入的位置
 26         {
 27             p = p->pNext;
 28         }
 29         p->pNext = pnewnode;//插入
 30 
 31         return queueA;
 32     }
 33 }
 34 
 35 QUEUDE *DeQuedu(QUEUDE *queueA, QUEUDE *pout)//顺序出队
 36 {
 37     if (queueA == NULL)
 38     {
 39         return NULL;
 40     }
 41     else
 42     {
 43         pout->num = queueA->num;
 44         pout->high = queueA->high;
 45         QUEUDE *ptemp = queueA;//记录要删除的地址
 46         queueA = queueA->pNext;//跳过queueA
 47         free(ptemp);
 48         return queueA;
 49     }
 50 }
 51 
 52 QUEUDE *freeall(QUEUDE *queueA)//清空
 53 {
 54 
 55 }
 56 
 57 QUEUDE *insertEnQuedu(QUEUDE *queueA, int num, int high)//队列插入,采用插入排序,不要用冒泡排序,原因:优先级相同,也可能会交换
 58 {
 59     //实现从大到小插入
 60     QUEUDE *pnewnode = (QUEUDE *)malloc(sizeof(QUEUDE));//分配内存
 61     pnewnode->num = num;
 62     pnewnode->high = high;
 63     
 64     if (queueA == NULL)//原队列为空
 65     {
 66         pnewnode->pNext = NULL;
 67         queueA = pnewnode;
 68         return queueA;
 69     }
 70     else 
 71     {
 72         if (pnewnode->high > queueA->high)//头部插入1/3
 73         {
 74             pnewnode->pNext = queueA;
 75             queueA = pnewnode;//指向这个结点
 76             return queueA;
 77         }
 78         else
 79         {
 80             QUEUDE *p = queueA;//头结点
 81             while (p->pNext != NULL)
 82             {
 83                 p = p->pNext;//p循环到尾部
 84             }
 85             if (pnewnode->high <= p->high)//尾部插入2/3
 86             {
 87                 p->pNext = pnewnode;
 88                 pnewnode->pNext = NULL;
 89                 return queueA;
 90             }
 91             else//中间插入3/3
 92             {
 93                 QUEUDE *p1, *p2;
 94                 p1 = p2 = NULL;//避免野指针
 95                 p1 = queueA;//头结点
 96                 while (p1->pNext != NULL)
 97                 {
 98                     p2 = p1->pNext;
 99                     if (p1->pNext >= pnewnode->high  && p2->high <= pnewnode->high)
100                     {
101                         pnewnode->pNext = p2;
102                         p1->pNext = pnewnode;//插入
103                         break;
104                     }
105                     p1 = p1->pNext;
106                 }
107                 return queueA;
108             }
109         }
110     }
111 }
112 
113 void printall(QUEUDE *queueA)//打印所有数据,递归
114 {
115     if (queueA == NULL)
116     {
117         return;
118     }
119     else
120     {
121         printf("%d,%d,%x,%x
", queueA->num, queueA->high, queueA, queueA->pNext);
122         printall(queueA->pNext);//进入下一个
123     }
124 }
原文地址:https://www.cnblogs.com/denggelin/p/5551486.html