[英]Insertion sort on linked list in C?
I've tried searching for a problem similar to mine, but haven't found much help. 我试过寻找类似于我的问题,但没有找到太多帮助。
I have a linked list of structs of this type: 我有一个这种结构的链表:
struct PCB {
struct PCB *next;
int reg1, reg2;
};
I first create 10 PCB structs linked together in this way: 我首先以这种方式创建10个PCB结构:
for(i=20;i<=30;i++) {
curr = (struct PCB *)malloc(sizeof(struct PCB));
curr->reg1 = i;
curr->next = head;
head = curr;
}
I then need to create 20 more PCB structs, but their reg1
values need to be generated using rand()
. 然后我需要再创建20个PCB结构,但是需要使用
rand()
生成它们的reg1
值。 I'm currently doing that as so: 我正在这样做:
for (j = 0;j<20;j++) {
curr = (struct PCB *)malloc(sizeof(struct PCB));
curr->reg1 = rand()%100;
curr->next = head;
head = curr;
}
However, when inserting these PCB structs into the linked list with random reg1
values, I need to be inserting them in the linked list in order (insertion sort). 但是,当使用随机
reg1
值将这些PCB结构插入到链表中时,我需要按顺序将它们插入到链表中(插入排序)。 What is the best way to approach this in just a single-link linked list? 在单链接链表中处理此问题的最佳方法是什么? Thanks
谢谢
EDIT: I am now keeping track of the first created struct to be able to loop through the linked list from the beginning: 编辑:我现在正在跟踪第一个创建的结构,以便能够从头开始循环链接列表:
// 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;
}
Then, when I'm creating the additional 10 PCB structs that need to be insertion sorted: 然后,当我创建需要插入排序的额外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;
}
But this immediately crashed my program. 但这立刻导致了我的计划崩溃。
The "best" way would probably be to implement a new function for the insertion. “最佳”方式可能是实现插入的新功能。 This function would iterate over the list until it finds a node whose
next
nodes value is less or equal to the node you want to insert, then put the new node before the next
node. 此函数将遍历列表,直到找到
next
节点值小于或等于要插入的节点的节点,然后将新节点放在next
节点之前。
How about this function: 这个功能怎么样:
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;
}
}
You would call it like this: 你会这样称呼它:
insert(&root, rand() % 100, 0);
Here is the simplified version of @Joachim: 这是@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;
}
The idea is simple: there need not be any special cases , in any case: a pointer needs to be changed, this could be the root pointer, or the tail pointer, or some pointer in the midddle of the LL. 这个想法很简单:在任何情况下都不需要任何特殊情况:需要更改指针,这可能是根指针,尾指针,或LL中间的一些指针。 In any/every case:
在任何/每种情况下:
->next
pointer. ->next
指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.