数据结构——线性表

 📕参考:王道+代码随想录+acwing


逻辑结构——线性表

1.线性表的定义(逻辑结构)

要点:

  • 相同数据类型
  • 有限
  • 序列

几个概念: 

  • a_i是线性表中的“第i个”元素线性表中的位序
  • a_1是表头元素;a_n是表尾元素。
  • 除第一个元素外,每个元素有且仅有一个直接前驱;除最后一个元素外,每个元素有且仅有一个直接后继
  • ⭐注意:位序从1开始,数组下标从0开始

物理结构——顺序表

顺序表,按数组理解即可。 

2.顺序表 (物理结构)

顺序表:用顺序存储的方式实现线性表。

逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。

 


物理结构——链表 

什么是链表?

链表是一种通过指针串联在一起的线性结构。

每一个节点由两部分组成,一个是数据域 data ,一个是指针域 next(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。

 

3.单链表(物理结构)

单链表:每个结点除了存放数据元素外,还要存储指向下一个节点的指针。

单链表中的指针域只能指向节点的下一个节点。

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+6;
int head,e[N],ne[N],idx;
//初始化
void initial(){
	head=-1,idx=1;
} 
//头插法
void head_insert(int x){
	e[idx]=x;
	ne[idx]=head;
	head=idx;
	idx++;
} 

//在第k个插入的数后插入一个数
void insert(int k,int x){
	//插入的是第k+1个数,下标是k
	 e[idx]=x;
	 ne[idx]=ne[k];
	 ne[k]=idx;
	 idx++;
} 
//删除第k个插入的数后面的数
void move(int k){
	//k=0时, 
	if(k==0)
		head=ne[head];
	else
		ne[k]=ne[ne[k]];
} 
int main(){
	int m;
	cin>>m;
	//初始化
	memset(ne,-1,sizeof ne); 
	initial();
	//cout<<ne[1]<<ne[10];
	while(m--){
		char a;
		cin>>a;
		if(a=='H'){
			int x;
			cin>>x;
			head_insert(x);
		}
		else if(a=='I'){
			int k,x;
			cin>>k>>x;
			insert(k,x);
		}
		else{
			//a==D
			int k;
			cin>>k;
			move(k);
		}
	}
	//cout<<ne[15];
	//输出
	for(int i=head;i!=-1;i=ne[i])
	{
		cout<<e[i]<<" ";
	} 
	return 0;
}

4.双链表(物理结构)

双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。

双链表既可以向前查询也可以向后查询。

 5.循环单链表(物理结构)

单链表:表尾结点的next指针指向NULL

循环单链表:表尾结点的next指针指向头结点

由于循环单链表的表尾结点的next指针指向头结点,所以对于循环单链表来说,从一个结点出发可以找到其它任何一个结点。但是对于单链表来说,从一个结点出发只能找到后续的各个结点,没有办法找到它的前面的结点。

单链表:从一个结点出发,只能找到后续的各个结点

循环单链表:从一个结点出发,可以找到其它任何一个结点

 6.循环双链表(物理结构)

双链表:表头结点的prior指向NULL,表尾结点的next指向NULL

循环双链表:表头结点的prior指向表尾结点,表尾结点的next指向头结点

7.静态链表(物理结构)

学习静态链表之前,我们需要先学一下链表在内存中的存储方式。

链表通过指针域的指针链接在内存中各个节点。

链表中的节点在散乱地分布在内存中的某地址上,分配机制取决于操作系统的内存管理。

如图所示:

 这个链表起始节点为2, 终止节点为7, 各个节点分布在内存的不同地址空间上,通过指针串联在一起。

静态链表呢,就是分配一整片连续的内存空间,各个结点集中安置。

如图所示:

每个数据元素 4B,每个游标4B(每个结点共 8B)

设起始地址为 addr ,则e1 的存放地址为 addr + 8*2

用代码定义一个静态链表如图所示。

 理解:

静态链表:用数组的方式实现的链表

优点:增、删 操作不需要大量移动元素 
缺点:不能随机存取,只能从头结点开始依次往后查找;容量固定不可变

适用场景:①不支持指针的低级语言;②数据元素数量固定不变的场景(如操作系统的文件分配表FAT) 


高频考点:

顺序表和链表的对比

 顺序表和链表的逻辑结构都是线性结构,都属于线性表。

但是两者的存储结构不同,顺序表采用顺序存储,链表采用链式存储。

顺序表采用顺序存储,这样支持随机存取(也就是支持按位查找,时间复杂度为O(1)),存储密度较高。但是顺序存储需要预分配大片连续空间。若分配空间过大,浪费内存资源;若分配空间过小,之后不方便扩展容量。而且顺序存储插入或删除元素时需要将后续元素都移动,这样时间复杂度较大为O(n),时间开销主要来自移动元素。综上所述,顺序表适合表长可预估,查询(搜索)操作比较多,插入删除操作比较少的情况。

链表采用链式存储,链式存储不需要分配连续空间,它是离散的存储的,且改变容量很方便,但是不可随机存取,存储密度低。链表插入/删除元素只需要修改指针即可,时间复杂度为O(n),时间开销主要来自查找目标元素。链表不支持随机存取,所以按位查找时需要从头找到尾。时间复杂度为O(n)。综上所述,链表适用于表长难以预估,插入删除操作比较多,查找操作比较少的情况。

 详细内容:

  • 顺序表v.s.链表

    • 逻辑结构

      • 都属于线性表,都是线性结构

      • 子主题 2

    • 物理结构/存储结构

      • 顺序表(顺序存储)

        • 优点:支持随机存取、存储密度高

        • 缺点:大片连续空间分配不方便,改变容量不方便

      • 链表(链式存储)

        • 优点:离散的小空间分配方便,改变容量方便

        • 缺点:不可随机存取,存储密度低

    • 数据的运算/基本操作

      • 创建链表

        • 顺序表

          • 需要预分配大片连续空间

          • 若分配空间过小,则之后不 方便拓展容量

          • 若分配空间 过大,则浪费内存资源

          • 分配方式

            • 静态分配

              • 静态数组:容量不可改变

            • 动态分配

              • 动态数组(malloc、free),容量可以改变,但需要移动大量元素,时间代价高

        • 链表

          • 只需分配一个头结点(也可 以不要头结点,只声明一个 头指针),之后方便拓展

      • 删除链表

        • 顺序表

          • 静态分配:静态数组

            • 系统自动回收空间

          • 动态分配:动态数组

            • 需要手动free

            • malloc和free必须成对出现

        • 链表

          • 依次删除各个结点(free)

      • 增加/删除元素

        • 顺序表

          • 插入/删除元素要将后续 元素都后移/前移

          • 时间复杂度 O(n),时间开 销主要来自移动元素

        • 链表

          • 插入/删除元素只需 修改指针即可

          • 时间复杂度 O(n),时间开 销主要来自查找目标元素

      • 查找元素

        • 顺序表

          • 按位查找:O(1)

          • 按值查找:O(n) 若表内元素有序,可在 O(log2n) 时间内找到

        • 链表

          • 按位查找:O(n)

          • 按值查找:O(n)

    • 使用场景

      • 顺序表

        • 表长可预估、查询(搜索)操作较多

      • 链表

        • 表长难以预估、经常要增加/删除元素

  • 29
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三三木木七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值