您的位置:首页 > 编程语言 > C语言/C++

线性表的链式存储(单链表)的c语言实现

2014-05-12 21:43 309 查看
#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;

//定义单链表的基本操作
//本程序中设定每个单链表都有一个头结点,末尾都指向NULL

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

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

//初始化随机数种子,准备产生随机数,依赖<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;

}
//3. 单链表的整表创建,依次从头部插入,即顺序插入a(1)->a(2)->...->a(n)
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;

//p=L->next;
while(L->next){
//头结点不计入长度
length++;
L=L->next;
}
//*len=length;
return length;

}
//4.单链表的插入操作
Status InsertNode(List *L,int i,ElemType e){

//在第i个结点处插入元素e;i可以从1~len+1
int j,len;
j=1;
List p,t;
p=*L;

len=GetLEN(p);
if(i>len+1 || i<1){
printf("\n请检查输入的i值是否超界!\n");
return ERROR;
}

//准备插入
while(j<i && p->next){
//将链表指针移到第i个结点
p=p->next;
j++;
}
//新建结点
t=(List)malloc(sizeof(Node));
t->data=e;
t->next=p->next;
p->next=t;
return OK;

}
//5. 单链表的删除结点
Status DeleteNode(List *L,int i){
//删除第i个结点
int j;
List p,t;
p=*L;
//先判断位置

if(!p || i<1 || i>GetLEN(p)){
printf("删除元素的位置超界!");
return ERROR;
}
j=1;
while(j<i && p->next){
p=p->next;
j++;
}
t=p->next;//指向第i个结点
p->next=t->next;
free(t);//让系统回收此结点,释放内存
return OK;
}

//单链表的元素获取
Status GetElem(List L,int i,ElemType *e){
//获取第i个结点的元素,将值传给e
if(i>GetLEN(L) || i<0){
return ERROR;
}
int j;
j=0;
while(j<i && L->next){
L=L->next;
j++;
}
*e=L->data;
return OK;
}

//单链表的整表删除,置空表
Status EmptyList(List *L){
List p,t;
p=(*L)->next;//指向第一个结点
while(p){
t=p->next;
free(p);
p=t;

}
(*L)->next=NULL;
return OK;
}

int main()
{
List L,t;

InitList(&L);
if(OK==CreateHeadList(&L)){
//输出初始化后的链表
//引入一个新的链表接收L,防止对L操作后影响对L的后续操作
//下面的代码如果while循环直接对L,即while(L),那么循环结束后,L指向的是NULL;进而影响对L的后续操作!

t=L->next;//指向第一个结点
while(t){
printf("%d\t",t->data);
t=t->next;
}
}

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

printf("\n准备插入结点\n输入插入结点的位置及数值,用逗号分隔\n");
int n,e;
scanf("%d,%d",&n,&e);
if(OK==InsertNode(&L,n,e)){
printf("\n插入元素成功,新的链表为:\n");
t=L->next;//指向第一个结点
while(t){
printf("%d\t",t->data);
t=t->next;
}
printf("当前链表长度为:%d\n",GetLEN(L));

}else{
printf("\n插入失败\n");
}
printf("输入要删除的结点位置n=\n");
scanf("%d",&n);
if(OK==DeleteNode(&L,n)){
printf("删除成功");
t=L->next;//指向第一个结点
while(t){
printf("%d\t",t->data);
t=t->next;
}
printf("当前链表长度为:%d\n",GetLEN(L));

}else{
printf("\n删除失败\n");
}

printf("输入想要获取元素的位置i=\n");
scanf("%d",&n);
int data;
if(OK==GetElem(L,n,&data)){
printf("链表第%d个元素的值为%d\n",n,data);
}

if(OK==EmptyList(&L)){
printf("当前链表长度为:%d\n",GetLEN(L));
printf("链表为空!");
}else{
printf("链表置空失败!");
}

if(OK==CreateHeadList(&L)){
//输出初始化后的链表
//引入一个新的链表接收L,防止对L操作后影响对L的后续操作
//下面的代码如果while循环直接对L,即while(L),那么循环结束后,L指向的是NULL;进而影响对L的后续操作!

t=L->next;//指向第一个结点
while(t){
printf("%d\t",t->data);
t=t->next;
}
}

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

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: