文章目录
- 一、一般线性表存储
- 1.1、线性表顺序存储
- 1.2、线性表的链式存储
- 1.2.1、 单链表
- 1、单链表的存储
- 2、单链表的基本操作的实现
- 1.2.2、双向链表
- 二、栈的存储结构
- 2.1 顺序栈
- 2.1.1、顺序栈的操作
- 1、 初始化空栈
- 2、插入
- 3、删除操作pop
- 4、获取栈顶元素
- 2.2 链栈
- 三、队列的存储
- 3.1 链队列:队列的链式表示
- 3.1.1 基本操作的算法描述
- 3.2 顺序队列
- 四、二叉树的存储结构
- 4.1 顺序存储二叉树(数组表示)
目标:
- 掌握典型的数据结构
- 掌握软件开发中存储对象的定义方法
- 掌握数据结构与算法基础应用
- 掌握业务逻辑的算法设计与选择方法
一、一般线性表存储
物理结构,又称存储结构。数据的存储结构是逻辑结构在计算机存储器中的实现。数据元素在计算机中主要有两种不同的存储方法:顺序存储结构和链式存储结构。
- 顺序存储结构: 借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系(公式化描述)
- 链式存储结构: 借助指示元素存储地址的指针表示数据元素之间的逻辑关系(链式描述)
- 不同的数据结构可以选择不同的物理结构存储
1、顺序存储
特点:内存地址连续,支持随机存取,适用于频繁查询;节约空间
2、链式存储
特点:线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素。
1.1、线性表顺序存储
线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素。
特点:是一种随机存取的存储结构只要确定了起始位置,就可以访问表中的任何一个元素
线性表顺序存储结构体定义:(一般用数组去描述)
#define LIST_INIT SIZE 100
#define LISTINCREAMENT 10
typedef struct {
ElemType *elem; /*指向线性表占用的数组空间。*/
int length; /* 线性表的长度*/
int listsize; /*当前分配的存储容量(以sizeof(ElemType)为单位*/
}SqList;
顺序线性表的操作
顺序表容易实现访问操作,可随机存取元素。但插入和删除操作主要是移动元素。
(1) 初始化操作:算法思想,构造一个空表。设置表的起始位置、表长及可用空间
Status InitList_Sq(SqList &L) {
// 构造一个空的线性表
L.elem = (ElemType *)malloc(LIST_INIT_SIZE*size of (ElemType));
if(! L.elem) exit(OVERFLOW) // 存储分配失败
L.lenght = 0; // 空表长度0
L.listsize = LIST_INIT_SIZE; // 初始存储容量
return OK;
} // InitList_Sq
(2)线性表的顺序表插入操作 ListInsert(&L,i,e)
- 分析:分析:“插入元素”使线性表的逻辑结构发生什么变化?假设在线性表的第i个元素之前插入一个元素e。
- 插入元素时,线性表的逻辑结构
- 基本思想:1、检查i值是否超出所允许的范围1<i<n+1,若超出,则进行“超出范围”错误处理。2、存储空间是否已满,如满需要增加空间;3、将线性表的第i个元素和它后面的所有元素均向后移动一个位置;4、将新元素写入到空出的第i个元素位置上。5、使线性表的升序增1
(3)线性表的顺序表删除操作ListDelete(&La,i,&e) - 分析:“删除元素” 线性表的逻辑结构发生什么变化?假设删除线性表的第i个元素保存在变量e中。
- 删除元素时,线性表的逻辑结构由
- 基本思想:1、检查i值是否超出所允许的范围 (lsisn),若超出,则进行“超出范围”错误处理。2、将线性表的第i个元素给e; 3、将线性表的第i个元素后面的所有元素均向前移动一个位置。4、使线性表的长度减1。
(4) 线性表的顺序表查找操作(时间复杂度:O(ListLength(L))
顺序存储结构的优缺点:
优点:
逻辑相邻,物理相邻
可随机存取任一元素
存储空间使用紧凑
缺点:
插入、删除操作需要移动大量的元素
预先分配空间需按最大空间分配,利用不充分
表容量难以扩充
1.2、线性表的链式存储
线性表的链式表示与实现有3种形式:单链表、循环链表、双向链表
1.2.1、 单链表
(1)特点:
用一组任意的存储单元存储线性表的数据元素。利用指针实现了用不相邻的存储单元存放逻辑上相邻的元素。每个数据元素a;,除存储本身信息外,还需存储其直接后继的信息。结点:数据元素a;的存储映像。
数据域:元素本身信息
指针域: 指示直接后继的存储位置
1、单链表的存储
(3)单链表的实现
2、单链表的基本操作的实现
(1)、查找操作
算法基本思想:
- 令p为指针变量,首先指向第一个结点,变量j为计数器;
- 依次向后查找,循环结束的条件,p为空或者j=i。
- 如果p为空并且j>i,出错
- 否则找到了,用e返回第i个元素
算法实现
(2) 插入操作
(3)删除操作——ListDelete(&L,i,&e)
(4) 创建单链表(头插法)
(5)创建单链表(尾插入法)
1.2.2、双向链表
定义:
二、栈的存储结构
2.1 顺序栈
用顺序存储结构表示的栈。顺序栈用一组连续的存储单元存放自栈底到栈顶的数据元素,一般用一维数组表示,设置一个简单变量top指示栈顶位置,称为栈顶指针,它始终指向待插入元素的位置。
理解栈的运算特点:后进先出 或 先进后出
栈的顺序存储结构是用一组连续的存储单元依次存放栈中的每个数据元素,并用起始端作为栈底
2.1.1、顺序栈的操作
1、 初始化空栈
构建空栈,分配空间
2、插入
操作示意图:
代码实现(C):
3、删除操作pop
4、获取栈顶元素
2.2 链栈
链栈的示意图:
三、队列的存储
队列逻辑结构:队列是插入在一端进行而删除在其另一端进行的线 性表。并按**先进先出(FIFO)**的原则进行操作。
- 能进行删除的一端称为队头(front)
- 能进行插入操作的一端称为队尾(rear)
3.1 链队列:队列的链式表示
- 链队列中,有两个分别指示队头和队尾的指针
- 链式队列在进队时无队满问题,但有队空问题
结构体定义:
3.1.1 基本操作的算法描述
1、初始化
2、销毁队列
free函数:释放
3、入队
4、出队
3.2 顺序队列
顺序队列操作时指针的变化情况:
如何解决(d)中的队列“假满”状态? 将顺序队列改造为循环队列
四、二叉树的存储结构
4.1 顺序存储二叉树(数组表示)
顺序存储二叉树的具体方法是:在一棵具有n个结点的完全二叉树中,从根结点开始编号为1,自上到下,每层自左至右地给所有结点编号,这样可以得到一个反映整个二叉树结构的线性序列;然后将完全二叉树上编号为i的结点依次存储在一维数组中下标为i-1的元素中。
实现:按满二叉树中结点的编号,依次存放二叉树中的数据元素。
特点:结点间关系蕴含在其存储位置中
1、顺序存储结构
2、链式存储结构
链式存储是使用链表来存储二叉树中的数据元素链表中的一个结点相应地存储二叉树中的一个结点。
常见的二叉树的链式存储结构有两种:叉链表和三叉链表
二叉链表:是指链表中的每个结点包含两个指针域和一个数据域,分别用来存储指向二叉树中结点的左右孩子的指针及结点信息。
三叉链表是指链表中的每个结点包含三个指针域和一个数据域,相比二叉链表多出的一个指针域则用来指向该结点的双亲结点。