• 经典算法_链表


    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 }
  • 相关阅读:
    Android App性能评测分析-耗电量
    Android App性能评测分析-CPU渲染
    APP性能测试_响应
    Android开发03
    javaweb-request与response(未处理)
    javaweb-cookie&session(未处理)
    Android开发02
    eclipse中工作集的创建,简化项目组分类
    Android开发01
    javaweb-JDBC(转发)
  • 原文地址:https://www.cnblogs.com/denggelin/p/5551486.html
Copyright © 2020-2023  润新知