如何链接列表指针排序

时间:2017-04-23 08:41:45

标签: c sorting pointers data-structures linked-list

[50] - > [20] - > [10] - > [30] 请告诉我如何通过节点指向的节点按升序或降序排序错位列表。 我认为这称为链接排序

p.s由于我是C语言和英语的初学者,我需要考虑。     ptr == tail(ptr not head)

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;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

列表是一个循环列表,所以尾指针足够好,因为如代码所示,tail-&gt; 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-&gt; 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;
}