zoukankan      html  css  js  c++  java
  • C语言实现单链表,并完成链表常用API函数

    C语言实现单链表,并完成链表常用API函数:

      1.链表增、删、改、查。

      2.打印链表、反转打印、打印环形链表。

      3.链表排序、链表冒泡排序、链表快速排序。

      4.求链表节点个数(普通方法、递归方法)。

      5.链表反转(普通方法、递归方法)。

      6.链表合并。

      7.获取链表中间节点。

      8.判断链表是否有环。

    LinkList.h :

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 struct LinkNode
     5 {
     6     int data;
     7     struct LinkNode *pNext;
     8 };
     9 
    10 typedef struct LinkNode Node;    //简化类型
    11 
    12 void init(Node *phead);                            //初始化
    13 Node *addBack(Node *phead, int data);            //尾插法:尾部添加节点
    14 void addHead(Node *phead, int data);            //头插法:头部添加节点
    15 
    16 void ShowAll(Node *phead);                        //显示链表
    17 void revShowAll(Node *phead);                    //反转显示链表                                
    18 void ShowCircleLink(Node *phead);                //显示环形链表
    19 
    20 Node *searchFirst(Node *phead, int findData);    //查找
    21 
    22 Node *changeFirst(Node *phead, int findData, int newData);    //修改
    23 
    24 Node *delFirst(Node *phead, int delData);        //删除
    25 
    26 Node *insertFirst(Node *phead, int insertData,int newData);        //插入
    27 
    28 void bubbleSort(Node *phead);                    //冒泡排序
    29 
    30 void quickSort(Node *pbegin, Node *pback);        //快速排序法:(双冒泡)
    31 Node *fen(Node *pbegin, Node *pback);            //分段
    32 
    33 int getNum1(Node *phead);                        //求链表节点个数
    34 int getNum2(Node *phead);                        //求链表节点个数(递归)
    35 
    36 Node *revList1(Node *phead);                    //链表反转(普通方法)
    37 Node *revList2(Node *phead);                    //链表反转(递归方法)
    38 
    39 //将链表phead1和phead2合并到phead3,并返回链表phead3
    40 Node *mergeList(Node *phead3, Node *phead1, Node *phead2);        //链表合并
    41 
    42 Node *getMid(Node *phead);                        //获取链表的中间节点
    43 
    44 int judgeCircle(Node *phead);                    //判断链表是否有环

    LinkList.c :

      1 #include "LinkList.h"
      2 
      3 //初始化
      4 void init(Node *phead)
      5 {
      6     phead->pNext = NULL;
      7     phead->data = 0;
      8 }
      9 
     10 //显示链表
     11 void ShowAll(Node *phead)
     12 {
     13     if (phead == NULL)
     14         return;
     15     else
     16     {
     17         printf("%4d", phead->data);
     18         //printf("%d,%p,%p
    ", phead->data, phead, phead->pNext);
     19         ShowAll(phead->pNext);                                    //跳到下一个节点
     20 
     21     }
     22 }
     23 
     24 //反转显示链表
     25 void revShowAll(Node *phead)
     26 {
     27     if (phead == NULL)
     28         return;
     29     else
     30     {
     31         printf("%d,%p,%p
    ", phead->data, phead, phead->pNext);
     32         ShowAll(phead->pNext);                                    //跳到下一个节点
     33 
     34     }
     35 }
     36 
     37 //显示环形链表
     38 void ShowCircleLink(Node *phead)
     39 {
     40     if (phead == NULL)
     41         return;
     42     else
     43     {
     44         Node *p = phead;
     45         for (; p->pNext != phead; p = p->pNext)
     46             printf("%4d", p->data);
     47 
     48         printf("%4d", p->data);    //还需要再打印最后一个元素
     49 
     50     }
     51 }
     52 
     53 //尾插法:尾部添加节点  (改变了头指针,改变一个指针,要么二级指针,要么用返回值给指针赋值,这里采用返回值)
     54 Node *addBack(Node *phead, int data)
     55 {
     56     Node *pnew = malloc(sizeof(Node));    //构建新的节点
     57     pnew->data = data;                    //新节点赋值
     58     pnew->pNext = NULL;
     59 
     60     if (phead == NULL)                    //phead为空,直接连接
     61         phead = pnew;
     62     else
     63     {
     64         Node *ptemp = phead;            //备份一下头指针
     65         while (ptemp->pNext != NULL)
     66         {
     67             ptemp = ptemp -> pNext;        //循环前进
     68         }
     69         ptemp->pNext = pnew;            //链接
     70     }
     71 
     72     return phead;
     73 }
     74 
     75 //头插法:头部添加节点 (采用二级指针的方法)
     76 void addHead(Node **pphead, int data)
     77 {
     78     Node *pnew = malloc(sizeof(Node));    //构建新的节点
     79     pnew->data = data;                    //新节点赋值
     80     pnew->pNext = NULL;
     81 
     82     if(*pphead==NULL)
     83         pphead = pnew;
     84     else
     85     {
     86         pnew->pNext = *pphead;
     87         *pphead = pnew;
     88     }
     89 }
     90 
     91 //查找
     92 Node *searchFirst(Node *phead, int findData)
     93 {
     94     for (Node *p = phead; p != NULL; p = p->pNext)
     95     {
     96         if (p->data == findData)
     97         {
     98             return p;        //返回找到的指针位置
     99         }
    100     }
    101 
    102     return NULL;
    103 }
    104 
    105 //修改
    106 Node *changeFirst(Node *phead, int findData, int newData)
    107 {
    108     for (Node *p = phead; p != NULL; p = p->pNext)
    109     {
    110         if (p->data == findData)
    111         {
    112             p->data = newData;
    113             return p;        //返回找到的指针位置
    114         }
    115     }
    116 
    117     return NULL;
    118 }
    119 
    120 //删除
    121 Node *delFirst(Node *phead, int delData)
    122 {
    123     Node *p1=NULL, *p2=NULL;        //此时需要双指针
    124     p1 = phead;            //保存头结点
    125 
    126     while (p1 != NULL)
    127     {
    128         if (p1->data != delData)
    129         {
    130             p2 = p1;        //p2保存的是p1的上一个位置
    131             p1 = p1->pNext;
    132         }
    133         else
    134             break;
    135     }
    136 
    137     if (p1 != phead)
    138     {
    139         p2->pNext = p1->pNext;    //跳过p1
    140         free(p1);                //删除p1
    141     }
    142     else
    143     {
    144         phead = phead->pNext;
    145         free(p1);                //头部删除
    146     }
    147 
    148     return phead;
    149 }
    150 
    151 //插入
    152 Node *insertFirst(Node *phead, int insertData, int newData)
    153 {
    154     Node *p1 = NULL, *p2 = NULL;        //此时需要双指针
    155     p1 = phead;            //保存头结点
    156 
    157     while (p1 != NULL)
    158     {
    159         if (p1->data != insertData)
    160         {
    161             p2 = p1;        //p2保存的是p1的上一个位置
    162             p1 = p1->pNext;    //向前移动
    163         }
    164         else
    165             break;
    166     }
    167 
    168     Node *pnew = malloc(sizeof(Node));    //构建新的节点
    169     pnew->data = newData;                //新节点赋值
    170     pnew->pNext = NULL;
    171 
    172     if (phead == p1)
    173     {
    174         pnew->pNext = phead;    //保存头结点
    175         phead = pnew;            //头部插入
    176     }
    177     else
    178     {
    179         pnew->pNext = p1;
    180         p2->pNext = pnew;        //插入
    181     }
    182 
    183     return phead;
    184 }
    185 
    186 //冒泡排序
    187 void bubbleSort(Node *phead)
    188 {
    189     //数组可以随机访问任何一个元素,可以规避一些比较
    190     //链表找到N个元素,必须先遍历N-1个元素
    191     for (Node *p1 = phead; p1 != NULL; p1 = p1->pNext)
    192     {
    193         for (Node *p2 = phead; p2 != NULL; p2 = p2->pNext)
    194         {
    195             if (p1->data < p2->data)
    196             {
    197                 int temp;
    198                 temp = p1->data;
    199                 p1->data = p2->data;
    200                 p2->data = temp;
    201             }
    202         }
    203     }
    204 }
    205 
    206 Node *fen(Node *pbegin, Node *pback)
    207 {
    208     int key = pbegin->data;        //以第一个数据为分段
    209 
    210     Node *p = pbegin;            //第一个节点
    211     Node *q = pbegin->pNext;    //第二个节点
    212 
    213     while (q != pback)
    214     {
    215         if (q->data < key)
    216         {
    217             p = p->pNext;        //循环下一个节点
    218 
    219             int temp = p->data;    //交换
    220             p->data = q->data;
    221             q->data = temp;
    222         }
    223         q = q->pNext;            //循环第二个指针
    224 
    225         printf("
    枢轴为:(%d)", key);
    226         printf("
    此时数:");
    227         ShowAll(pbegin);
    228 
    229     }
    230 
    231     int temp = p->data;    //交换
    232     p->data = pbegin->data;
    233     pbegin->data = temp;
    234 
    235     printf("
    
    交换值:");
    236     ShowAll(pbegin);
    237     printf("
    -----------------------------------------------");
    238 
    239     return p;
    240 }
    241 
    242 //快速排序法:(双冒泡)
    243 void quickSort(Node *pbegin,Node *pback)
    244 {
    245     if (pbegin != pback)
    246     {
    247         Node *pfen = fen(pbegin, pback);    //取中间点,分成两段分别再进行快排
    248 
    249         quickSort(pbegin, pfen);            //前半段快排
    250         quickSort(pfen->pNext, pback);        //后半段快排
    251     }
    252 }
    253 
    254 //求链表节点个数(普通方法)
    255 int getNum1(Node *phead)
    256 {
    257     int i = 0;
    258     for (; phead != NULL; phead = phead->pNext)
    259     {
    260         i++;
    261     }
    262     return i;
    263 }
    264 
    265 //求链表节点个数(递归)
    266 int getNum2(Node *phead)
    267 {
    268     if (phead == NULL)
    269         return 0;
    270     else
    271         return 1 + getNum2(phead->pNext);
    272 }
    273 
    274 //链表反转(普通方法)
    275 Node *revList1(Node *phead)
    276 {
    277     if (phead == NULL || phead->pNext == NULL)
    278         return phead;
    279     else
    280     {
    281         Node *pre = NULL;
    282         Node *pcur = NULL;
    283         Node *pnext = NULL;
    284 
    285         pre = phead;
    286         pcur = phead->pNext;
    287         while (pcur != NULL)
    288         {
    289             pnext = pcur->pNext;    //备份下一个节点
    290             pcur->pNext = pre;        //第一个节点指向NULL,此时pre指向NULL(指针反转)
    291             
    292             pre = pcur;                //前进
    293             pcur = pnext;            //轮替前进
    294         }
    295 
    296         phead->pNext = NULL;        //注意尾节点置空
    297         phead = pre;
    298     }
    299 
    300     return phead;
    301 }
    302 
    303 //链表反转(递归方法)
    304 Node *revList2(Node *phead)
    305 {
    306     if (phead == NULL || phead->pNext == NULL)
    307         return phead;
    308     else
    309     {
    310         Node *pnext = phead->pNext;        //顺序
    311 
    312         Node *Head = revList2(pnext);    //轮询所有的节点,递归调用
    313 
    314         pnext->pNext = phead;
    315 
    316         phead->pNext = NULL;            //逆序
    317 
    318         return Head; 
    319     }
    320 }
    321 
    322 //链表合并
    323 Node *mergeList(Node *phead3, Node *phead1, Node *phead2)
    324 {
    325     Node *pcur1 = phead1;
    326     Node *pcur2 = phead2;
    327 
    328     while (pcur1 != NULL || pcur2 != NULL)
    329     {
    330         if (pcur1 != NULL && pcur2 != NULL)
    331         {
    332             if (pcur1->data < pcur2->data)
    333             {
    334                 phead3 = addBack(phead3, pcur1->data);
    335                 pcur1 = pcur1->pNext;
    336             }
    337             else
    338             {
    339                 phead3 = addBack(phead3, pcur2->data);
    340                 pcur2 = pcur2->pNext;
    341             }
    342         }
    343         else
    344         {
    345             while (pcur1 != NULL)
    346             {
    347                 phead3 = addBack(phead3, pcur1->data);
    348                 pcur1 = pcur1->pNext;
    349             }
    350             while (pcur2 != NULL)
    351             {
    352                 phead3 = addBack(phead3, pcur2->data);
    353                 pcur2 = pcur2->pNext;
    354             }
    355 
    356             break;
    357         }
    358     }
    359 
    360     return phead3;
    361 }
    362 
    363 //获取链表的中间节点
    364 Node *getMid(Node *phead)
    365 {
    366     if (phead == NULL || phead->pNext == NULL)
    367         return phead;
    368     else
    369     {
    370         Node *p1 = phead;            //一次前进一步
    371         Node *p2 = phead;            //一次前进两步
    372 
    373         while (p2->pNext != NULL)    //注意循环条件,而不是p2 != NULL
    374         {
    375             p1 = p1->pNext;
    376             p2 = p2->pNext;
    377             if (p2->pNext != NULL)
    378                 p2 = p2->pNext;
    379         }
    380 
    381         return p1;
    382     }
    383 }
    384 
    385 //判断链表是否有环
    386 int judgeCircle(Node *phead)
    387 {
    388     int flag = 0;
    389     for (Node *p1 = phead, *p2 = phead; p1 != NULL && p2 != NULL; p1 = p1->pNext, p2 = p2->pNext)    //死循环
    390     {    
    391         if(p2->pNext!=NULL)    //p2一次前进两步,而p1一次前进一步
    392             p2 = p2->pNext;
    393 
    394         if (p1 == p2)
    395         {
    396             flag == 1;        //p1追上了p2,有环
    397             break;
    398         }
    399             
    400         
    401     }
    402 
    403     return flag;
    404 }

    main.c :

      1 #include "LinkList.h"
      2 
      3 void main()
      4 {
      5     Node *phead = NULL;
      6     //init(phead);    //初始化,头结点不分配内存,这里不能初始化头结点
      7 
      8     phead = addBack(phead, 14);        //尾插
      9     phead = addBack(phead, 15);
     10     phead = addBack(phead, 16);
     11     phead = addBack(phead, 8);
     12     phead = addBack(phead, 12);
     13     phead = addBack(phead, 13);
     14 
     15     //addHead(&phead, 9);            //头插
     16     //addHead(&phead, 22);
     17     //addHead(&phead, 41);
     18     //addHead(&phead, 18);
     19     //ShowAll(phead);
     20 
     21     //Node *pfind = searchFirst(phead, 13);
     22     //pfind->data = 33;
     23     //ShowAll(phead);
     24 
     25     //Node *pchange = changeFirst(phead, 14,93);
     26     //ShowAll(phead);
     27 
     28     //ShowAll(phead);
     29     //printf("
    
    ");
     30     //phead = delFirst(phead, 24);
     31     //ShowAll(phead);
     32 
     33     //printf("
    
    ");
     34     //insertFirst(phead, 11, 100);
     35     //ShowAll(phead);
     36 
     37     printf("排序前:");
     38     ShowAll(phead);
     39     printf("
    
    ");
     40 
     41     //bubbleSort(phead);
     42     quickSort(phead, NULL);
     43     
     44     printf("
    
    ");
     45     printf("排序后:");
     46     ShowAll(phead);
     47     printf("
    ");
     48 
     49     printf("%d
    ", getNum2(phead));
     50 
     51     phead = revList1(phead);
     52     ShowAll(phead);
     53     printf("
    ");
     54     phead = revList2(phead);
     55     ShowAll(phead);
     56     printf("
    ");
     57 
     58     Node *phead1 = NULL;
     59     phead1 = addBack(phead1, 1);
     60     phead1 = addBack(phead1, 3);
     61     phead1 = addBack(phead1, 5);
     62     phead1 = addBack(phead1, 7);
     63     phead1 = addBack(phead1, 9);
     64 
     65     Node *phead2 = NULL;
     66     phead2 = addBack(phead2, 2);
     67     phead2 = addBack(phead2, 4);
     68     phead2 = addBack(phead2, 6);
     69     phead2 = addBack(phead2, 8);
     70 
     71     printf("
    
    
    ");
     72     ShowAll(phead1);
     73     printf("
    ");
     74     ShowAll(phead2);
     75     printf("
    ");
     76 
     77     Node *phead3 = NULL;
     78     phead3 = mergeList(phead3, phead1, phead2);
     79     ShowAll(phead3);
     80     printf("
    ");
     81 
     82     Node *pmid = getMid(phead3);
     83     printf("%d
    ", pmid->data);
     84 
     85     Node *phead4 = NULL;
     86     phead4 = addBack(phead4, 1);
     87     phead4 = addBack(phead4, 2);
     88     phead4 = addBack(phead4, 3);
     89     phead4 = addBack(phead4, 4);
     90     phead4 = addBack(phead4, 5);
     91     phead4 = addBack(phead4, 6);
     92     phead4 = addBack(phead4, 7);
     93 
     94     Node *p = phead4;
     95     for (; p->pNext != NULL; p = p->pNext)
     96     {
     97     }
     98     p->pNext = phead4;
     99 
    100     ShowCircleLink(phead4);    //打印环形链表
    101     printf("
    ");
    102     printf("%d
    ", judgeCircle(phead4));
    103 
    104     system("pause");
    105 }
  • 相关阅读:
    Leetcode 349. Intersection of Two Arrays
    hdu 1016 Prime Ring Problem
    map 树木品种
    油田合并
    函数学习
    Leetcode 103. Binary Tree Zigzag Level Order Traversal
    Leetcode 102. Binary Tree Level Order Traversal
    Leetcode 101. Symmetric Tree
    poj 2524 Ubiquitous Religions(宗教信仰)
    pat 1009. 说反话 (20)
  • 原文地址:https://www.cnblogs.com/si-lei/p/9493002.html
Copyright © 2011-2022 走看看