您的位置:首页 > 其它

线性表的链式存储结构(菜鸟问题)

2014-05-11 11:17 190 查看
#include <stdio.h>
#include <stdlib.h>
/*线性表的链式存储结构*/
#define OK 1
#define ERROR -1

typedef int ElemType;
typedef int Status;
typedef struct {
//链式存储结构有哪些要素?
//每个元素有数据项和指针域
ElemType data;
struct Node *next;
}Node,*List;

//有哪些操作呢?
Status InitList(List L){
//初始化链表
L->data=NULL;
L->next=NULL;
return OK;
}
//获取元素
Status GetElem(List L ,int i,ElemType *e){
int j;
List p;
p=L->next;
j=1;
while(p && j<i){
p=p->next;
++j;
}
if(!p || j>i)
return ERROR;
*e=p->data;
return OK;
}

//获取链表长度
int GetLength(List L){
int i;
i=0;
List P;
P=L->next;
while(P){
P=P->next;
i++;
}
return i;
}

Status StoreNode(List *L,ElemType e){
//将元素e存入链表尾部
List p,t;
p=*L;
while(p->next){
p=p->next;
}
//得新建一个结点
t=(List)malloc(sizeof(Node));
t->data=e;
t->next=NULL;
p->next=t;
return OK;

}

/*插入元素*/
Status InsertNode(List *L,ElemType e,int i){
//在位置i上插入元素e,链表的元素从0开始记
List p;
p=*L;
int j;
j=0;
while(p->next && j<i){
p=p->next;
j++;
}
//新建一个结点
List t;
t=(List)malloc(sizeof(Node));
t->data=e;
t->next=p->next;
p->next=t;
return OK;

}

int main()
{
List L,t;
if(InitList(L)){
printf("初始化链表成功");
}else{
printf("error");
}

int n;
printf("输入要存入的元素个数");

scanf("%d",&n);
int i,temp,e,location;
for(i=0;i<n;i++){
scanf("%d",&temp);
StoreNode(&L,temp);
}

//插入元素
printf("\n输入插入的位置及元素值\n");
scanf("%d,%d",&location,&e);
InsertNode(&L,e,location);
// 查看输出结果

t=L->next;
while(t){
printf("%d\t",t->data);
t=t->next;

}

GetElem(L,2,&e);
printf("%d\n",e);
printf("%d\n",GetLength(L));

return 0;
}


以上程序整体能够运行;

但是发现问题

如果没有如下这段代码

t=L->next;
while(t){
printf("%d\t",t->data);
t=t->next;

}


会出现异常,直接终止程序;为什么?单独调用各个函数也会出现问题。

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

原来是没有给链表L分配存储空间;

如果在初始化时改为

Status InitList(List *L){
//初始化链表
*L=malloc(sizeof(Node));
(*L)->data=NULL;
(*L)->next=NULL;
return OK;
}


调用

InitList(&L)
可以解决此问题。

问题2:

//1. 单链表的初始化
Status InitList(List *L){
*L=(List)malloc(sizeof(Node));//*L指向一个结点的存储空间
(*L)->data=1;
(*L)->next=NULL;
return OK;
}

//2. 当链表的整表创建,依次从尾部插入结点
Status CreateTailList(List *L){
int i,n;
List t;//新建临时结点
printf("输入要创建的单链表的结点的个数,n=\n");
scanf("%d",&n);

if(OK!=InitList(&L)){
return ERROR;
}

//初始化随机数种子,准备产生随机数,依赖<string.h>头文件
srand(time(0));
for(i=0;i<n;i++){

//
t=(List)malloc(sizeof(Node));
t->data=rand()%100+1;//产生1~100的随机数
t->next=(*L)->next;//指向L的尾部
(*L)->next=t;
}
return OK;

}


CreateTailList中调用InitList会出现问题

int main()
{
List L;

// InitList(&L);
if(OK==CreateTailList(&L)){
//输出初始化后的链表
L=L->next;//指向第一个结点
while(L){
printf("%d\t",L->data);
L=L->next;
}
}

return 0;
}
以上代码调用会出现问题,直接终止程序;

但是如果在CreateTailList中注销初始化函数InitList;而在main函数中单独调用InitList后运行CreateTailList,又可以正常运行!!

为毛?

问题3:

Status CreateHeadList(List *L){
int i,n;
List t,p;//新建临时结点
printf("输入要创建的单链表的结点的个数,n=\n");
scanf("%d",&n);

//初始化随机数种子,准备产生随机数,依赖<string.h>头文件
srand(time(0));
//p=*L;
for(i=0;i<n;i++){

//
t=(List)malloc(sizeof(Node));
t->data=rand()%100+1;//产生1~100的随机数
(*L)->next=t;
(*L)=t;
}
(*L)->next=NULL;
return OK;

}


运行失败

但是改为以下代码就没有问题!(只是将*L用p来替换)

Status CreateHeadList(List *L){
int i,n;
List t,p;//新建临时结点
printf("输入要创建的单链表的结点的个数,n=\n");
scanf("%d",&n);

//初始化随机数种子,准备产生随机数,依赖<string.h>头文件
srand(time(0));
p=*L;
for(i=0;i<n;i++){

//
t=(List)malloc(sizeof(Node));
t->data=rand()%100+1;//产生1~100的随机数
p->next=t;
p=t;
}
p->next=NULL;
return OK;

}


这又是为什么?

问题4:

int GetLEN(List L){
int length;
length=0;
List p;
p=L->next;
while(p){
length++;
p=p->next;
}
//*len=length;
return length;

}


在main函数中调用直接终止程序了!指针啊,指针!!!!!!!!

printf("当前链表长度为:%d\n",GetLEN(L));


妈蛋,终于发现问题了,原来是在主函数中调用函数时出了问题

main中

List L;

InitList(&L);
if(OK==CreateHeadList(&L)){
printf("当前链表长度为:%d\n",GetLEN(L));
//输出初始化后的链表
L=L->next;//指向第一个结点
while(L){
printf("%d\t",L->data);
L=L->next;
}
}

printf("当前链表长度为:%d\n",GetLEN(L));


注意:当我查看链表各个结点的值时,直接对L进行移动指针操作,L=L->next;当循环结束后,L指向的是NULL,在后面的GetLEN(L)中,其实是把NULL传给了L,当然会出现问题了!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: