您的位置:首页 > 其它

线性表的链式存储

2016-04-10 15:36 369 查看
1.链式存储定义:为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息。



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.获取指定数据的元素时需要顺序的访问该元素之前的元素
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: