用c语言创建链表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用c语言创建链表相关的知识,希望对你有一定的参考价值。

下面是我写的程序,通过键盘输入数据创建链表。主程序中创建链表的函数已经运行成功了,因为printf("初始化成功,初始链表共有%d个结点\n",num); 这个语句有显示出来。
但是,马上就会弹出对话框说程序已停止,也就是没有办法读取链表中的数据,这是为什么?

下面是我写的程序:
#include <stdio.h>
#include <stdlib.h>

#define OK 1
#define ERROR 0

typedef int Status;
typedef int ElemType;
typedef struct LNode

ElemType data;
struct LNode *next;
LNode,*Linklist;

void CreateList_H(Linklist L,int n)

LNode *p;
ElemType val;
int i;
L=(LNode*)malloc(sizeof(LNode));
L->next=NULL;
for(i=0;i<n;i++)

p=(LNode*)malloc(sizeof(LNode));
scanf("%d",&(val));
p->data=val;
p->next=L->next;
L->next=p;



void main()

int num;
int loc=2;
ElemType temp;

Linklist List;
printf("输入创建链表的长度:");
scanf("%d",&num);

CreateList_H(List,num); //创建链表
printf("初始化成功,初始链表共有%d个结点\n",num);
temp=List->next->data;
printf("%d",temp);

参考技术A

主函数这里

Linklist List;
printf("输入创建链表的长度:");
scanf("%d",&num);
CreateList_H(List,num); //创建链表
改为 
LNode List;
printf("输入创建链表的长度:");
scanf("%d",&num);
CreateList_H(&List,num); //创建链表

函数内在堆上分配好内存,但是 没有传递到栈上

另外 你的变量名很迷人

追问

LNode List;

CreateList_H(&List,num); //创建链表
printf("初始化成功,初始链表共有%d个结点\\n",num);
temp=List.next->data;
printf("%d",temp);

但是也是一样的结果。

参考技术B void CreateList_H(Linklist L,int n)中的L是局部变量,你生成的头结点L不能被返回,应该改为:
Linklist CreateList_H(int n)
调用方式和函数内部返回值都需要相应改动。追问

我这里的void CreateList_H(Linklist L,int n),Linklist L是指针呀,为什么头结点不能被返回呀?

追答

形参,也是局部变量,作用域仅在函数内部,你改变了L,但main函数中变量List的值没有任何改变,返回不了啊。。。

你可以自己试一下,List初始化为NULL,按你的调用完,List是不是还是NULL?

你的目的是改变指针值(实参值),这个目的没有实现。

追问

那这样需要把整个结构设为全局变量么?
这已经是用指针传递了呀,还有没有什么办法呀?

追答

函数这样改:
Linklist CreateList_H(int n)

LNode *p;
ElemType val;
int i;
Linklist L=(LNode*)malloc(sizeof(LNode));
L->next=NULL;
for(i=0;idata=val;
p->next=L->next;
L->next=p;

return L;//返回值

调用这样改:
List=CreateList_H(num); //创建链表

函数和指针这块,你再看看书。。。

你的代码的重点是要修改实参值,与实参值的类型无关,这不成啊。。。

本回答被提问者采纳

C语言中怎样用链表保存结构体数据(动态数据结构)

我在做一个银行账户管理系统,现在定义了一下结构体:
struct client
char account[14]; //账号
char name[10]; //名字
char identity[20]; //身份证号
char address[15]; //地址
long int money; //存款(可存可取)
;

因为考虑到用户数量应该没有上限,所以采用链表的动态数据结构,以达到目的。这里有几点疑问:
1.我准备用单链表,是用头插法好还是尾插法好呢?哪种更好实现数据的追加和删除呢?
2.我在定义了结构体后又定义了链表,如下所示:
struct client
char account[14];
char name[10];
char identity[20];
char address[15];
long int money;
;
/*定义记录用户数据的链表*/
struct node //定义节点类型node
char account[14];
char name[10];
char identity[20];
char address[15];
long int money;
struct node *next;
;
这样做对的吗?我想用链表对client结构体进行插入、遍历、删除、修改等操作,是不是在定义结构体之后再这样定义一个链表呢?

3.(重要)定义完链表之后,就要实现注册功能,按照要求,要把账号、姓名等信息以二进制流存储到文件当中,比如我要把account通过链表插入并保存到二进制文件中,应该怎么写呢?重点突出指针的定义和使用,像文件打开判断部分可以省略
重点:1)定义完链表后怎么定义和使用指向成员们的指针呢?
2)二进制文件是保存为.bat格式吗?
3)执行这条语句来保存输入的内容吗?
for(i=0;i<n;i++)
if(fwrite(&stud[i],sizeof(struct student_type),1,fp)!=1) //为什么只有判断,没有保存的过程呢?
printf("flie write error\n");

