线性表的链式存储结构 ( 链表 )
Posted 幻向二哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表的链式存储结构 ( 链表 )相关的知识,希望对你有一定的参考价值。
目录
线性表的链式存储结构
1.相比于线性表的顺序存储结构的优缺点
相比于线性表的顺序存储结构的优点
(1)链式存储时,相邻数据元素可随意存放,但所占存储空间分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针
优点:插入或删除元素时很方便,使用灵活,存储空间利用率高。
缺点:存储密度小(<1),查找和修改需要遍历整个链表。
(2)顺序存储时,相邻数据元素的存放地址也相邻(逻辑与物理统一);要求内存中可用存储单元的地址必须是连续的。
优点:存储密度大(=1),易于查找和修改。
缺点:插入或删除元素时不方便;存储空间利用率低,预先分配内存可能造成存储空间浪费。
2.线性表的单链表储存结构
//线性表的单链表储存结构
typedef struct node
{
Elemtype date;
struct node *next;
} node;
typedef struct node *list;
3.单链表的整表创建 (尾插法)
//单链表的整表创建 (尾插法)
void creatlist(list*L,int a[],int n)
{
list p,r;//r指向链表的尾结点,
int i;
*L=(list)malloc(sizeof(node));//L为线性表
r=*L;//定义r指向尾部的结点
for(i=0;i<n;i++)
{
p=(list)malloc(sizeof(node));//生成新结点
p->date=a[i];
r->next=p;//表尾终端结点的指针指向新节点,就是将将新生成的节点p插入链表尾部
r=p;//r重新指向尾结点
}
r->next=NULL;
}
4.单链表的整表输出
void showlist(list L,int n)
{
list p=L->next;
while(p)
{
printf("%3d",p->date);
p=p->next;
}
printf("\\n");
}
3.单链表元素的获取
int getElem(list L,int i,Elemtype *x)
{
int j=1;//从链表第一个结点开始一一检索
list p;//定义一个头指针
p=L->next;
for(j=1;j<i;j++)
{
p=p->next;
}
if(p==NULL||j>i)//判断指针p和j是否合法 ,若不合法返回0
return 0;
*x=p->date;//将第i个元素的数据赋给*e;
return 1;//获取成功返回1
}
4.单链表的插入
//在原链表第i个元素之前插入数据元素X,L的长度++
//单链表的插入,在原链表第i个元素之前插入数据元素X,L的长度++
int listinsert(list*L,int i,Elemtype x)
{
int j=1;
list p=*L;
list s;//定义一个空结点s;
for(j=1;j<i;j++)
{
p=p->next;
}
if(p==NULL||j>i)//判断指针p和j是否合法 ,若不合法返回0
return 0;
s=(list)malloc(sizeof(node));//生成新节点
s->date=x;
s->next=p->next;//顺序不可改变,若更换就会造成s->next=s;
p->next=s;
return 1;
}
5.//单链表的删除
//单链表的删除
int listdelete(list L,int i,Elemtype*x)
{
int j=1;
list q;
list p=L->next;
for(j=1;j<i;j++)//遍历寻找第i个元素
{
p=p->next;
}
if(p->next==NULL||j>i) //若第i个元素不存在,返回零
return 0;
q=p->next;//借用q删除第i个结点
p->next=q->next;
free(q);//回收删除的结点
return 1;
}
完整代码详解
#include<stdio.h>
#include<stdlib.h>
#include<typeinfo>
typedef int Elemtype;
//线性表的单链表储存结构
typedef struct node
{
Elemtype date;
struct node *next;
} node;
typedef struct node *list;
//单链表的整表创建 (尾插法)
void creatlist(list*L,int a[],int n)
{
list p,r;//r指向链表的尾结点,
int i;
*L=(list)malloc(sizeof(node));//L为线性表
r=*L;//定义r指向尾部的结点
for(i=0;i<n;i++)
{
p=(list)malloc(sizeof(node));//生成新结点
p->date=a[i];
r->next=p;//表尾终端结点的指针指向新节点,就是将将新生成的节点p插入链表尾部
r=p;//r重新指向尾结点
}
r->next=NULL;
}
//单链表的整表输出
void showlist(list L,int n)
{
list p=L->next;
while(p)
{
printf("%3d",p->date);
p=p->next;
}
printf("\\n");
}
//单链表元素的获取
int getElem(list L,int i,Elemtype *x)
{
int j=1;//从链表第一个结点开始一一检索
list p;//定义一个头指针
p=L->next;
for(j=1;j<i;j++)
{
p=p->next;
}
if(p==NULL||j>i)//判断指针p和j是否合法 ,若不合法返回0
return 0;
*x=p->date;//将第i个元素的数据赋给*x;
return 1;//获取成功返回1
}
//单链表的插入,在原链表第i个元素之前插入数据元素X,L的长度++
int listinsert(list*L,int i,Elemtype x)
{
int j=1;
list p=*L;
list s;//定义一个空结点s;
for(j=1;j<i;j++)
{
p=p->next;
}
if(p==NULL||j>i)//判断指针p和j是否合法 ,若不合法返回0
return 0;
s=(list)malloc(sizeof(node));//生成新节点
s->date=x;
s->next=p->next;//顺序不可改变,若更换就会造成s->next=s;
p->next=s;
return 1;
}
//单链表的删除
int listdelete(list L,int i,Elemtype *x)
{
int j=1;
list q;
list p=L->next;
for(j=1;j<i;j++)//遍历寻找第i个元素
{
p=p->next;
}
if(p->next==NULL||j>i) //若第i个元素不存在,返回零
return 0;
q=p->next;//借用q删除第i个结点
p->next=q->next;
free(q);//回收删除的结点
return 1;
}
int main()
{
list L;
int n=5;
printf("请输入链表长度\\n");
scanf("%d",&n);
int x,i;
int a[100];
printf("请输入%d位链表的值\\n",n);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
creatlist(&L,a,n);
printf("请输入你要查询的链表中的第i个值\\n");
scanf("%d",&i);
getElem(L,i,&x);
printf("第%d个值为%d\\n",i,x);
printf("请输入要插入节点的位置z和插入的值x0\\n");
int z,x0;
scanf("%d %d",&z,&x0);
listinsert(&L,z,x0);
printf("此时链表的各元素如下\\n");
showlist( L, n);
printf("请输入要删除的位置o\\n");
int o;
scanf("%d",&o);
listdelete( L,o,&x);
showlist( L, n);
}
运行结果
注:我本人是在vs上编写代码的,上传代码将所有scanf_s改为了scanf;
以便使用其他编译器运行
以上是关于线性表的链式存储结构 ( 链表 )的主要内容,如果未能解决你的问题,请参考以下文章