链表排序 感悟及源码

来源:互联网 发布:vr 知乎 编辑:程序博客网 时间:2024/06/05 05:18

最近在补充和提高数据结构及算法方面的知识,对于链表操作有些感悟,特此记录下来。

 

一般的链表生成、插入、去除等基本操作没什么好说的,只是在做两个有序链表合成一个的题目时感觉有些吃力。花了很长时间外加调试终于磕磕碰碰把它做完后,问了自己一个问题是,如果原始链表是乱序的呢? 那就先排序呗。 没想到的是,链表排序比数组排序要复杂N倍。 指针飞来飞去的,很容易把脑子搞糊涂。虽然最后独自完成了,但过程蛮痛苦,也发现自己对于链表的复杂操作比较薄弱,缺乏练习。打击人啊 :)

总结几点感悟:

1)链表是数据结构基础中的基础,尤其在复杂些的非线性数据结构中,如树,图, 基本上都是写链表操作。 所以多花些力气把链表操作尤其是复杂操作练熟还是很有帮助的。我以前就对它不是很重视,总以为应用很少。。。

 

2) 无论是基本操作还是复制操作,都要动手去实现它。 试问自己一下,能不看任何资料、准确无误快速的写一个链表生成的代码吗?起码我以前是不行,这东西只有多练过几次才熟练。

 

3)在链表基本操作中,如删除或添加某节点, 我们总是先从Head节点for循环遍历到目标节点的前继节点,然后在进行相应的操作。 但是在链表的sort或merge的复杂操作中, 需要定义额外的指针来实时记录目标节点的前继节点。 所以在这类操作中,对于单个链表,往往定义额外的4、5指针,有的用于遍历原始链表、有的用于实时记录前继节点、有的用于比较节点值大小。。。

 

4)在链表排序中,一般地有两种思路,一是不停的遍历原始链表找出最大或最小值的节点,然后remove再依次插到新的链表中;另一是从头结点开始遍历链表,将找到的最大或最小的节点和头节点交换,然后从第二个节点开始遍历找到第二个最大值,并和第二个节点进行交换,依次类推。。。  从这里可以看出,这两种思路的基础是 选择排序法,而不是bubble sort。

废话少说,附上算法实现源代码。欢迎指正。。。

第一种思路

static void RemoveNode(LINK_NODE *pFront, LINK_NODE *pRemove, LINK *ppLinkList)610 {611     if (pFront == pRemove)612     {613         *ppLinkList = (*ppLinkList)->pNextNode;614     }615     else616     {617         pFront->pNextNode = pRemove->pNextNode;618     }619     printf("remove value is %d \n", pRemove->index);620 }621                                                                                                               622 static void InsertNode(LINK *ppInsertFront, LINK_NODE *pInsert, LINK *ppNewList)                              623 {                                                                                                             624     if (*ppInsertFront == NULL)                                                                               625     {                                                                                                         626         *ppNewList = pInsert;                                                                                 627         *ppInsertFront = pInsert;                                                                             628     }                                                                                                         629     else                                                                                                      630     {                                                                                                         631         (*ppInsertFront)->pNextNode = pInsert;                                                                632         *ppInsertFront = (*ppInsertFront)->pNextNode;                                                         633     }                                                                                                         634 }                                                                                                             635                                                                                                               636 void SortLinkList(LINK_NODE *pList, LINK *ppNewList)                                                          637 {                                                                                                             638     LINK_NODE *pOrignNode, *pNewNode;                                                                         639     LINK_NODE *pRemoveNode, *pFrontNode;                                                                      640     LINK_NODE *pInsertFront;                                                                                  641                                                                                                               642     pOrignNode = pNewNode = pList;                                                                            643     pRemoveNode = pFrontNode = pOrignNode;                                                                    644     pInsertFront = NULL;                                                                                      645                                                                                                               646     while (pOrignNode)                                                                                        647     {                                                                                                         648         while (pOrignNode->pNextNode)                                                                         649         {                                                                                                     650             if (pOrignNode->pNextNode->index < pRemoveNode->index)                                            651             {                                                                                                 652                 pFrontNode = pOrignNode;                                                                      653                 pRemoveNode = pOrignNode->pNextNode;                                                          654             }                                                                                                 655             pOrignNode = pOrignNode->pNextNode;                                                               656         }                                                                                                     657         RemoveNode(pFrontNode, pRemoveNode, &pList);                                                          658         InsertNode(&pInsertFront, pRemoveNode, ppNewList);                                                    659                                                                                                               660         pOrignNode = pFrontNode = pList;                                                                      661         pRemoveNode = pOrignNode;                                                                             662     }                                                                                                         663     pInsertFront = NULL;                                                                                      664 } 

第二种思路

static void SwitchNode(LINK_NODE *pFront1, LINK_NODE *pNode1, LINK_NODE *pFront2, LINK_NODE *pNode2, LINK *ppNewList)       667 {                                                                                                             668     LINK_NODE *pTempNode;                                                                                     669                                                                                                               670     if (pFront1 == pFront2)                                                                                   671         return;                                                                                               672                                                                                                               673     if (pNode1 == pFront2)                                                                                    674     {                                                                                                         675         pFront1->pNextNode = pNode2;                                                                          676         pTempNode = pNode2->pNextNode;                                                                        677         pNode2->pNextNode = pNode1;                                                                           678         pNode1->pNextNode = pTempNode;                                                                        679         return;                                                                                               680     }                                                                                                         681                                                                                                               682     if (pFront1 == pNode1)                                                                                    683     {                                                                                                         684         *ppNewList = pNode2;                                                                                  685     }                                                                                                         686     else                                                                                                      687     {                                                                                                         688         pFront1->pNextNode = pNode2;                                                                          689     }                                                                                                         690                                                                                                               691     pTempNode = pNode2->pNextNode;                                                                            692     pNode2->pNextNode = pNode1->pNextNode;                                                                    693                                                                                                               694     pFront2->pNextNode = pNode1;                                                                              695     pNode1->pNextNode = pTempNode;                                                                            696 }                                                                                                             697                                                                                                               698 void SelectSortList(LINK_NODE *pList, LINK *ppNewList)                                                        699 {                                                                                                             700     LINK_NODE *pNode1, *pNode2;                                                                               701     LINK_NODE *pFront1, *pFront2;                                                                             702     LINK_NODE *pMaxNode;                                                                                      703                                                                                                               704     pNode1 = pNode2 = pList;                                                                                  705     pFront1 = pFront2 = pList;                                                                                706                                                                                                               707     while (pNode1)                                                                                            708     {                                                                                                         709         pMaxNode = pNode1;                                                                                    710         while (pNode2->pNextNode)                                                                             711         {                                                                                                     712             if (pNode2->pNextNode->index > pMaxNode->index)                                                   713             {                                                                                                 714                 pFront2 = pNode2;                                                                             715                 pMaxNode = pNode2->pNextNode;                                                                 716             }                                                                                                 717             pNode2 = pNode2->pNextNode;                                                                       718         }                                                                                                     719         SwitchNode(pFront1, pNode1, pFront2, pMaxNode, ppNewList);                                            720         pFront1 = pMaxNode;                                                                                   721         pNode1 = pMaxNode->pNextNode;                                                                         722         pNode2 = pNode1;                                                                                      723     }                                                                                                         724 }  


 

0 0