22 线性表的链式表示与实现

链式存储结构:用一组物理位置任意的存储单元来存放线性表的数据元素。

这组存储单元既可以是连续的,也可以是不连续的,甚至是零散分布内存中的任意位置。

链表中的元素的逻辑次序与物理次序不一定相同

例子:

线性表(赵,钱,孙,李,周,吴,郑,王)

顺序表:存储地址依次增加

链表:存储地址不规律,存储每一个元素时,也要存储下一个元素的存储地址。没有下一个元素,既为NULL。

结点=数据域+指针域(链指针)数据元素的存储映像。

数据域:存储元素数字数据

指针域:存储直接后继结点的存储位置

链表:n个结点由指针链组成一个链表

它是线性表的链式存储映像,称为线性表的链式存储结构。


单链表,双链表,循环链表

1.结点只有一个指针域的链表,称为单链表或者线性链表。

2.结点有两个指针域的链表,称为双链表。

3.首尾相接的链表称为循环链表


头节点,头指针,首元结点:

头指针:是指向链表中第一个结点的指针。

首元结点:是指链表中存储第一个数据元素a1的结点。

头结点:是在链表的首元结点之前附设的一个结点。

(1):不带头结点:第一个数直接指向a1

(2):带头结点:第一个数指向一个地址,任何下一个才是a1。

如何表示空表;

1.无头结点时,头指针为空时表示空表

2.有头结点时,当头结点的指针域为空时表示空表。

讨论2:在链表中设置头结点有什么好处?

1.便于首元结点的处理

首元结点的地址保存在头结点的指针域中,所以在链表的第一个位置上的操作和其它位置一致,无需进行特殊处理。

2.便于空表和非空表的统一处理

无论链表是否为空,头指针都是指向头结点的非空指针,因此空表和非空表的处理也就统一了。

讨论3:头结点的数据域内装的是什么?

头结点的数据域可以为空,也可以存放线性表长度等附加信息,但此结点不能计入链表长度值。

链式(链式存储结构)的特点:

(1).结点在存储器中的位置是任意的,既逻辑上相邻的数据元素在物理上不一定相邻。

(2).访问时只能通过头指针进入链表,并通过每个结点域依次向后顺序扫描其余结点,所以寻找第一个结点和最后一个结点所花费的时间不等。

顺序存取法:每个结点域依次向后顺序扫描其余结点。

顺序表-->随机抽取          链表---->顺序存取


带头结点的单链表

空表:带头结点。

单链表是由表头决定的,因此单链表可以用头指针的名字来命名,若头指针名是L,则把链表称为表L。

单链表的存储结构:

数据域 data 指针域next

typedef struct Lnode{//声明结点的类型和指向结点的指针类型

ElemType data;//结点的数据域

struct Lnode *next;//结点的指针域

}Lnode,*LinkList;//LinkList为指向结构体Lnode的指针类型。

定义链表:LinkList L;

定义结点指针p :LNode *p;<==>LinkList p;

例子:存储学生的学号,姓名,成绩的单链表结点类型定义:

typedef Struct student{

char num[8];//数据域

char name[8];//数据域

int score;//数据域

struct student *next;//指针域

}Lnode,*LinkList;

LinkList L;.


单链表的基本操作的实现

带头结点单链表的初始化:既构造一个空表。

算法步骤:

1.生成新结点作头结点,用头指针L指向头结点。

2.将头结点的指针域置空。

Status InitList_L(LinkList &L){

L=new LNode;

L->next=NULL;

return OK;
}

判断链表是否为空

算法思路:判断头结点指针域是否为空

int ListEmpty(LinkList L){
if(L->next)return 0;//非空
else return 1;
}


单链表的销毁:链表销毁后不存在

算法思路:从头开始,依次释放所有结点

Status DestroyList_L(LinkList &L)//销毁单链表L
{
Lnode *p;
while(L){
p=L;
L=L->next;
delete p;(new)//free(p)malloc().
}
return OK;
}

清空单链表:链表仍然存在,但是无元素,成为空链表,头指针和头结点依然存在。

算法思路:依次释放所有的结点,并将头结点指针域设置为空。

status ClearList(ListList &L)
{
Lnode *p,*q;
p=L->next;
while(p){
q=p->next;
delete p;
p=q;
}
L->next=NULL;
return OK;
}

求链表的表长

算法思路:从首元结点开始,依次计数所有的结点

int ListLength_L(LinkList L){
LinkList p;//Lnode *p;
p=L->next;//P指向第一个结点
i=0;
while(p){
i++;
p=p->next;
}
return i;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值