目录

1. 顺序表(数组 Array)

2. 链表

2.1 单链表(SingleList)

2.2 带头双向循环链表(List)

2.3 顺序表和链表的对比

3. 栈(Stack)

4. 队列(Queue)

5. 树(Tree)

5.1 树的特点

5.2 二叉树:满二叉树和完全二叉树

5.2.1 顺序结构(数组来存储,heap里面讲)

5.2.2 链式结构

6. 堆(Heap)其实是完全二叉树

7. 图(graph)

8. 散列表(Hash)


数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成 。每一种数据结构都有着独特的数据存储方式。常用的数据结构有:数组,栈,链表,队列,树,图,堆,散列表等,如图所示:

1. 顺序表(数组 Array)

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
  1. 静态顺序表:使用定长数组存储。
  2. 动态顺序表:使用动态开辟的数组存储。

顺序表的接口:

struct SerList//动态顺序表
{SQDateType *a;int size;int capacity;
};
typedef struct SerList SL;void SeqListPushBack(SL* ps, SQDateType x);
void SeqListPushFront(SL* ps, SQDateType x);
void SeqListPopBack(SL* ps);
void SeqListPopFront(SL* ps);
void SeqListInsert(SL* ps, int pos, SQDateType x);
void SeqListErase(SL* ps, int pos);
int SeqListFind(SL* ps, SQDateType x);
void SeqListModify(SL* ps, int pos, SQDateType x);

顺序表的问题:

  1. 中间/头部的插入删除,时间复杂度为O(N)
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200, 我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
因此,有了链表!

2. 链表

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。

  1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
  2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。

2.1 单链表(SingleList)

单链表的接口:

typedef int SLDateType;
typedef struct SListNode
{SLDateType data;struct SListNode* next;//注意:这里不能嵌套结构体,只能是地址}SLTNode;void SListPrint(SLTNode* phead);
void SListPushBack(SLTNode** pphead, SLDateType x);
void SListPushFront(SLTNode** pphead, SLDateType x);
void SListPopBack(SLTNode** pphead);
void SListPopFront(SLTNode** pphead);SLTNode* SListFind(SLTNode* phead, SLDateType x);void SListInsert(SLTNode** pphead, SLTNode* pos, SLDateType x);
void SListErase(SLTNode** pphead, SLTNode* pos);int SListLen(SLTNode* phead);//求链表的长度

2.2 带头双向循环链表(List)

双向循环链表的接口:

typedef int LTDataType;
typedef struct ListNode
{LTDataType data;struct ListNode* prev;struct ListNode* next;
}ListNode;void ListInit(ListNode** pphead);
void ListDestroy(ListNode* phead);
void ListPushBack(ListNode* phead, LTDataType x);
void ListPushFront(ListNode* phead, LTDataType x);
void ListPopBack(ListNode* phead);
void ListPopFront(ListNode* phead);void ListPrint(ListNode* phead);
ListNode* ListFind(ListNode* phead, LTDataType x);void ListInsert(ListNode* phead, ListNode* pos, LTDataType x);
void ListErase(ListNode* phead, ListNode* pos);

2.3 顺序表和链表的对比

顺序表:

  • 优点:空间连续、支持随机访问
  • 缺点:1.中间或前面部分的插入删除时间复杂度O(N) 2.增容的代价比较大。

链表:

  • 优点:1.任意位置插入删除时间复杂度为O(1) 2.没有增容问题,插入一个开辟一个空间。
  • 缺点:以节点为单位存储,不支持随机访问

3. 栈(Stack)

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
出栈:栈的删除叫做出栈,出数据在栈顶。

栈的接口(用数组来实现的,也可以用链表):

//栈可以用顺序表(数组)来实现
typedef int STDateType;
typedef struct Stack
{STDateType* a;int top;//top用来操作栈顶的数据,top相当于sizeint capacity;
}Stack;void StackInit(Stack* pst);
void StackDestroy(Stack* pst);void StackPush(Stack* pst, STDateType x);
void StackPop(Stack* pst);STDateType StackTop(Stack* pst);
bool StackEmpty(Stack* pst);
int StackSize(Stack* pst);

4. 队列(Queue)

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头

队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

队列的接口:

typedef int QDataType;
// 链式结构:表示队列
typedef struct QListNode
{struct QListNode* next;QDataType data;
}QNode;// 队列可以用链表来实现
typedef struct Queue
{QNode* head;QNode* tail;
}Queue;void QueueInit(Queue* q);// 初始化队列
void QueueDestroy(Queue* q);// 销毁队列
void QueuePush(Queue* q, QDataType data);// 队尾入队列
void QueuePop(Queue* q);// 队头出队列QDataType QueueFront(Queue* q);// 获取队列头部元素
QDataType QueueBack(Queue* q);// 获取队列队尾元素
int QueueSize(Queue* q);// 获取队列中有效元素个数
bool QueueEmpty(Queue* q);// 检测队列是否为空

5. 树(Tree)

5.1 树的特点

树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做 “树” 是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:

  1. 每个节点有零个或多个子节点;
  2. 没有父节点的节点称为根节点;
  3. 每一个非根节点有且只有一个父节点;
  4. 除了根节点外,每个子节点可以分为多个不相交的子树;

5.2 二叉树:满二叉树完全二叉树

在日常的应用中,我们讨论和用的更多的是树的其中一种结构,就是二叉树
二叉树是树的特殊一种,具有如下特点:

  1. 每个结点最多有两颗子树,结点的度最大为2。
  2. 左子树和右子树是有顺序的,次序不能颠倒。
  3. 即使某结点只有一个子树,也要区分左右子树。

二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。

5.2.1 顺序结构(数组来存储,heap里面讲)

顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,关于堆我们后面的章节会专门讲解。二叉树顺序存储在 物理上是一个数组,在逻辑上是一颗二叉树。

5.2.2 链式结构

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表 中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结 点的存储地址 。链式结构又分为二叉链和三叉链,当前我们学习中一般都是二叉链,后面课程学到高阶数据 结构如红黑树等会用到三叉链。

链式结构接口如下:(包括三种遍历方式:前序遍历、中序遍历、后序遍历,以及层序遍历)

typedef char BTDataType;
typedef struct BinaryTreeNode
{BTDataType _data;struct BinaryTreeNode* _left;struct BinaryTreeNode* _right;
}BTNode;// 通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树
BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi);
// 二叉树销毁
void BinaryTreeDestory(BTNode** root);
// 二叉树节点个数
int BinaryTreeSize(BTNode* root);
// 二叉树叶子节点个数
int BinaryTreeLeafSize(BTNode* root);
// 二叉树第k层节点个数
int BinaryTreeLevelKSize(BTNode* root, int k);
// 二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root, BTDataType x);
// 二叉树前序遍历
void BinaryTreePrevOrder(BTNode* root);
// 二叉树中序遍历
void BinaryTreeInOrder(BTNode* root);
// 二叉树后序遍历
void BinaryTreePostOrder(BTNode* root);
// 层序遍历
void BinaryTreeLevelOrder(BTNode* root);
// 判断二叉树是否是完全二叉树
int BinaryTreeComplete(BTNode* root);

