线性表的链式存储
2016-04-10 15:36
369 查看
1.链式存储定义:为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息。
2.链式存储逻辑结构:
n个节点链接成一个链式线性表的结构叫做链表,当每个节点只包含一个指针域是叫做单链表。
3.链表的基本概念:
表头结点:链表中的第一个结点
,包含指向第一个数据元素的指针以及链表自身的一些信息。
数据结点:链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息。
尾结点:链表中最后一个数据结点,其后继。
在C语言中可以用结构体来定义链表中的指针域.
链表中的表头节点也可以用结构体来实现
4.获取第POS个元素的算法操作:
1.判断线性表是否合法
2.判断位置是否合法
3.由表头开始通过next指针移动POS之后,当前元素的next指针即指向要获取的元素。
5.插入元素到pos的算法操作:(在新的链表形成之前,旧的链表不能断裂)
1.判断线性表是否合法
2.判断位置是否合法
3.有表头开始通过next指针移动pos次之后,当前元素的next指针即指向要插入的位置
4.将新元素插入
5.线性表的长度加1
6.删除第POS个元素的算法操作:
1.判断线性表是否合法
2.判断插入位置是否合法
3.获取第POS个元素
4.将第POS个元素删除
5.线性表长度减1
[/code]
可以复用的链表实例
.h文件
.c文件
main.c
线性表的链式存储结构的优缺点:
优点:
1.无需一次性定制链表的长度
2.插入或者删除元素操作时无需移动数据元素
缺点:
1.数据元素必须保后继元素的位置信息
2.获取指定数据的元素时需要顺序的访问该元素之前的元素
2.链式存储逻辑结构:
n个节点链接成一个链式线性表的结构叫做链表,当每个节点只包含一个指针域是叫做单链表。
3.链表的基本概念:
表头结点:链表中的第一个结点
,包含指向第一个数据元素的指针以及链表自身的一些信息。
数据结点:链表中代表数据元素的结点,包含指向下一个数据元素的指针和数据元素的信息。
尾结点:链表中最后一个数据结点,其后继。
在C语言中可以用结构体来定义链表中的指针域.
链表中的表头节点也可以用结构体来实现
typedefstruct_tag_Link_listNode_Link_list_node
struct_tag_Link_listNode_
{
Link_list_node*next;
};
结点指针域定义
typedefstruct_tag_Linklist
{
Link_list_nodehearder;
intlength;
}TlinkList;
头结点定义
structValue
{
_Link_list_nodeheader;
intv;
}
数据元素定义实例
4.获取第POS个元素的算法操作:
1.判断线性表是否合法
2.判断位置是否合法
3.由表头开始通过next指针移动POS之后,当前元素的next指针即指向要获取的元素。
LinkListNode*current=(LinkListNode*)list;
for(inti=0;i<pos;i++)
{
current=current->next;
}
ret=*current->next;
5.插入元素到pos的算法操作:(在新的链表形成之前,旧的链表不能断裂)
1.判断线性表是否合法
2.判断位置是否合法
3.有表头开始通过next指针移动pos次之后,当前元素的next指针即指向要插入的位置
4.将新元素插入
5.线性表的长度加1
LinkListNode*current=(LinkListNode*)list
for(inti=0;(i<pos)&&(current<-next!=NULL);i++)
{
current=current->next;
}
node->next=current->next;
corrent->next=node;
sList++;
6.删除第POS个元素的算法操作:
1.判断线性表是否合法
2.判断插入位置是否合法
3.获取第POS个元素
4.将第POS个元素删除
5.线性表长度减1
TLinkList*sList=(TLinkList*)list;
LinklistNode*ret=NUll;
inti=0;
if((sList!=NULL)&&(0<pos)&&(pos<sList->length))
{
LinklistNode*current=(LinkListNode*)list;//current指向表头
for(inti=0;i<pos;i++)
{
current=current->next;
}
ret=current->next;
current->next=ret->next;
Slist->length--;
}
[/code]
可以复用的链表实例
.h文件
#ifndef_LINKLIST_H_
#define_LINKLIST_H_
typedefvoidLinkList;//为了实现数据的封装,void*作为右值赋值给其他指针是,需要进程强制类型转换
typedefstruct_tag_LinkListNodeLinkListNode;
/*包含指针域的结构体*/
struct_tag_LinkListNode
{
LinkListNode*next;//指针域
};
LinkList*LinkList_Creat();
voidLinkList_Destory(LinkList*list);
voidLinkList_Clear(LinkList*list);
intLinkList_Capacity(LinkList*List);
intLinkList_Insert(LinkList*list,LinkListNode*node,intpos);
LinkListNode*LinkList_Delete(LinkList*list,intpos);
LinkListNode*LinkList_Get(LinkList*list,intpos);
intSeqList_Length(LinkList*list);
#endif
.c文件
#include<stdio.h>
#include<malloc.h>
#include"Linklist.h"
/*单链表的头结点*/
typedefstruct_tag_LinkList
{
LinkListNodeheader;//指向下一个数据元素的指针
intlength;//指示整个链表的长度
}TLinkList;
LinkList*LinkList_Creat()//O(1)
{
TLinkList*ret=(TLinkList*)malloc(sizeof(TLinkList));//申请一个表头结点
if(ret!=NULL)
{
ret->length=0;
ret->header.next=NULL;
}
returnret;
}
/*销毁已经创建的单链表,即释放申请的内存*/
voidLinkList_Destory(LinkList*list)
{
free(list);
}
/*清空链表,即将list的长度变为0*/
voidLinkList_Clear(LinkList*list)
{
TLinkList*slist=(LinkList*)list;//为了使用头结点里的信息进行强制类型转换
//void*作为右值赋值给其他指针是,需要进程强制类型转换
if(slist!=NULL)
{
slist->length=0;
slist->header.next=NULL;
}
}
/*得到单链表的长度*///o)
intSeqList_Length(LinkList*list)
{
intret=-1;
TLinkList*slist=(TLinkList*)list;
if(slist!=NULL)
{
ret=slist->length;
}
returnret;
}
/*向链表中插入一个元素*/
intLinkList_Insert(LinkList*list,LinkListNode*node,intpos)
{
TLinkList*slist=(TLinkList*)list;
inti=0;
intret=1;
ret=(slist!=NULL)&&(pos>=0)&&(node!=NULL);
if(ret)
{
LinkListNode*current=(LinkListNode*)slist;//定义一个current指针使其指向头结点
for(i=0;(i<pos)&&(current->next!=NULL);i++)
{
current=current->next;
}
current->next=node->next;
current->next=node;
slist->length++;
}
returnret;
}
/*从链表中得到一个元素*/
LinkListNode*LinkList_Get(LinkList*list,intpos)
{
TLinkList*slist=(TLinkList*)list;
LinkListNode*ret=NULL;
inti=0;
if((pos>=0)&&(slist!=NULL)&&(pos<=slist->length))
{
LinkListNode*current=(LinkListNode*)list;
for(i=0;i<pos;i++)
{
current=current->next;
}
ret=current->next;
}
returnret;
}
/*删除链表中的一个元素*/
LinkListNode*LinkList_Delete(LinkList*list,intpos)
{
TLinkList*slist=(TLinkList*)list;
LinkListNode*ret=NULL;
inti=0;
if((pos>=0)&&(slist!=NULL)&&(pos<=slist->length))
{
LinkListNode*current=(LinkListNode*)slist;
for(i=0;i<pos;i++)
{
current=current->next;
}
ret=current->next;
current->next=ret->next;
slist->length--;
}
returnret;
}
main.c
#include<stdio.h>
#include"Linklist.h"
structValue
{
LinkListNodeheader;
intv;
};
intmain()
{
LinkList*list=LinkList_Creat();
inti=0;
structValuev1;
structValuev2;
structValuev3;
structValuev4;
structValuev5;
v1.v=1;
v2.v=2;
v3.v=3;
v4.v=4;
v5.v=5;
LinkList_Insert(list,(LinkListNode*)&v1,SeqList_Length(list));
LinkList_Insert(list,(LinkListNode*)&v2,SeqList_Length(list));
LinkList_Insert(list,(LinkListNode*)&v3,SeqList_Length(list));
LinkList_Insert(list,(LinkListNode*)&v4,SeqList_Length(list));
LinkList_Insert(list,(LinkListNode*)&v5,SeqList_Length(list));
for(i=0;i<SeqList_Length(list);i++)
{
structValue*pv=(structValue*)LinkList_Get(list,i);
printf("%d\n",pv->v);
}
printf("listlengthis%d\n",SeqList_Length(list));
while(SeqList_Length(list)>0)
{
structValue*pv=(structValue*)LinkList_Delete(list,SeqList_Length(list)-1);
printf("%d\n",pv->v);
}
printf("listlengthis%d\n",SeqList_Length(list));
LinkList_Destory(list);
return0;
}
线性表的链式存储结构的优缺点:
优点:
1.无需一次性定制链表的长度
2.插入或者删除元素操作时无需移动数据元素
缺点:
1.数据元素必须保后继元素的位置信息
2.获取指定数据的元素时需要顺序的访问该元素之前的元素
相关文章推荐
- spring自带的定时器@Scheduled
- opencv HOG中detectMultiScale()参数含义
- 29.获取文件缓存大小
- 英语单词最全的前后缀讲解
- Axure RP的基础使用
- Xamarin.Forms Hello word
- win2008 server ping不同
- 查询服务器基本硬件配置信息
- 线性链表的顺序存储结构
- C++第三次实验.3
- nginx配置文件nginx.conf解读
- 项目实战:iOS极光推送集成(30分钟搞定)
- 开门见喜第一篇
- Android学习(二)--第二个项目遇到的问题
- 随笔知识2
- 20145307陈俊达第六周JAVA学习总结
- 九度 1011
- Web前端前沿技术专业术语解读
- 远程线程注入
- 小技巧当从后台传入数据时不要传null最好是个空对象入json中