[英]Trying to sort a linked list
網上有很多實現,但我想自己做。
誰能告訴我我犯了什么錯誤?
當我創建鏈表時,我給出的輸入是 3、12、5、2。 所以排序后它應該是2,3,5,12,但它給了我輸出3,5,2,12。
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *start=NULL;
void sort()
{
struct node *preptr, *ptr, *temp;
temp = (struct node *)malloc(sizeof(struct node));
ptr=start;
while(ptr->next != NULL)
{
preptr=ptr;
ptr=ptr->next;
if (preptr->data > ptr->data )
{
temp->data=ptr->data;
ptr->data=preptr->data;
preptr->data=temp->data;
ptr=start;
}
}
}
您似乎已嘗試實施冒泡排序,但通常需要多次通過數據,而您只執行一次。 在那一次通過時,輸入 3、12、5、2,你的代碼
然后它停止,留下 3、5、2、12 作為最終結果。
在一般情況下, n元素列表上的冒泡排序必須使n - 1 次通過列表,而您的特定輸入恰好需要最大次數。 修復它的一種方法是在運行n - 1 次的for
循環中運行您現有的代碼進行一次排序,但當然您需要先計算n 。 更好的方法(無需更改為更好的算法)是通過外循環運行不確定次數的傳遞,跟蹤傳遞期間是否執行了任何交換。 當你完成一次傳球而不進行任何交換時,你就完成了。
補充說明:
您不需要struct node
來交換兩個節點的int
數據。
如果想要一個局部臨時struct node
,則不需要動態分配它。 只需聲明:
struct node temp_node;
如果您想要一個struct node *
用於本地臨時,您(可能)不需要為其分配任何內存以指向它。
如果你想要一個局部臨時struct node
和一個指向它的指針,你仍然不需要動態分配任何東西。 只需聲明結構並獲取其地址:
struct node temp_node; struct node *temp = &temp_node;
動態分配的主要原因是您事先不知道需要多少內存,或者分配的對象需要比創建它的函數的執行時間更長。
對鏈表進行排序通常是通過更改節點的鏈接重新排列節點來完成的,而不是像您的函數那樣通過交換節點有效負載來完成。 交換有效載荷不一定是錯誤的,但這並沒有利用鏈表結構的任何優勢。
正如您在評論中所寫的,您實際上需要移動節點,而不是值,您將需要重新分配next
指針。
出於同樣的原因, start
必須可以引用不同的節點。 因此,我建議sort
將start
作為參數並返回它的新值。
為了實現冒泡排序,您需要一個額外的外循環,它會重新開始對列表的迭代。 這最多應重復n次,其中n是列表中的節點數。 您也可以檢查是否需要交換,在這種情況下決定再次掃描您的列表......直到不再發生交換。
我在這里實現了第二個想法:
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
// A function to create a new node.
// This allows for easy initialisation of a linked list
struct node *newNode(int data, struct node *next) {
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->data = data;
temp->next = next;
return temp;
}
// Useful to see what is in the list...
void printList(struct node *cur) {
while (cur != NULL) {
printf("%i ", cur->data);
cur = cur->next;
}
printf("\n");
}
// Let the sort function
struct node * sort(struct node *start) {
struct node *prev, *cur, *next;
// flag indicating we are not sure yet that
// the list is sorted
int mutation = 1;
// extra dummy node that precedes the start node
struct node sentinel;
sentinel.next = start;
while (mutation) {
mutation = 0;
prev = &sentinel;
cur = sentinel.next;
next = start->next;
while (next != NULL) {
if (cur->data > next->data ) {
// swap cur and next
prev->next = next;
cur->next = next->next;
next->next = cur;
// flag that we need more iterations
mutation = 1;
// prepare for next iteration
prev = next;
} else {
prev = cur;
cur = next;
}
next = cur->next;
}
}
return sentinel.next;
}
// demo:
int main(void) {
// Create list that was given as example
struct node *start = newNode(3, newNode(12, newNode(5, newNode(2, NULL))));
printf("Input:\n");
printList(start);
start = sort(start);
printf("Sorted:\n");
printList(start);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.