簡體   English   中英

嘗試對鏈表進行排序

[英]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,你的代碼

  1. 將 3 與 12 進行比較,沒有任何變化;
  2. 將 12 與 5 進行比較,並交換它們;
  3. 將 12 與 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必須可以引用不同的節點。 因此,我建議sortstart作為參數並返回它的新值。

為了實現冒泡排序,您需要一個額外的外循環,它會重新開始對列表的迭代。 這最多應重復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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM