数据结构——3.线性表、顺序表

数据结构

3.线性表、顺序表

线性表是逻辑结构,顺序表链表是存储结构

3.1 线性表的概念

线性结构的特点:

  • 存在唯一一个被称为“第一个”的数据元素;
  • 存在唯一一个被称为“最后一个”的数据元素;
  • 除“第一个”元素无前驱外,集合中的每个元素均有且只有一个“直接”前驱;除“最后一个”元素无后继外,集合中每个数据元素均有且只有一个“直接”后继。

1.线性表(Linear_List):是具有相同数据类型的n(n≥0)个数据元素的有限序列,通常记为:
( a 0 , a 1 , … , a i − 1 , a i , a i + 1 , … , a n − 1 ) (a_0,a_1,…,a_{i-1},a_i,a_{i+1},…,a_{n-1}) (a0a1ai1aiai+1an1)
2.前驱、后继、表长、空表、首结点、尾结点
3.位序: a i ( 0 ≤ i ≤ n − 1 ) a_i(0\leq i \leq n-1) ai(0in1)是线性表中的元素,则称i为数据元素 a i a_i ai在线性表中的位序(位置)。

线性表存储分类:【顺序表】、【链表】
1、顺序表(用一维数组实现定长的线性存储结构)
按索引值从小到大存放在一片相邻的连续区域
紧凑结构,存储密度为1

在这里插入图片描述

2、链表(用指针实现变长的线性存储结构)

单链表

在这里插入图片描述

双链表

在这里插入图片描述

循环链表

在这里插入图片描述

顺序表需要一块连续的存储空间,可以用一个数组实现。保存一个动态数组,需要三个变量:
data:指向线性表元素类型的指针,
curLength:数组中当前存储的元素个数(表长),
maxSize:数组规模(容量)。
在这里插入图片描述

初始化顺序表
maxSize=initSize;//参数
data=new elemType[maxSize];//元素类型
curLength=0;//当前表的长度

3.2 顺序表

1.遍历
if(curLength==0) cout<<"empty"<<endl;
else
{
	cout<<"output elements:\n";
	for(int i=0;i < curlength;i++)//依次访问元素			cout<<data[i]<<" ";
	cout<<endl;
}
时间复杂度为0(n),空间复杂度0(1)
2.查找

算法思想:遍历线性表,将线性表中每一个元素依次与value进行比较。若value==data[i](0<=i<curLength)则查找成功,返回data[i]的位序i,否则查找失败返回-1

for(int i=0;i< curlength;i++)
	if(value==data[i]) return i;
return -1;
//查找失败返回-1

时间复杂度为0(n),空间复杂度0(1)
3.插入

要求:位置0-n都是合法的,因为元素紧密排列;否则不合法,插入了就不再是顺序表了

设线性表 L = ( a 0 , a 1 , … , a i − 1 , a i , a i + 1 , … , a n − 1 ) L=(a_0,a_1,…,a_{i-1},a_i,a_{i+1},…,a_{n-1}) L=(a0a1ai1aiai+1an1)
线性表的插入是指在位序为i的位置上插入一个值为value的新元素,使L变为:
( a 0 , a 1 , … , a i − 1 , v a l u e , a i , a i + 1 , … , a n − 1 ) (a_0,a_1,…,a_{i-1},value,a_i,a_{i+1},…,a_{n-1}) (a0a1ai1valueaiai+1an1)

if(i<0 || i>curlength) throw outOfRange();//报错或抛出异常
//合法的插入位置为[0..curLength]

if(curLength==maxSize) resize();//表满,则报错或扩大表

for(int j=curLength;j>i;j--)//[curlength-1..i]范围的元素后移一步
	data[j]=data[j-1];

data[i]=value;//将value置入位序为i的位置
++curLength;//表的突际长度增1

时间复杂度为0(n),空间复杂度0(1)

插入运算平均移动数据元素的次数(期望值)为n/2

4.删除

要求:①不能为空表;②删除位置要合法[0,n-1]

设线性表 L = ( a 0 , a 1 , … , a i − 1 , a i , a i + 1 , … , a n − 1 ) L=(a_0,a_1,…,a_{i-1},a_i,a_{i+1},…,a_{n-1}) L=(a0a1ai1aiai+1an1)
线性表的删除运算是指将表中位序为的元素从线性表中去掉,L变为:
L = ( a 0 , a 1 , … , a i − 1 , a i + 1 , … , a n − 1 ) L=(a_0,a_1,…,a_{i-1},a_{i+1},…,a_{n-1}) L=(a0a1ai1ai+1an1)

if(i<0 || i> curlength-1)
throw outOfRange();//抛出异常
//合法的删除位置为[0..curLength-1]

for(int j=i;j < curlength-1;j++)
	data[j]=data[j+1];  //[i+1..curlength-1]范围的元素前移一步

--curLength;/表的实际长度减1

时间复杂度为0(n),空间复杂度0(1)

删除运算平均移动数据元素的次数(期望值)为(n-1)/2

5.逆置

线性表 L = ( a 0 , a 1 , … , a i − 1 , a i , a i + 1 , … , a n − 1 ) L=(a_0,a_1,…,a_{i-1},a_i,a_{i+1},…,a_{n-1}) L=(a0a1ai1aiai+1an1)

线性表的逆置是指调整线性表中元素的顺序,使L变为: ( a n − 1 , a n − 2 , … , a 1 , a 0 ) (a_{n-1},a_{n-2},…,a_1,a_0) an1an2a1a0
可用两两交换元素的方法求解,即 a 0 a_0 a0 a n − 1 a_{n-1} an1 a 1 a_1 a1 a n − 2 a_{n-2} an2,共进行[n/2]次(向下取整,例如9个元素,除以2后取4)交换。

elemType tmp;
for(int i=0;i<curlength/2;i++){//控制交换的次数
	tmp=data[i];
	data[i]=data[curLength-i-1];
	data[curLength-i-1]=tmp;
}

时间复杂度为O(n),空间复杂度O(1)
顺序表的特点

(1)顺序表需要预先分配存储空间,很难恰当预留空间
(2)逻辑次序和物理次序的一致性,能够按序号(下标)直接存取元素,具有随机存取的优点
(3)顺序表在插入删除时需要移动大量的数据,因此其插入和删除效率低
(4)难于改变顺序表的大小,需要重新创建一个新的顺序表,把原表里的数据复制到新表,然后释放原表空间。
(5)顺序表比较适合静态的、经常做定位访问的线性表

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值