插入排序的链表

时间:2018-11-26 07:51:42

标签: c linked-list

我正在尝试将元素添加到已排序的链表中。当我尝试添加一个小于现有元素或小于第一个元素的元素时。它开始重复。有人可以帮我吗?

预先感谢

struct node {
    int key;
    struct node *next;
};

struct node *init() {
    struct node *head = 0;
    return head;
}

void create(struct node **head, int num) {
    struct node *tmp = *head;
    struct node *prev = NULL;
    struct node *new = calloc(1, sizeof(struct node));
    new->key = num;
    prev = tmp;
    if (*head == NULL)
        *head = new;
    while (tmp != NULL && tmp->key < num) {
        prev = tmp;
        tmp = tmp->next;
    }
    new->next = tmp;
    if (prev != NULL)
        prev->next = new;
}

int main() {
    int op;
    int num;
    struct node *head;
    head = init();
    do {
        printf("\n Menu \n 1.Insert \n 2.delete element \n 3.display List 
    \n 4. end program ");
        printf("n \n \n please enter an option :     ");
        scanf("%d", &op);
        switch (op) {
          case 1:
            printf("Enter data:");
            scanf("%d", &num);
            create(&head, num);
            break;
          case 2:
            printf("Enter data:");
            scanf("%d",&num);
            delete(&head, num);
            break;
          case 4:
            free(head);
            exit(0);
          default:
            printf("\n enter an option : ");
        }
    } while(1);
}

这就是我得到的:

program output

2 个答案:

答案 0 :(得分:1)

您的create函数有多个问题:

  • 应将其重命名为append_node或更明确的名称。
  • 您应避免使用诸如newdelete之类的C ++关键字,因为这可能会使某些编辑者和读者感到困惑。
  • 您应该测试内存分配失败并返回NULL,否则返回新的节点指针,以允许调用方测试错误。
  • 您错误地处理了num小于头节点的key的情况:新节点:将next指针设置为列表中的上一个节点,是头节点,有效地创建了一个循环。

这是更正的版本:

struct node *append_node(struct node **head, int num) {
    struct node *tmp, *new_node;

    new_node = calloc(1, sizeof(*new_node));
    if (new_node == NULL)
        return NULL;
    new_node->key = num;
    tmp = *head;
    if (tmp == NULL || tmp->key > num) {
        /* insert at the head */
        new_node->next = tmp;
        *head = new_node;
    } else {
        /* locate the insertion point */
        while (tmp->next != NULL && tmp->next->key <= num)
            tmp = tmp->next;
        new_node->next = tmp;
        tmp->next = new_node;
    }
    return new_node;
}

请注意,使用双指针定位插入点的版本更短,但更难理解:

struct node *append_node(struct node **head, int num) {
    struct node *new_node;

    new_node = calloc(1, sizeof(*new_node));
    if (new_node != NULL) {
        new_node->key = num;
        while (*head != NULL && (*head)->key < num)
            head = &(*head)->next;
        new_node->next = *head);
        *head = new_node;
    }
    return new_node;
}

答案 1 :(得分:1)

当您插入一个小于或等于第一个元素的元素时,您永远不会进入while循环。因此执行的代码会在您的列表中创建一个循环,因为prevtmp相同。

这是当您不进入循环时执行的代码:

prev = tmp;
...
new->next = tmp;
if (prev != NULL)
    prev->next = new; // You create the cycle here.