繁体   English   中英

如何链接列表指针排序

[英]how to linked list pointer sorting

[50]-> [20]-> [10]-> [30]请告诉我如何按节点所指向的节点以升序或降序对未对齐列表进行排序。 我认为这称为链接排序

ps由于我是C语言和英语的初学者,因此需要考虑。 ptr == tail(ptr不是头)

void sort_data(Node* ptr){
    Node* head = ptr->Next;
    Node* tail = ptr;
    for (int i = 0; i < 10; i++) {
        if (head->Next == tail) {
        }
        if (head->data < head->Next->data) {
            Node* swap1 = head;
            Node* swap2 = head->Next;
            swap1->Next = swap2->Next;
            swap2->Next = swap1;
            tail->Next = swap2;
            tail = tail->Next;
        }
        else {
            head = head->Next;
            tail = tail->Next;
        }
    }
}

该列表是一个循环列表,因此尾部指针就足够了,因为如代码中所示,tail-> next将产生头部指针。 该代码不会检查空列表或仅包含单个节点的列表。

冒泡排序通常需要一个循环内的一个循环(一个外部循环和一个内部循环)。 每个内部循环将应排在最后的节点移到列表的末尾。 第一个内部循环将最后一个节点放置到位,第二个内部循环将倒数第二个节点放置到位,依此类推,最后一个内部循环将第二个节点放置到位。

为了交换节点,代码需要能够更新先前节点的下一个指针。 例如:

A->B->C->D     // to swap B and C, A's next pointer needs to be updated
A->C->B->D     //  along with B and C's next pointers

由于返回的指针是尾指针,因此可以在第一个内部循环之后设置尾指针,因为那是将最后一个节点放置到位,或者可以在排序之后对列表进行扫描以找到最后一个节点。

我建议在sort函数中将循环列表转换为普通列表:

    Node *head = ptr->next;   // same as above
    Node *tail = ptr;         // same as above
    tail->next = NULL;        // convert to normal list

由于简化了列表开头或结尾的节点,因此简化了确定列表结尾的步骤(检查NULL是否指向特定节点)。

通过在列表的末尾跟踪排序的节点,可以避免对已排序的节点进行扫描和比较,从而优化代码。

优化冒泡排序的示例代码。 设置pHead后,列表将从循环更改为普通(pTail-> next = NULL)。 pEnd用于跟踪未排序列表的末尾,并初始化为NULL。 pnEnd根据无序检查来跟踪未排序列表的末尾,并用于为下一个内部循环设置pEnd。 当pEnd是列表中的第二个节点时,将完成排序,因为作为单个节点的第一个节点也将被排序。 ppCurr是指向当前节点的指针,并且是指向pHead或某些节点的下一个指针的指针,这简化了处理第一个节点和随后的节点的逻辑(在其他不支持指针的语言中,为虚拟节点)可以类似的方式使用(使用与* ppCurr类似的dummy.next)。 首次完成内部循环检查,将pTail设置为最后一个节点,如果交换了最后两个节点,则可能已更改。 排序完成后,将pTail-> next设置为pHead,以将列表更改回循环。

/* bubble sort circular linked list */
NODE * SortList(NODE *pTail)
{
NODE *pHead;                    /* ptr to first node */
NODE *pEnd;                     /* ptr to end of unsorted part of list */
NODE *pnEnd;                    /* pEnd for next pass */
NODE *pNext;                    /* ptr to next node */
NODE **ppCurr;                  /* ptr to ptr to curr node */
    if(pTail == NULL || pTail->next == pTail) /* if empty list or single node */
        return pTail;           /*  return pTail */
    pHead = pTail->next;
    pEnd = pTail->next = NULL;  /* change to normal list */
    do{
        ppCurr = &pHead;        /* set ppCurr to start of list */
        pnEnd = pHead->next;    /* set pnEnd to 2nd node */
        while((pNext = (*ppCurr)->next) != pEnd){
            if((*ppCurr)->data > pNext->data){ /* if out of order swap */
                (*ppCurr)->next = pNext->next;
                pnEnd = pNext->next = *ppCurr;
                *ppCurr = pNext;
            }
            ppCurr = &(*ppCurr)->next; /* advance to next node */
        }
        if(pEnd == NULL)        /* if first time, set pTail */
            pTail = *ppCurr;    /*  in case last two nodes swapped */
        pEnd = pnEnd;           /* update pEnd since rest of list is sorted */
    }while(pEnd != pHead->next); /* loop until pEnd => 2nd node */
    pTail->next = pHead;        /* change to circular list */
    return pTail;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM