问题描述
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
struct node {
int data;
struct node* nextptr;
} * manode;
void add();
void delete ();
void display();
int main()
{
int choice;
int echoice;
while (choice != 4) {
printf("\n \t ENTER YOUR CHOICE FOR SINGLE LINKED LIST ");
printf("\n \t 1. ADD ELEMENT ");
printf("\n \t 2. disPLAY ELEMENT ");
printf("\n \t 3. DELETE ELEMENT ");
printf("\n \t 4. EXIT ");
scanf("%d",&choice);
switch (choice) {
case 1:
while (echoice != 0) {
add();
printf("\n DO YOU WANT TO CONTINUE 1/0 ");
scanf("%d",&echoice);
}
break;
case 2:
display();
break;
case 3:
delete ();
break;
case 4:
exit(0);
break;
default:
printf("\n \t WRONG VALUE ENTERED ");
};
}
return 0;
}
#Add function is responsible to add the first node and all the remaining nodes as well.
void add()
{
struct node *tmp,*tmp2;
tmp = malloc(sizeof(struct node));
tmp2 = malloc(sizeof(struct node));
int value;
printf(" ENTER THE VALUE YOU WANT TO ENTER ");
scanf("%d",&value);
if (manode == NULL) {
manode = malloc(sizeof(struct node));
printf(" FirsT ENTRY ");
manode->data = value;
manode->nextptr = NULL;
tmp = manode;
printf("THE DATA %d ",manode->data);
}
else {
if (tmp2 == NULL) {
printf("\n MEMORY ALLOCATION Failed");
}
else {
tmp2->data = value;
tmp2->nextptr = NULL;
tmp->nextptr = tmp2;
tmp = tmp->nextptr;
}
}
//manode=tmp;
}
void display()
{
struct node* tmp1;
if (manode == NULL) {
printf(" MEMORY ALLOCATION Failed ");
}
else {
tmp1 = manode;
while (tmp1 != NULL) {
printf("\n%d DATA IS disPLAY \n",tmp1->data);
tmp1 = tmp1->nextptr;
}
}
}
void delete ()
{
struct node* tmp;
if (manode == NULL) {
printf("nothing TO DELETE ");
}
else {
tmp = malloc(sizeof(struct node));
}
}
请复制并编译代码,它可以工作,但没有显示列表中的内容。请复制并编译代码,它可以工作,但不显示列表中的内容。请复制并编译代码,它可以工作,但不显示列表中的内容。请复制并编译代码,它是工作,但它不显示列表中的内容。
解决方法
据我所知,您的代码存在许多问题。
- 不要使用
conio.h
。这东西来自 80 年代,对现代程序没有任何增加,但问题 - 永远不要尝试实现 ADT --- 任何容器,例如列表、集合、映射 --- 作为节点。它只会给您带来麻烦:列表是节点的集合。每个节点都有一个有效载荷,一些数据。该数据可以有一个键,用于比较记录。节点不是列表。节点不是数据。列表不是节点。从列表中可以看出,数据是节点。通过这种方式,您可以将任何内容用作列表中的数据。这就是容器的目的:一次编写,始终使用。并且该列表具有元数据,一些明显的控件,例如其大小、起始地址、结束地址以及其他可能的内容。
- 不要使用
void()
。是一种浪费,有时会出错。在你的情况下是一个错误。所有的指针都埋在函数内部并死在那里。所以display()
和add()
不起作用 - 不要typedef 指针。这是一团糟。在你的情况下
manode
是一个指针。几天后,有人,甚至是你自己,还记得什么是什么吗?如果manode
是结构体的 typedef,大家都知道
manode* many_nodes[30]
将 many_nodes
声明为指向结构数组的指针。星号说明一切:many_nodes
是指向 manode
的指针。 BTOS 如果您将 *
埋在 typedef 中,您将始终需要引用标头中的代码。
- 不要将列表的代码与 I/O 混合。它只会让你的喜欢更难。您有一个简单的
int
列表,因此例如将add()
声明为int add(int item,List* the_list)
。这种方式更具可读性,您可以编写一个简单的循环,用几百个或仅一个节点填充列表并开始测试。 - 如果您有菜单,只需将其编写为返回用户选项的函数即可。但稍后将其添加到程序中。菜单对列表和程序没有任何作用
-
scanf()
不是为了从键盘读取输入而写入的。它用于扫描格式化输入,因此得名。从标准输入读取时,它总是会给你带来麻烦。但是尽你的一份力量,至少总是测试 scanf() 的返回。总是。 rtfm。 - 不要在 printf 上写
\n \t
。仅使用制表符或计算空格。 - 总是初始化所有变量。在您的代码中,您开始在未设置任何值的情况下测试
choice
和echoice
。 - 在选项 1 上循环有什么意义,因为无论如何用户都需要输入答案并输入
1
?
回到你的程序
请参阅下面使用我上面写的一些内容重新排列的代码。与您的代码进行比较
示例代码
#include <stdio.h>
#include <stdlib.h>
typedef struct st_node
{
int data;
struct st_node* nextptr;
} Node;
typedef struct tlist
{
unsigned size;
Node* start;
} List;
int add(int,List*);
int delete (int,List*);
int display(List*);
int menu();
int main(void)
{
List one;
one.size = 0;
one.start = NULL;
int res = menu();
printf("menu returned %d\n",res);
display(&one);
for( int i = 0; i<10; i+=1)
add(i,&one);
display(&one);
return 0;
}
int add(int value,List* l)
{
if ( l == NULL ) return -1;
Node* node = (Node*) malloc(sizeof(Node));
// simplest: insert at the beginning
node->nextptr = l->start;
node->data = value;
l->start = node;
l->size += 1;
return l->size;
};
int display(List* l)
{
if ( l== NULL) return -1;
if ( l->size == 0 )
{
printf("\n\tlist is empty\n\n");
return 0;
}
else
{
printf("\n\t%d elements in the list\n\n",l->size);
};
Node* p = l->start;
for( unsigned i = 0; i< l->size; i+=1)
{
printf("%3d: %11d\n",1+i,p->data);
p = p->nextptr;
};
return l->size;
}
int delete (int v,List* l)
{
return 0;
}
int menu()
{
int choice = 0;
int res = 0;
printf(
"\n\tENTER YOUR CHOICE FOR SINGLE LINKED LIST:\n\
\n\t\t1. ADD ELEMENT\
\n\t\t2. DISPLAY ELEMENT\
\n\t\t3. DELETE ELEMENT\
\n\t\t4. EXIT\
\n\n\t\tYour choice: ");
while( res != 1 )
{
res = scanf("%d",&choice);
if ( choice >=1 && choice <= 4 ) return choice;
};
return 4;
}
输出
ENTER YOUR CHOICE FOR SINGLE LINKED LIST:
1. ADD ELEMENT
2. DISPLAY ELEMENT
3. DELETE ELEMENT
4. EXIT
Your choice: 2
menu returned 2
list is empty
10 elements in the list
1: 9
2: 8
3: 7
4: 6
5: 5
6: 4
7: 3
8: 2
9: 1
10: 0
这只是一个使用更易于管理的列表的例子。