[英]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.