我正在尝试将元素添加到已排序的链表中。当我尝试添加一个小于现有元素或小于第一个元素的元素时。它开始重复。有人可以帮我吗?
预先感谢
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);
}
这就是我得到的:
答案 0 :(得分:1)
您的create
函数有多个问题:
append_node
或更明确的名称。new
和delete
之类的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循环。因此执行的代码会在您的列表中创建一个循环,因为prev
和tmp
相同。
这是当您不进入循环时执行的代码:
prev = tmp;
...
new->next = tmp;
if (prev != NULL)
prev->next = new; // You create the cycle here.