数据结构与算法(三)——线性表

目录

一、线性表的定义

二、线性表的抽象数据类型

三、线性表的顺序存储结构

1、顺序存储定义

2、顺序存储方式

3、数据长度与线性表长度区别

4、地址计算方法

四、顺序存储结构的插入与删除

1、获取元素

2、插入操作

3、删除操作

4、线性表顺序存储结构的优缺点

五、线性表的链式存储结构

1、线性表的链式存储结构定义

2、头指针和头结点的异同

3、线性表链式存储结构代码描述

六、单链表

1、单链表的遍历

2、单链表的插入

3、单链表的删除

4、单链表的整表创建

5、单链表的整表删除

6、单链表结构与顺序存储结构的优缺点

七、静态链表

八、循环链表

九、双向链表


一、线性表的定义

        线性表:是零个或多个数据元素的有限序列。

        线性表中的元素有且只有一个前驱和后继(其中头元素只有后继没有前驱,尾元素只有前驱没有后继)。当线性表的长度为0时,称为空表。如果a是线性表中的第k个元素,则称k为数据元素a在线性表中的位序。在比较复杂的线性表中,一个数据元素可以由若干个数据项组成(如学生点名册中每一位学生的基本信息)。

二、线性表的抽象数据类型

ADT 线性表(List)

Data

    线性表的数据对象集合为{a1,a2,......,an},每个元素的类型为DataType。其中,除第一个元素a1外,每
一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个后继元素。数据元素之间
的关系是一对一的关系。

Operation

    InitList(*L):    初始化操作,建立一个空的线性表L
    ListEmpty(L):    若线性表为空,返回true,否则返回false
    ClearList(*L):   将线性表清空
    GetElem(L,i,*e): 将线性表L中第i个位置元素返回给e
    LocateElem(L,e): 在线性表L中查找与给定值e相等的元素,如果查找成功,则返回该元素在表中序号;否
则返回0表示失败
    ListInsert(*L,i,e): 在线性表L中的第i个位置插入新元素e
    ListDelete(*L,i,*e): 删除线性表L中第i个位置元素,并用e返回其值
    ListLength(L):    返回线性表L的元素个数
    
endADT

三、线性表的顺序存储结构

1、顺序存储定义

        线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。

2、顺序存储方式

        简单来说,就是在内存空间中找一块地儿,通过占位的形式,把一定的内存空间给占了,然后把相同数据类型的数据元素依次存放在这块空地中。C语言中可以用一维数组来实现顺序存储结构,即把第一个元素放到数组下标为0的位置,后面的元素依次存放。

        描述线性表的存储结构需要三个属性:

        ① 存储空间的起始位置;

        ② 线性表的最大容量;

        ③ 线性表的当前长度。

        下面是代码示例:

//线性表的顺序存储结构
#define MAXSIZE 20 //存储空间初始容量分配
typedef int ElemType; //存储元素类型ElemType根据实际情况而定,这里假设为int
typedef struct{
	ElemType data[MAXSIZE]; //定义数组存储数据元素个数最大为MAXSIZE
	int length; //线性表的当前长度
}SqList;

3、数据长度与线性表长度区别

        数组的长度是存放线性表的存储空间的长度,存储分配后这个量一般是不变的。

        线性表的长度是线性表中数据元素的个数,随着线性表插入和删除操作的进行这个量是动态变化的。

4、地址计算方法

        C语言中的数组是从0开始第一个下标的,于是线性表的第i个元素是要存储在数组下标为i-1的位置。用数组存储顺序表意味着要分配固定长度的数组空间,由于线性表中可以进行插入和删除操作,因此分配的数组空间要大于或等于当前线性表的长度。

        假设一个数据元素占用c个存储单元,那么线性表中第i+1个数据元素的存储位置和第i个数据元素的存储位置计算公式如下:

fun(Ai+1) = fun(Ai) + c

四、顺序存储结构的插入与删除

1、获取元素

//用e返回L中第i个数据元素的值
#define OK 1
#define ERROR 0
#define TURE 1
#define FALSE 0
typedef int Status; //函数结果状态码,如OK等
Status GetElem(SqList L, int i, ElemType *e){
	if(L.length == 0 || i<1 || i>L.length){
		return ERROR;
	}
	*e = L.data[i - 1];
	return OK;
}

2、插入操作

插入算法的思路:

① 如果插入位置不合理,抛出异常;

② 如果线性表长度大于等于数组长度,则抛出异常或动态增加容量;

③ 从最后一个位置开始向前遍历到第i个位置,分别将它们都向后移动一个位置;

④ 表长加1。

实现代码如下:

//在线性表L中的第i个位置插入新元素e
Status ListInert(SqList *L, int i, ElemType e){
	if(L->length == MAXSIZE){//线性表已经满了
		return ERROR;
	}
	if(i < 1 || i > L->length+1){//i不在数组的范围之内
		return ERROR;
	}

	if(i <= L->length){//如果插入的数据不是表尾,则需要将插入位置后的元素向后移动一位
		for(int t = L->length-1;t >= i - 1; t--){
			L->data[t+1] = L->data[t];
		}
	}
	L->data[i-1] = e;
	L->length++;
	return OK;
}

3、删除操作

删除算法的思路:<

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值