fclose(fp);

我对以上的内容不是很了解,希望知道的人帮忙解答,谢谢了。

单向链表很简单的,你这几这么就可以了:
struct client
char account[14]; //账号
char name[10]; //名字
char identity[20]; //身份证号
char address[15]; //地址
long int money; //存款(可存可取)
client* pNext; //指向下一个节点,如果是最后一个节点则为NULL
;

然后,程序里只需要保存第一个节点就行了:
client* head = (client*)malloc(sizeof(client)); //第一个节点这么产生
head->pNext = NULL; //该表只有一个节点,所以第一个也是最后一个,别忘记赋0

插入的时候从头部插入就行了
client* p = (client*)malloc(sizeof(client));
p->pNext = head;
head = p; //将原来的头付给p的pNext指针,然后原来保存头元素的指针用p取代。

遍历链表更加容易了
client* pNode = head;
while (pNode)

printf(pNode->account); //比如打印所有客户的帐号
pNode = pNode->pNext; //让pNode指向下一个节点
//如果该节点是最后一个节点,那么pNode就会变成NULL,因为最后一个节点的pNext指针是NULL,while循环就会因为pNode为0而结束


保存进文件的时候相当于遍历一边所有的元素,读取的时候则一个一个读取,然后重新插入链表。最后,提醒一下的是别忘记用free释放由malloc分配的内存。

另外,考虑使用C++,可以更好的管理内存,思路也会更清晰。而且,如果是为了应用,根本不需要自己开发链表类,用STL就可以了,STL不仅提供双向链表,还有Map,HashMap等数据结构,非常适合特别大的数据量保存和查找,链表的查找很慢的,找一个数据相当于要把链表全部过一遍。
参考技术A 1.用头插法。因为数据追加和删除比较多,追加的话,头插法可以直接插,用尾插降低了时间效率,删除用两个一样。
2./*结构体定义*/
struct client
char account[14];
char name[10];
char identity[20];
char address[15];
long int money;
;
/*链表结点定义*/
struct node
struct client band_inf;
struct node *next;
;
应该把结构体结点定义成链表的成员,这样链表才对。如果像你那样定义的话,完全不用定义结构体,链表就搞定了。因为你在链表里面把结构的成员都又定义了。
3.
1),定义结点:p1=(struct node*)malloc(sizeof(struct node)) ;表示定义一个node型的结点指针
使用,这个要看具体怎么用了。比如说删除searchp,priorp是searchp的前面一个结点,这样写
priorp->next=searchp->next;
delete searchp; 即可
插入newnode在searchp的后面,可以这样:
newnode->next=searchp->next;
searchp->next=newnode;
2)广义的二进制就是文件,你存成什么文件都行。.txt就行。
3)有保存的。if(fwrite(&stud[i],sizeof(struct student_type),1,fp)!=1)。里面有个fwrite就是写入文件,在判断的过程中,能写入文件的就已经写入了。 望采纳。本回答被提问者和网友采纳
参考技术B 链表有多种形式,如:单向链表,双向链表,单向循环链表,双向循环链表。将链表结构定义为list_t,则该类型中一定(至少)存在一个指向下一节点的指针list_t *next;除了这个指针,list_t 中可以包含其它类型的数据,包括结构体变量。比如:typedef struct
struct usr_struct data;
list_t *next;
list_t;
参考技术C p1=(struct studinf*)malloc(sizeof(struct studinf)) 表示开辟一段strunt 1.结构体和共用体类型数据的定义方法和引用方法。 2.用指针和结构体构成 参考技术D 厉害

以上是关于用c语言创建链表的主要内容,如果未能解决你的问题,请参考以下文章

关于C语言链表的

C语言链表问题,作业编程。编好出现问题。高手看下。

C语言链表的使用

C语言链表问题

C语言两个链表连接简单问题

C语言: 链表查询