知道为什么我的程序在显示正确结果后会崩溃? (即我插入6 2 4 3他返回2 3 4 6但控制台在之后崩溃!)
主要思想是在用户给出整数后对链表进行排序。我试图解决它,就好像它是一个冒泡类型,但由于某种原因,它不是100%可操作的。对不起葡萄牙语的评论!
#define ITEM_TYPE int
typedef struct lnode* List;
typedef struct lnode{
ITEM_TYPE info;
List next;
}List_node;
void ordenalista(List lista){
int contador = 0, i;
/* lista é uma lista recebida */
List head = lista; /* termos sempre disponível o início da lista*/
List actual = NULL; /*lista vazia, ou nó */
List temp = NULL;
if(head == NULL || head->next == NULL){ /* caso de lista vazia ou so com 1 elemento*/
printf("A lista esta vazia ou tem apenas um elemento");
return 0;
}
while(head != NULL){ /* contar quantos elementos tem a lista*/
contador++;
head = head->next;
printf("%d \n", contador);
}
for(i=0; i<contador; i++){ /* percorrer todos os elementos da lista*/
while(head->next != NULL){ /* enquanto não chegarmos ao final da lista*/
if(head->info > head->next->info){ /* se o valor do atual for maior que o valor do seguinte*/
temp = head->next;
head->next = head->next->next; /* não precisamos de usar actual->data, apenas precisamos de mudar os ponteiros*/
temp->next = head;
}
}
}
}
void ex213(){
int numero;
List lista;
lista = create_list();
while((scanf("%d",&numero)) == 1){ /* lê da esquerda para a direita. SCANF DÁ 1 SE INSERIR INTEIRO, 0 CASO CONTRÁRIO */
insertwithoutorder(lista, numero);
}
ordenalista(lista);
printlist(lista);
}
void insertwithoutorder(List lista, ITEM_TYPE it){
List no;
List ant, inutil;
no = (List)malloc(sizeof(List_node));
if (no != NULL) {
no->info = it;
searchwithoutorder(lista, it, &ant, &inutil);
/*while(ant->next != NULL){
ant = ant->next;
}*/
no->next = NULL;
ant->next = no;
}
}
void searchwithoutorder(List lista, ITEM_TYPE chave, List *ant, List*actual){
*ant = lista; *actual = lista->next;
while ((*actual) != NULL){
*ant = *actual;
*actual = (*actual)->next;
}
if ((*actual) != NULL && (*actual)->info != chave)
*actual = NULL; /* Se elemento não encontrado*/
}
void printlist(List lista){
List l = lista->next; /* Salta o header */
while (l){
printf("%d ", l->info);
l=l->next;
}
}
int main(){
ex213();
return 0;
}
答案 0 :(得分:1)
崩溃必须发生在名为printlist()
的函数(现在)中,因为在该函数返回后,程序不会执行任何其他操作。
我没有看到printlist()
的任何内在错误,但它确实取决于列表处于有效状态。特别是,我最好猜测程序失败的原因是最后一个列表元素的next
指针包含垃圾值而不是预期的NULL
。您可以通过在调试器中运行程序来验证它。
那么列表可能会如何被破坏?
好吧,你的插入功能看起来不错。它所依赖的searchwithoutorder()
函数实际上并不像它的名字所说的那样,但它确实做insertwithoutorder()
需要它做的事情。
离开排序函数ordenalista()
,这里我有点乱了。我不知道您发布的版本如何进行任何排序。你有一个像这样的while循环:while(head != NULL){...}
,内部没有break
或goto
,所以当控制超出这个循环时,它必须是head == NULL
。然后,在不修改head
的值的情况下,您将进入如下的循环嵌套:
for(i=0; i<contador; i++) { /* percorrer todos os elementos da lista*/
while(head->next != NULL) { /* enquanto não chegarmos ao final da lista*/
...
}
}
但是那时head
是NULL
,所以取消它会产生未定义的行为。如果该行为本身并不是崩溃,那么正确猜测和解除引用意味着的指针是一种极不可能的替代方案。此外,您不会修改循环体中的head
,因此仍为 NULL
。这个循环还有其他问题。
好像所有的东西都不够,你的排序函数也没有好办法改变列表中的哪个元素 - 至少没有一个对调用者有效。
基本上,我不相信你已经准确地描述了这个问题。它必须是您观察到的失败行为与您描述的失败行为不同,或者您提供的代码与您描述的行为不当的程序不对应。
答案 1 :(得分:1)
#include <stdio.h>
#include <stdlib.h>
#define ITEM_TYPE int
typedef struct lnode* List;
typedef struct lnode{
ITEM_TYPE info;
List next;
} List_node;
List create_list(void){
//top node unused
return calloc(1, sizeof(List_node));//note : might NULL != 0
}
List lastNode(List lista){
while (lista->next != NULL){
lista = lista->next;
}
return lista;
}
void insertwithoutorder(List lista, ITEM_TYPE it){
List no, ant;
no = create_list();
if (no != NULL) {
no->info = it;
no->next = NULL;
ant = lastNode(lista);
ant->next = no;
} else {
printf("failed to create a new node.\n");
}
}
void ordenalista(List lista){
List head = lista;
List actual, neighbor, sentinel = NULL;
if(head->next == NULL){
printf("A lista esta vazia\n");
return ;
}
while(head->next != sentinel){
actual = head->next;
neighbor= actual->next;
while(neighbor != sentinel){
if(actual->info > neighbor->info){
ITEM_TYPE temp = actual->info;
actual->info = neighbor->info;
neighbor->info = temp;
}
actual = neighbor;
neighbor= neighbor->next;
}
sentinel = actual;
}
}
void printlist(List lista){
List l = lista->next;
while (l){
printf("%d ", l->info);
l=l->next;
}
puts("");
}
void ex213(void){
int numero;
List lista = create_list();
while((scanf("%d", &numero)) == 1){
insertwithoutorder(lista, numero);
}
//printlist(lista);
ordenalista(lista);
printlist(lista);
//deallocate ?
}
int main(void){
ex213();
return 0;
}
答案 2 :(得分:0)
当询问用户数据时,让用户知道您要求的内容以及如何处理/终止任何输入请求是很有用的。空白行上闪烁的光标告诉用户什么都没有。 (即使它正在测试你,它可以帮助防止错误类型的无意按键)。例如,您的ex213
函数在空行上留下一个闪烁的光标,让用户想知道“程序是否挂起?” “它遇到了竞争条件吗?”当询问用户链接列表数据时,一个或两个简单的附加行可以真正起到帮助作用。例如:
void ex213 (void)
{
int numero;
List lista = create_list ();
printf ("\nEnter a number to add to the list [CTRL+D] when done:\n\n");
while (printf (" data: ") && (scanf ("%d", &numero)) == 1) {
insertwithoutorder (lista, numero);
}
ordenalista (lista);
printf ("\n\nThe ordered linked-list is:\n\n");
printlist (lista);
printf ("\n");
//deallocate ?
}
<强>输出强>
$ ./bin/ll_single_sort
Enter a number to add to the list [CTRL+D] when done:
data: 2
data: 8
data: 20
data: 6
data: 9
data: 1
data:
The ordered linked-list is:
1 2 6 8 9 20
将其添加到BLUEPIXY提供的答案中可提供您正在寻找的结果。