簡體   English   中英

在C中的鏈表上插入排序?

[英]Insertion sort on linked list in C?

我試過尋找類似於我的問題,但沒有找到太多幫助。

我有一個這種結構的鏈表:

struct PCB {
    struct PCB *next;
    int reg1, reg2;
};

我首先以這種方式創建10個PCB結構:

for(i=20;i<=30;i++) {
        curr = (struct PCB *)malloc(sizeof(struct PCB));
        curr->reg1 = i;
        curr->next  = head;
        head = curr;
    }

然后我需要再創建20個PCB結構,但是需要使用rand()生成它們的reg1值。 我正在這樣做:

for (j = 0;j<20;j++) {
        curr = (struct PCB *)malloc(sizeof(struct PCB));
        curr->reg1 = rand()%100;
        curr->next  = head;
        head = curr;
    }

但是,當使用隨機reg1值將這些PCB結構插入到鏈表中時,我需要按順序將它們插入到鏈表中(插入排序)。 在單鏈接鏈表中處理此問題的最佳方法是什么? 謝謝

編輯:我現在正在跟蹤第一個創建的結構,以便能夠從頭開始循環鏈接列表:

// create root struct to keep track of beginning of linked list
root = (struct PCB *)malloc(sizeof(struct PCB));
root->next = 0;  
root->reg1 = 20;

head = NULL;

// create first 10 structs with reg1 ranging from 20 to 30
for(i=21;i<=30;i++) {
    curr = (struct PCB *)malloc(sizeof(struct PCB));
    // link root to current struct if not yet linked
    if(root->next == 0){
        root->next = curr;
    }
    curr->reg1 = i;
    curr->next  = head;
    head = curr;
}

然后,當我創建需要插入排序的額外10個PCB結構時:

// create 20 more structs with random number as reg1 value
    for (j = 0;j<20;j++) {
        curr = (struct PCB *)malloc(sizeof(struct PCB));
        curr->reg1 = rand()%100;
        // get root for looping through whole linked list
        curr_two = root;
        while(curr_two) {
            original_next = curr_two->next;
            // check values against curr->reg1 to know where to insert
            if(curr_two->next->reg1 >= curr->reg1) {
                // make curr's 'next' value curr_two's original 'next' value
                curr->next = curr_two->next;
                // change current item's 'next' value to curr
                curr_two->next = curr;
            }
            else if(!curr_two->next) {
                curr->next = NULL;
                curr_two->next = curr;
            }
            // move to next struct in linked list
            curr_two = original_next;
        }
        head = curr;
    }

但這立刻導致了我的計划崩潰。

“最佳”方式可能是實現插入的新功能。 此函數將遍歷列表,直到找到next節點值小於或等於要插入的節點的節點,然后將新節點放在next節點之前。


這個功能怎么樣:

void insert(struct PCB **head, const int reg1, const int reg2)
{
    struct PCB *node = malloc(sizeof(struct PCB));
    node->reg1 = reg1;
    node->reg2 = reg2;
    node->next = NULL;

    if (*head == NULL)
    {
        /* Special case, list is empty */
        *head = node;
    }
    else if (reg1 < (*head)->reg1)
    {
        /* Special case, new node is less than the current head */
        node->next = *head;
        *head = node;
    }
    else
    {
        struct PCB *current = *head;

        /* Find the insertion point */
        while (current->next != NULL && reg1 < current->next->reg1)
            current = current->next;

        /* Insert after `current` */
        node->next = current->next;
        current->next = node;
    }
}

你會這樣稱呼它:

insert(&root, rand() % 100, 0);

這是@Joachim的簡化版本:

void insert(struct PCB **head, const int reg1, const int reg2)
{
    struct PCB *new ;
        /* Find the insertion point */
    for (       ;*head; head = & (*head)->next)
    {
        if ((*head)->reg1 > reg1) break;
    }

    new = malloc(sizeof *new );
    new->reg1 = reg1;
    new->reg2 = reg2;
    new->next = *head;
   *head = new;
}

這個想法很簡單:在任何情況下都不需要任何特殊情況:需要更改指針,這可能是根指針,尾指針,或LL中間的一些指針。 在任何/每種情況下:

  • 新節點實際上竊取了這個指針:
  • 它使它指向自己
  • 采用前一個值作為后繼(將其賦值給->next指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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