【问题标题】:Create a sorted linked list创建一个排序的链表
【发布时间】:2020-09-18 09:25:49
【问题描述】:

将近 3 年后,我开始重新学习 C

我创建了一个Linked list,并希望将其扩展到创建一个排序的链表。这是我的代码:

typedef struct node{
int data;
struct node *ptr;
}node;

node* insert(node* head, int num){
node *temp,*prev,*next;
temp = (node*)malloc(sizeof(node));
temp->data = num;
temp->ptr = '\0';
if(head=='\0'){
    head=temp;
}else{
    next = head;
    prev = next;
    while(next->data<=num){
        prev = next;
        next = next->ptr;
    }
    if(next==NULL){
        prev->ptr = temp;
    }else{
        temp->ptr = prev->ptr;
        prev-> ptr = temp;
    }

}
return head;
}

void main(){
int num;
node *head, *p;
head = '\0';
do{
    printf("Enter a number");
    scanf("%d",&num);
    if(num!=0)
        head = insert(head,num);
}while(num!=0);
p = head;
printf("\nThe numbers are:\n");
while(p!='\0'){
    printf("%d ",p->data);
    p = p->ptr;
}
}

这是我的想法。我遍历列表,直到找到输入的数字&gt;=。我将前一个节点存储在prev 中,next 节点包含当前值。如果next是null,则列表结束,列表中编号最高的,所以要插入最后一个位置,如果编号在中间某个位置,则prev节点的地址部分存储在临时节点地址部分现在临时节点指针保存下一个节点的地址。

编辑: 我的代码有问题,如果我输入 1,2,我会收到 a.exe has stopped working 的错误消息。我正在使用 MinGW 进行编译。当用户输入 0 时,我正在打破循环。

【问题讨论】:

标签: c linked-list


【解决方案1】:

你必须换行

while(next->data<=num)

while(next!='\0' && next->data<=num)

当您插入第二个元素时,next 在第二次迭代中将是'\0',并尝试使用next-&gt;data 获取字段data 将导致分段错误。

如果next!='\0' 为假(因此next=='\0')的while 条件已更改,则while 被中止,并且由于&amp;&amp; 的短路next-&gt;data 未被计算。


编辑

您的代码中存在更多问题。

如果您查看输入 2 1 0,那么正确运行程序的输出应该是 1 2,但它是 2 1。问题在于,在您的 insert 函数中,您没有考虑插入当前最小元素将成为新头部的情况。

另一个问题是你最后没有释放malloced内存,这会导致内存泄漏。

我更改了您的代码以使其行为正确:

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
    int data;
    struct node *ptr;
} node;

node* insert(node* head, int num) {
    node *temp, *prev, *next;
    temp = (node*)malloc(sizeof(node));
    temp->data = num;
    temp->ptr = NULL;
    if(!head){
        head=temp;
    } else{
        prev = NULL;
        next = head;
        while(next && next->data<=num){
            prev = next;
            next = next->ptr;
        }
        if(!next){
            prev->ptr = temp;
        } else{
            if(prev) {
                temp->ptr = prev->ptr;
                prev-> ptr = temp;
            } else {
                temp->ptr = head;
                head = temp;
            }            
        }   
    }
    return head;
}

void free_list(node *head) {
    node *prev = head;
    node *cur = head;
    while(cur) {
        prev = cur;
        cur = prev->ptr;
        free(prev);
    }       
}

int main(){
    int num;
    node *head, *p;
    head = NULL;
    do {
        printf("Enter a number");
        scanf("%d",&num);
        if(num) {
            head = insert(head, num);
        }
    } while(num);
    p = head;
    printf("\nThe numbers are:\n");
    while(p) {
        printf("%d ", p->data);
        p = p->ptr;
    }
    free_list(head);
    return 0;
}

请参阅https://ideone.com/wT5iQ8,了解我在测试输入上的代码以及正确的输出。

【讨论】:

  • 为什么要将指针与字符进行比较?无论如何,只要while (next &amp;&amp; next-&gt;data &lt;= num) 就足够了。
  • @FredLarson 你是对的,OP 应该使用NULL 而不是'\0',但我想在他的代码中尽可能少地改变:)。它也适用于'\0'
  • @Dibya 我编辑了我的问题并添加了我的工作代码。我希望没有更多的错误,因为我很快测试了它。如果您有任何问题,请不要犹豫:)
  • @halex:当第一个数字大于第二个数字时,我得到了它,它被忽略了。非常感谢..
猜你喜欢
  • 1970-01-01
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 2014-08-12
  • 2014-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多