hello,这里是bangbang,本系列记录我所学数据结构相关知识。
目录
1.线性表
线性表
(
linear list
)
是
n
个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使
用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串
...
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的(比如链表只是逻辑上的连续), 线性表在物理上存储时,通常以数组和链式结构的形式存储。
2.顺序表
顺序表是用一段
物理地址连续
的存储单元依次存储数据元素的线性结构,一般情况下采用数组存
储。在数组上完成数据的增删查改。
静态顺序表:定长数组
![](https://i-blog.csdnimg.cn/blog_migrate/4fd84c635d9a30470f067d1666dd6d4e.png)
动态顺序表:动态开辟
2.1接口实现
// 基本增删查改接口// 顺序表初始化void SeqListInit ( SeqList * psl );// 检查空间,如果满了,进行增容void CheckCapacity ( SeqList * psl );// 顺序表尾插void SeqListPushBack ( SeqList * psl , SLDataType x );// 顺序表尾删void SeqListPopBack ( SeqList * psl );// 顺序表头插void SeqListPushFront ( SeqList * psl , SLDataType x );// 顺序表头删void SeqListPopFront ( SeqList * psl );// 顺序表查找int SeqListFind ( SeqList * psl , SLDataType x );// 顺序表在 pos 位置插入 xvoid SeqListInsert ( SeqList * psl , size_t pos , SLDataType x );// 顺序表删除 pos 位置的值void SeqListErase ( SeqList * psl , size_t pos );// 顺序表销毁void SeqListDestory ( SeqList * psl );// 顺序表打印void SeqListPrint ( SeqList * psl );
具体代码可以参考我的gitee
3.链表
3.1链表的概念和结构
链表是一种
物理存储结构上非连续
、非顺序的存储结构,数据元素的
逻辑顺序
是通过链表
中的
指针链接
次序实现的 。
单链表:一个数据域,一个地址域
![](https://i-blog.csdnimg.cn/blog_migrate/f22f1ac75bccfe4377fee2dccd4fb413.png)
需要注意:
申请的空间一般是从堆上申请,并且连续申请的两个结点可能地址连续,也可能不连续。
3.2链表分类
链表有许多种类,我分为3部分,进行组合形成我们需要的链表
1、单向或双向
2、带头或不带头
3、循环或非循环
我们最常用的两种结构是:无头单向非循环链表、带头双向循环链表
1. 无头单向非循环链表: 结构简单 ,一般不会单独用来存数据。实际中更多是作为 其他数据结构的子结构 ,如哈希桶、图的邻接表等等。另外这种结构在 笔试面试 中出现很多。2. 带头双向循环链表: 结构最复杂 ,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。
3.3单链表接口
// 1 、无头 + 单向 + 非循环链表增删查改实现typedef int SLTDateType ;typedef struct SListNode{SLTDateType data ;struct SListNode * next ;} SListNode ;// 动态申请一个结点SListNode * BuySListNode ( SLTDateType x );// 单链表打印void SListPrint ( SListNode * plist );// 单链表尾插void SListPushBack ( SListNode ** pplist , SLTDateType x );// 单链表的头插void SListPushFront ( SListNode ** pplist , SLTDateType x );// 单链表的尾删void SListPopBack ( SListNode ** pplist );// 单链表头删void SListPopFront ( SListNode ** pplist );// 单链表查找SListNode * SListFind ( SListNode * plist , SLTDateType x );// 单链表在 pos 位置之后插入 xvoid SListInsertAfter ( SListNode * pos , SLTDateType x );// 单链表删除 pos 位置之后的值void SListEraseAfter ( SListNode * pos );
详细代码:我的gitee
3.4带头双向循环链表
// 2 、带头 + 双向 + 循环链表增删查改实现typedef int LTDataType ;typedef struct ListNode{LTDataType _data ;struct ListNode * next ;struct ListNode * prev ;} ListNode ;// 创建返回链表的头结点 .ListNode * ListCreate ();// 双向链表销毁void ListDestory ( ListNode * plist );// 双向链表打印void ListPrint ( ListNode * plist );// 双向链表尾插void ListPushBack ( ListNode * plist , LTDataType x );// 双向链表尾删void ListPopBack ( ListNode * plist );// 双向链表头插void ListPushFront ( ListNode * plist , LTDataType x );// 双向链表头删void ListPopFront ( ListNode * plist );// 双向链表查找ListNode * ListFind ( ListNode * plist , LTDataType x );// 双向链表在 pos 的前面进行插入void ListInsert ( ListNode * pos , LTDataType x );// 双向链表删除 pos 位置的结点void ListErase ( ListNode * pos );
老规矩(滑稽)gitee
4.顺序表和链表的区别
不同点 | 顺序表 | 链表 |
存储空间上
|
物理上一定连续
|
逻辑上连续,但物理上不一定连续
|
随机访问
| 支持O(1) |
不支持:
O(N)
|
任意位置插入或者删除元素
| 可能需要搬移元素,效率低O(N) |
只需修改指针指向
|
插入
|
动态顺序表,空间不够时需要扩容
|
没有容量的概念
|
应用场景
|
元素高效存储
+
频繁访问
|
任意位置插入和删除频繁
|
缓存利用率
| 高 | 低 |
记录学习,有些草率了请见谅,谢谢!