了解合并两个已排序链接列表的算法

时间:2015-08-09 13:38:58

标签: c algorithm sorting

我尝试理解以下算法,将两个已排序的链接lsits合并为一个已排序的链接列表(取自here)。

我完全不明白这段代码是如何工作的,并且很乐意解释。

代码:

ng-if

3 个答案:

答案 0 :(得分:2)

在开始时,有一些NULL参数的标准测试,这些测试对应于一个列表为空白而另一个列表默认排序的基本情况。

写入器在这里做了一个技巧,每次下一个项目将从指向节点名为list1的指针添加,这发生在行textSize,剩下的是了解如何始终添加从一个列表中,这是使用SWAP_PTRS宏完成的,该宏在onDraw处设置了较低值的列表startig。

更新完成后,使用以下内容找到应更新的下一个节点:*pnext = list1;。它工作的原因也很有趣,因为当前更新的节点已指向list1的当前项,其下一个字段中的值是指向下一个应该更新的位置的指针,方法是传递该指针的地址(使用& ;)我们可以更改下一个项目的内容。

此过程一直持续到添加的项目是列表中的最后一项。这里有一个有趣的观点是没有边缘条件,因为删除的项总是来自list1,这意味着list2在list1之前不能为空。当添加list1的最后一项时,while循环终止,list2的其余部分被添加到结果列表的末尾。

答案 1 :(得分:1)

算法如下:

如果list2为空,这意味着只有一个列表,则算法将返回list1,这是合并列表。如果list1为空,则应进行相同的测试...

接下来,我们将两个列表一起循环,直到我们到达list1list2的末尾。从每个列表中的第一个项目开始,我们比较项目并将较小的项目添加到合并列表,并在相应的列表中前进。在下一次迭代中,将比较一个列表中的第一个项目与另一个列表中的第二个项目,依此类推,直到我们到达其中一个列表的末尾。

之后,我们只需添加列表中的项目,但我们没有达到合并列表的结尾

答案 2 :(得分:1)

这个没有交换的例子可能更容易理解。

Node * MergeLists(Node *pSrc1, Node *pSrc2)
{
Node *pDst = NULL;                      /* destination head ptr */
Node **ppDst = &pDst;                   /* ptr to head or prev->next */
    if(pSrc1 == NULL)
        return pSrc2;
    if(pSrc2 == NULL)
        return pSrc1;
    while(1){
        if(pSrc2->data < pSrc1->data){  /* if src2 < src1 */
            *ppDst = pSrc2;
            pSrc2 = *(ppDst = &(pSrc2->next));
            if(pSrc2 == NULL){
                *ppDst = pSrc1;
                break;
            }
        } else {                        /* src1 <= src2 */
            *ppDst = pSrc1;
            pSrc1 = *(ppDst = &(pSrc1->next));
            if(pSrc1 == NULL){
                *ppDst = pSrc2;
                break;
            }
        }
    }
    return pDst;
}

此线程中显示的任何一个MergeList函数都可以由此合并排序函数使用,该函数使用指向节点的指针数组对列表进行排序:

#define NUMLISTS 32                     /* size of array */
Node * SortList(Node *pList)
{
Node * aList[NUMLISTS];                 /* array of lists */
Node * pNode;
Node * pNext;
int i;
    if(pList == NULL)                   /* check for empty list */
        return NULL;
    for(i = 0; i < NUMLISTS; i++)       /* zero array */
        aList[i] = NULL;
    pNode = pList;                      /* merge Nodes into aList[] */
    while(pNode != NULL){
        pNext = pNode->next;
        pNode->next = NULL;
        for(i = 0; (i < NUMLISTS) && (aList[i] != NULL); i++){
            pNode = MergeLists(aList[i], pNode);
            aList[i] = NULL;
        }
        if(i == NUMLISTS)
            i--;
        aList[i] = pNode;
        pNode = pNext;
    }
    pNode = NULL;                       /* merge array into one list */
    for(i = 0; i < NUMLISTS; i++)
        pNode = MergeLists(aList[i], pNode);
    return pNode;
}