6. 堆(Heap)其实是完全二叉树

堆是一种比较特殊的数据结构,可以被看做一棵树的数组对象,具有以下的性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。

将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。常见的堆有二叉堆、斐波那契堆等。

堆的定义如下:n个元素的序列{k1,k2,ki,…,kn}当且仅当满足下关系时,称之为堆。
(ki <= k2i,ki <= k2i+1)或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4…n/2),满足前者的表达式的成为小顶堆,满足后者表达式的为大顶堆,这两者的结构图可以用完全二叉树排列出来,示例图如下:

堆的接口实现:(向下调整算法、向上调整算法)

typedef int HPDataType;
//用数组来实现堆(堆就是完全二叉树)
typedef struct Heap
{HPDataType* _a;int _size;int _capacity;
}Heap;void AdjustDown(int* a, int n, int parent);
void AdjustUp(int* a, int child);// 堆的构建
void HeapCreate(Heap* hp, HPDataType* a, int n);
// 堆的销毁
void HeapDestory(Heap* hp);
// 堆的插入
void HeapPush(Heap* hp, HPDataType x);
// 堆的删除
void HeapPop(Heap* hp);
// 取堆顶的数据
HPDataType HeapTop(Heap* hp);
// 堆的数据个数
int HeapSize(Heap* hp);
// 堆的判空
int HeapEmpty(Heap* hp);
// 对数组进行堆排序
void HeapSort(int* a, int n);

7. 图(graph)

8. 散列表(Hash)

(待更新……)

