三木社区

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 596|回复: 0
打印 上一主题 下一主题

C语言单链表实现18个功能完全详解

[复制链接]

1562

主题

1564

帖子

4904

积分

博士

Rank: 8Rank: 8

积分
4904
跳转到指定楼层
楼主
发表于 2017-9-2 09:25:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #define NN 12  
  4. #define MM 20  
  5. typedef int elemType ;  
  6.   
  7. /************************************************************************/  
  8. /*            以下是关于线性表链接存储(单链表)操作的18种算法        */  
  9.   
  10. /* 1.初始化线性表,即置单链表的表头指针为空*/  
  11. /* 2.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表*/  
  12. /* 3.返回单链表的长度*/  
  13. /* 4.检查单链表是否为空,若为空则返回1,否则返回0 */  
  14. /* 5.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行*/  
  15. /* 6.遍历一个单链表*/  
  16. /* 7.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */  
  17. /* 8.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */  
  18. /* 9.向单链表的表头插入一个元素*/  
  19. /* 10.向单链表的末尾添加一个元素*/  
  20. /* 11.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */  
  21. /* 12.向有序单链表中插入元素x结点,使得插入后仍然有序*/  
  22. /* 13.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行*/  
  23. /* 14.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行*/  
  24. /* 15.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行*/  
  25. /* 16.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */  
  26. /* 17.交换2个元素的位置*/  
  27. /* 18.将线性表进行快速排序*/  
  28.   
  29.   
  30. /************************************************************************/  
  31. struct sNode{    /*定义单链表结点类型*/  
  32.     elemType data;  
  33.     struct sNode *next;  
  34. };  
  35.   
  36. /* 1.初始化线性表,即置单链表的表头指针为空*/  
  37. void initList(struct sNode* *hl)  
  38. {  
  39.     *hl = NULL;  
  40.     return;  
  41. }  
  42.   
  43. /* 2.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表*/  
  44. void clearList(struct sNode* *hl)  
  45. {  
  46.     /* cp和np分别作为指向两个相邻结点的指针*/  
  47.     struct sNode *cp, *np;  
  48.     cp = *hl;  
  49.     /*遍历单链表,依次释放每个结点*/  
  50.     while(cp != NULL){  
  51.         np = cp->next;    /*保存下一个结点的指针*/  
  52.         free(cp);  
  53.         cp = np;  
  54.     }  
  55.     *hl = NULL;        /*置单链表的表头指针为空*/  
  56.     return;  
  57. }  
  58.   
  59. /* 3.返回单链表的长度*/  
  60. int sizeList(struct sNode *hl)  
  61. {  
  62.     int count = 0;        /*用于统计结点的个数*/  
  63.     while(hl != NULL){  
  64.         count++;  
  65.         hl = hl->next;  
  66.     }  
  67.     return count;  
  68. }  
  69.   
  70. /* 4.检查单链表是否为空,若为空则返回1,否则返回0*/  
  71. int emptyList(struct sNode *hl)  
  72. {  
  73.     if(hl == NULL){  
  74.         return 1;  
  75.     }else{  
  76.         return 0;  
  77.     }  
  78. }  
  79.   
  80. /* 5.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行*/  
  81. elemType getElem(struct sNode *hl, int pos)  
  82. {  
  83.     int i = 0;        /*统计已遍历的结点个数*/  
  84.     if(pos < 1){  
  85.         printf("pos值非法,退出运行!");  
  86.         exit(1);  
  87.     }  
  88.     while(hl != NULL){  
  89.         i++;  
  90.         if(i == pos){  
  91.             break;  
  92.         }  
  93.         hl = hl->next;  
  94.     }  
  95.     if(hl != NULL){  
  96.         return hl->data;  
  97.     }else{  
  98.         printf("pos值非法,退出运行!");  
  99.         exit(1);  
  100.     }  
  101. }  
  102.   
  103. /* 6.遍历一个单链表*/  
  104. void traverseList(struct sNode *hl)  
  105. {  
  106.     while(hl != NULL){  
  107.         printf("%5d", hl->data);  
  108.         hl = hl->next;  
  109.     }  
  110.     printf(" ");  
  111.     return;  
  112. }  
  113.   
  114. /* 7.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */  
  115. elemType* findList(struct sNode *hl, elemType x)  
  116. {  
  117.     while(hl != NULL){  
  118.         if(hl->data == x){  
  119.             return &hl->data;  
  120.         }else{  
  121.             hl = hl->next;      
  122.         }  
  123.     }  
  124.     return NULL;  
  125. }  
  126.   
  127. /* 8.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0*/  
  128. int updatePosList(struct sNode *hl, int pos, elemType x)  
  129. {  
  130.     int i = 0;  
  131.     struct sNode *p = hl;  
  132.     while(p != NULL){        /*查找第pos个结点*/  
  133.         i++;  
  134.         if(pos == i){  
  135.             break;  
  136.         }else{  
  137.             p = p->next;  
  138.         }  
  139.     }  
  140.     if(pos == i){  
  141.         p->data = x;  
  142.         return 1;  
  143.     }else{  
  144.         return 0;  
  145.     }  
  146. }  
  147.   
  148. /* 9.向单链表的表头插入一个元素*/  
  149. void insertFirstList(struct sNode* *hl, elemType x)  
  150. {  
  151.     struct sNode *newP;  
  152.     newP = malloc(sizeof(struct sNode));  
  153.     if(newP == NULL){  
  154.         printf("内存分配失败,退出运行!");  
  155.         exit(1);  
  156.     }  
  157.     newP->data = x;        /*把x的值赋给新结点的data域*/  
  158.     /*把新结点作为新的表头结点插入*/  
  159.     newP->next = *hl;         
  160.     *hl = newP;  
  161.     return;  
  162. }  
  163.   
  164. /* 10.向单链表的末尾添加一个元素*/  
  165. void insertLastList(struct sNode* *hl, elemType x)  
  166. {  
  167.     struct sNode *newP;  
  168.     newP = malloc(sizeof(struct sNode));  
  169.     if(newP == NULL){  
  170.         printf("内在分配失败,退出运行!");  
  171.         exit(1);  
  172.     }  
  173.     /*把x的值赋给新结点的data域,把空值赋给新结点的next域*/  
  174.     newP->data = x;  
  175.     newP->next = NULL;  
  176.     /*若原表为空,则作为表头结点插入*/  
  177.     if(*hl == NULL){  
  178.         *hl = newP;         
  179.     }  
  180.     /*查找到表尾结点并完成插入*/  
  181.     else{  
  182.         struct sNode *p = NULL;  
  183.         while(p->next != NULL){  
  184.             p = p->next;  
  185.         }  
  186.         p->next = newP;  
  187.     }  
  188.     return;  
  189. }  
  190.   
  191. /* 11.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0*/  
  192. int insetPosList(struct sNode* *hl, int pos, elemType x){  
  193.     int i = 0;  
  194.     struct sNode *newP;  
  195.     struct sNode *cp = *hl, *ap = NULL;  
  196.     /*对pos值小于等于0的情况进行处理*/  
  197.     if(pos <= 0){  
  198.         printf("pos值非法,返回0表示插入失败!");  
  199.         return 0;  
  200.     }  
  201.     /*查找第pos个结点*/  
  202.     while(cp != NULL){  
  203.         i++;  
  204.         if(pos == i){  
  205.             break;  
  206.         }else{  
  207.             ap = cp;  
  208.             cp = cp->next;  
  209.         }  
  210.     }  
  211.     /*产生新结点,若分配失败,则停止插入*/  
  212.     newP = malloc(sizeof(struct sNode));  
  213.     if(newP == NULL){  
  214.         printf("内存分配失败,无法进行插入操作!");  
  215.         return 0;  
  216.     }  
  217.     /*把x的值赋给新结点的data域*/  
  218.     newP->data = x;  
  219.     /*把新结点插入到表头*/  
  220.     if(ap == NULL){  
  221.         newP->next = cp;        /*或改为newP->next = *hl; */  
  222.         *hl = newP;  
  223.     }  
  224.     /*把新结点插入到ap和cp之间*/  
  225.     else{  
  226.         newP->next = cp;  
  227.         ap->next = newP;  
  228.     }  
  229.     return 1;        /*插入成功返回1 */  
  230. }  
  231.   
  232. /* 12.向有序单链表中插入元素x结点,使得插入后仍然有序*/  
  233. void insertOrderList(struct sNode* *hl, elemType x)  
  234. {  
  235.     /*把单链表的表头指针赋给cp,把ap置空*/  
  236.     struct sNode *cp = *hl, *ap = NULL;  
  237.     /*建立新结点*/  
  238.     struct sNode *newP;  
  239.     newP = malloc(sizeof(struct sNode));  
  240.     if(newP == NULL){  
  241.         printf("内在分配失败,退出运行!");  
  242.         exit(1);  
  243.     }  
  244.     newP->data = x;        /*把x的值赋给新结点的data域*/  
  245.     /*把新结点插入到表头*/  
  246.     if((cp == NULL) || (x < cp->data)){  
  247.         newP->next = cp;  
  248.         *hl = newP;  
  249.         return;  
  250.     }  
  251.     /*顺序查找出x结点的插入位置*/  
  252.     while(cp != NULL){  
  253.         if(x < cp->data){  
  254.             break;  
  255.         }else{  
  256.             ap = cp;  
  257.             cp = cp->next;  
  258.         }  
  259.     }  
  260.     /*把x结点插入到ap和cp之间*/  
  261.     newP->next = cp;  
  262.     ap->next = newP;  
  263.     return;  
  264. }  
  265.   
  266. /* 13.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行*/  
  267. elemType deleteFirstList(struct sNode* *hl)  
  268. {  
  269.     elemType temp;  
  270.     struct sNode *p = *hl;        /*暂存表头结点指针,以便回收*/  
  271.     if(*hl == NULL){  
  272.         printf("单链表为空,无表头可进行删除,退出运行!");  
  273.         exit(1);  
  274.     }  
  275.     *hl = (*hl)->next;        /*使表头指针指向第二个结点*/  
  276.     temp = p->data;            /*暂存原表头元素,以便返回*/  
  277.     free(p);                /*回收被删除的表头结点*/  
  278.     return temp;            /*返回第一个结点的值*/  
  279. }  
  280.   
  281. /* 14.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行*/  
  282. elemType deleteLastList(struct sNode* *hl)  
  283. {  
  284.     elemType temp;  
  285.     /*初始化cp和ap指针,使cp指向表头结点,使ap为空*/  
  286.     struct sNode *cp = *hl;  
  287.     struct sNode *ap = NULL;  
  288.     /*单链表为空则停止运行*/  
  289.     if(cp == NULL){  
  290.         printf("单链表为空,无表头进行删除,退出运行!");  
  291.         exit(1);  
  292.     }  
  293.     /*从单链表中查找表尾结点,循环结束时cp指向表尾结点,ap指向其前驱结点*/  
  294.     while(cp->next != NULL){  
  295.         ap = cp;  
  296.         cp = cp->next;  
  297.     }  
  298.     /*若单链表中只有一个结点,则需要修改表头指针*/  
  299.     if(ap == NULL){  
  300.         *hl = (*hl)->next;        /*或改为*hl = NULL; */  
  301.     }  
  302.     /*删除表尾结点*/  
  303.     else{  
  304.         ap->next = NULL;  
  305.     }  
  306.     /*暂存表尾元素,以便返回*/  
  307.     temp = cp->data;  
  308.     free(cp);        /*回收被删除的表尾结点*/  
  309.     return temp;        /*返回表尾结点的值*/  
  310. }  
  311.   
  312. /* 15.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行*/  
  313. elemType deletePosList(struct sNode* *hl, int pos)  
  314. {  
  315.     int i = 0;  
  316.     elemType temp;  
  317.     /*初始化cp和ap指针,使cp指向表头结点,使ap为空*/  
  318.     struct sNode *cp = *hl;  
  319.     struct sNode *ap = NULL;  
  320.     /*单链表为空或pos值非法则停止运行*/  
  321.     if((cp == NULL) || (pos <= 0)){  
  322.         printf("单链表为空或pos值不正确,退出运行!");  
  323.         exit(1);  
  324.     }  
  325.     /*从单链表中查找第pos个结点,找到后由cp指向该结点,由ap指向其前驱结点*/  
  326.     while(cp != NULL){  
  327.         i++;  
  328.         if(i == pos){  
  329.             break;  
  330.         }  
  331.         ap = cp;  
  332.         cp = cp->next;  
  333.     }  
  334.     /*单链表中没有第pos个结点*/  
  335.     if(cp == NULL){  
  336.         printf("pos值不正确,退出运行!");  
  337.         exit(1);  
  338.     }  
  339.     /*若pos等于1,则需要删除表头结点*/  
  340.     if(pos == 1){  
  341.         *hl = (*hl)->next;        /*或改为*hl = cp->next; */  
  342.     }  
  343.     /*否则删除非表头结点,此时cp指向该结点,ap指向前驱结点*/  
  344.     else{  
  345.         ap->next = cp->next;  
  346.     }  
  347.     /*暂存第pos个结点的值,以便返回*/  
  348.     temp = cp->data;  
  349.     free(cp);        /*回收被删除的第pos个结点*/  
  350.     return temp;    /*返回在temp中暂存的第pos个结点的值*/  
  351. }  
  352.   
  353. /* 16.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */  
  354. int deleteValueList(struct sNode* *hl, elemType x)  
  355. {  
  356.     /*初始化cp和ap指针,使cp指向表头结点,使ap为空*/  
  357.     struct sNode *cp = *hl;  
  358.     struct sNode *ap = NULL;  
  359.     /*从单链表中查找值为x的结点,找到后由cp指向该结点,由ap指向其前驱结点*/  
  360.     while(cp != NULL){  
  361.         if(cp->data == x){  
  362.             break;  
  363.         }  
  364.         ap = cp;  
  365.         cp = cp->next;  
  366.     }  
  367.     /*若查找失败,即该单链表中不存在值为x的结点,则返回0 */  
  368.     if(cp == NULL){  
  369.         return 0;  
  370.     }  
  371.     /*如果删除的是表头或非表头结点则分别进行处理*/  
  372.     if(ap == NULL){  
  373.         *hl = (*hl)->next;        /*或改为*hl= cp->next */  
  374.     }else{  
  375.         ap->next = cp->next;  
  376.     }  
  377.     free(cp);        /*回收被删除的结点*/  
  378.     return 1;        /*返回1表示删除成功*/  
  379. }  
  380. /* 17.交换2个元素的位置*/  
  381.   
  382. void Swip(struct sNode *h1,int i,int j)  
  383. {  
  384.     /*

  385.      
  386.     */  
  387.     int temp=0;  
  388.     if(i==j)  
  389.         return;  
  390.          
  391.     temp=getElem(h1,i);  
  392.     updatePosList(h1, i, getElem(h1,j));  
  393.     updatePosList(h1, j, temp);  
  394.   
  395.   
  396. }  
  397.   
  398. /* 18.将线性表进行快速排序*/  
  399.   
  400.   
  401. void FastSort(struct sNode *h1, int low,int high)  
  402. {  
  403.     /*
  404.      

  405.     */  
  406.         if(low<high)  
  407.     {  
  408.         int m = (low+high)/2;  
  409.         int i=low,j=high;  
  410.         do  
  411.         {  
  412.             while(getElem(h1,j)>getElem(h1,m)) j--;  
  413.             while(getElem(h1,i)<getElem(h1,m)) i++;  
  414.             if(i<=j)  
  415.             {  
  416.                 if(m==j)  
  417.                     m=i;  
  418.                 else if(m==i)  
  419.                     m=i;  
  420.              Swip(h1,i,j);  
  421.                 i++,j--;  
  422.             }  
  423.   
  424.         }while(i<=j);  
  425.         /*
  426.         printf("\n %5d\n",j);
  427.         traverseList(h1);
  428.         */  
  429.         FastSort(h1,low,j);  
  430.         FastSort(h1,i,high);  
  431.     }  
  432.       
  433. }  
  434.    
  435.   
  436. /*/**/  
  437.   
  438. /************************************************************************/  
  439.   
  440. int main(int argc, char* argv[])  
  441. {  
  442.     int a[NN];  
  443.     int i;  
  444.     struct sNode *p, *h, *s;  
  445.     srand(time(NULL));  
  446.     initList(&p);  
  447.     for(i = 0; i < NN; i++){  
  448.         a[i] = rand() & MM;  
  449.     }  
  450.     printf("随机数序列:\n");  
  451.     for(i = 0; i < NN; i++){  
  452.         printf("%5d", a[i]);  
  453.     }  
  454.     printf(" ");  
  455.     printf("\n随机数逆序:\n");  
  456.     for(i = 0; i < NN; i++){  
  457.         insertFirstList(&p, a[i]);  
  458.     }  
  459.     printf("\n随机数产生的序列\n");  
  460.     traverseList(p);  
  461.   
  462.     /*

  463.     */  
  464.      printf("\n经过快速排序后的序列\n");  
  465.     FastSort(p,1,sizeList(p));  
  466.     traverseList(p);  
  467.   
  468.   
  469.     printf("\n单链表长度:%5d ", sizeList(p));  
  470.     for(h = p; h != NULL; h = h->next){  
  471.         while(deleteValueList(&(h->next), h->data))  
  472.             ;  
  473.     }  
  474.     printf("\n去除重复数:\n");  
  475.     traverseList(p);  
  476.     printf("\n单链表长度:%5d ", sizeList(p));  
  477.     h = NULL;  
  478.     for(s = p; s != NULL; s = s->next){  
  479.         insertOrderList(&h, s->data);  
  480.     }  
  481.     printf("\n有序表序列:\n");  
  482.     traverseList(h);  
  483.     clearList(&p);  
  484.     system("pause");  
  485.     return 0;  
  486. }  
复制代码


回复

使用道具 举报

Archiver|手机版|小黑屋|三木电子社区 ( 辽ICP备11000133号-4 )

辽公网安备 21021702000620号

GMT+8, 2025-10-22 00:39 , Processed in 0.025702 second(s), 22 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表