[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;
}
}
}
答案 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;
}