常见的数据结构总结(8种)相关推荐

  1. 【数据结构】549- 8种常见数据结构(JS实现)

    来源 | https://segmentfault.com/a/1190000020011987 本文代码较多,建议PC阅读~ 做前端的同学不少都是自学成才或者半路出家,计算机基础的知识比较薄弱,尤其 ...

  2. redis五种常见的数据结构

    文章目录 概述 一.对象的类型和编码 二.五种数据结构 五种数据结构的底层实现结构 1.字符串(String) 1)int 编码 2)embstr 编码 3)raw 编码 2.列表(List) 1)z ...

  3. Java基础-JAVA中常见的数据结构介绍

    Java基础-JAVA中常见的数据结构介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是数据结构 答:数据结构是指数据存储的组织方式.大致上分为线性表.栈(Stack) ...

  4. python常见的数据结构

    Python中常见的数据结构可以统称为容器.序列(如列表和元组).映射(如字典)以及集合(set)是三类主要的容器. 线性数据结构分类:栈(stack)--先进后出. 队列(queue)-先进先出.双 ...

  5. java中常见的数据结构分类

    自己总结了下java中常见的数据结构和分类 在这里,我总结了list中数据结构对应我们所学的线性表,属于顺序存储还是链式存储,但没有总结set数据结构对应我们所学的哪一种(按理说应该是集合),是因为t ...

  6. 面试中常见的数据结构

    上次在面试时被面试官问到学了哪些数据结构,那时简单答了栈.队列/(ㄒoㄒ)/~~其它就都想不起来了,今天有空整理了一下几种常见的数据结构,原来我们学过的数据结构有这么多~ 首先,先来回顾下C语言中常见 ...

  7. 硬核资源!Redis 五种数据结构以及三种高级数据结构解析(详解)

    上一篇分享的是<深入理解JVM>,这篇给大家分享<Redis 五种数据结构以及三种高级数据结构解析>. 前言 在 Redis 最重要最基础就属 它丰富的数据结构了,Redis ...

  8. 常见的数据结构:栈 队列 数组 链表 红黑树——List集合 _ HashSet集合、可变参数 collections集合 Map集合

    2021-06-07复习java 一.常见的数据结构 栈(先进后出) 队列 数组 链表 红黑树 二.List集合_介绍&常用方法 ArrayList集合 Linkedlist集合 三.Hash ...

  9. 常见的数据结构基本介绍

    文章目录 常见的数据结构介绍 栈和队列的介绍 数组数据结构 链表数据结构 二叉树和二叉查找树 平衡二叉树 红黑树结构 常见的数据结构介绍 数据结构是计算机底层存储.组织数据的方式.是指数据相互之间是以 ...

  10. python快速入门【二】----常见的数据结构

    python入门合集: python快速入门[一]-----基础语法 python快速入门[二]----常见的数据结构 python快速入门[三]-----For 循环.While 循环 python ...

最新文章

  1. mac 命令行 解压7z文件_Mac 有哪些好用的压缩软件?
  2. linux 用户态 隐藏进程 简介
  3. Python的单引号、双引号和三引号的字符串
  4. 开启Linux系统路由转发功能 实现多网段电脑共享上网
  5. 从运维角度浅谈MySQL数据库优化
  6. c语言结构体单元测试,C语言结构体单元练习.doc
  7. 优化 回归_使用回归优化产品价格
  8. 李宏毅机器学习(四)Spatial Transformer Layer
  9. Microsoft Visual Studio Tools for AI
  10. android简易双屏支持【转】
  11. 如何查询以太信道接口_浅谈百兆千兆以太网物理层
  12. 一些机器学习算法总结
  13. centos7 搭建本地git_小白也能看懂,30 分钟搭建个人博客!
  14. 处理11gR2 RAC集群资源状态异常INTERMEDIATE,CHECK TIMED OUT
  15. 主成分分析(PCA)Principal Component Analysis
  16. egret性能优化总结
  17. hist 和imhist的区别
  18. 大数据核心技术是什么 怎么掌握Hadoop知识
  19. 域名转入阿里云操作说明
  20. linux内存条故障,linux – 如何从MCE消息中找到故障内存模块?

热门文章

  1. Delphi之BitBlt函数与屏幕截屏
  2. 使用Android API最佳实践 Retrofit OKHttp GSON
  3. 如何判断对象已经死亡
  4. 初赛可能会用到的计算机基础理论知识整理
  5. 八月节日营销活动方案
  6. 支付宝小程序订单倒计时分秒
  7. 对于Hadamard product (matrices)的初相识
  8. Office365配置Outlook客户端报到服务器的加密连接不可用如何处理?
  9. osgEarth各个示例分析目录
  10. 一文彻底搞懂volatile用法