数据结构总结+搬运

C语言与数据结构小总结,自我总结+各处收集来的他人的总结(很多记不清了,若有侵权请联系我删!在这里插入图片描述

一、常用C语言小总结

1)数据类型、运算符与表达式

逗号运算符优先级最低,左操作数为先运算,但这是为右操作数服务,因为整个式子的结果为右操作数的运算结果。

2)输入输出与数组

当遇到需要输入保存空格的情况,使用gets或fgets(还会在最后存多一个\n),而不能使用scanf(遇到空格自动结束输入)。
fgets(a,b,c)a为变量,可为指针;b为其可使用的空间大小;c为stdin(固搭)
eg:scanf(“%s %c”,&a,&b);这里的%c前要空一个格,不然在输完%s后分隔两个数据时就会把那个空格放入b中了。

3)指针

1、必须掌握动态内存申请内存malloc(x)【x代表多少字节】,即申请堆空间。指向堆空间的指针使用完后需要释放,继而置NULL。
在这里插入图片描述

2、堆、栈差异:
(1)栈空间的系统自动分配的,已知大小的,效率高;而堆空间是自己申请的,空间可动态,效率比栈低。
(2)栈空间在函数使用完后就会释放,而堆空间会一直保存着,除非free。

3、指针的表示方法:p、p[]

4)结构体

1、结构体的大小不是将所有数据的类型大小的总和,而是在每种数据对齐4位后才计算。
在这里插入图片描述
2、 结构体指针的定义 eg:struct student *p; struct student *p,q;(定义两个指针时不能忽略 * 号)
结构体指针获取成员 eg: p->num或(p).num(不能写p.Num,因为 . 运算的优先级比
高)

二、数据结构

1、typedef的使用:给数据类型起别名。
目的:为了代码规范,实现代码即含义。
Eg:
typedef struct student
{
Int n;
Int m;
}stu,*pstu

Typedef int INTEGER;

2、C++的引用
把&写进函数形参位置。
Eg:void x(int &a){} 此时操作a与操作实参一样。

3、逻辑结构与存储结构
逻辑结构 数据元素之间的逻辑关系
分类:集合(无序)、线性(一对一)、树形(一对多)、图形(多对多)

存储结构 数据结构在计算机上的实现
分类:顺序存储、链式存储、(索引存储、散列存储)

顺序存储与链式存储对比
在这里插入图片描述

4、时间复杂度与空间复杂度
时间复杂度:要忽略高阶项系数和低阶项。
eg:执行次数为3n3+2n时,时间复杂度为O(n3)
二分查找法,时间复杂度为O(log2n)

---------------------------------------------------------------------------------分割线

1、线性表

1)基本概念
定义:由n个相同类型的数据元素组成有序的集合。
线性表的长度:元素的个数
空表:元素为0个
前驱:an-1为an的前驱
后继:…
2)特点:元素有限、类型相同(即占用空间大小相等)、顺序性

小区分:
线性表为一种逻辑结构,而顺序表、链表是存储结构,两者为两种概念。
数据项构成数据元素,数据元素与数据项不是同一个概念。

3)优缺点
在这里插入图片描述
4)编程实现线性表的 增 删 改 查

2、单链表

1)头插和尾插
2)查找、删除

3、栈

编程实现过程:

1)定义结构体(数组data+,变量top)
2)初始化栈函数(top置-1,否则返回false)
3)确认是否初始化成功,成功后再继续
4)入栈函数(传入指针&S和数据x,若MaxSize-1==top即栈满,则返回false;否则data[++S.top]=x)
5)获取栈顶元素(传入指针S和数据&x<以获取弹出的值>,若栈为空,则false;否则x=data[S.top])
6)出栈函数(传入指针&S和数据&x<以获取弹出的值>,若栈为空,则false;否则x=data[S.top–]<给完值再移回上一位置>)

4、循环队列(为存储结构)

1)定义结构体(数组data,变量front,变量end)
2)初始化函数(传入指针Q,设置front=end=0,返回true)
3)判断是否为空队列(传入指针Q,若end%MaxSize=front,则true;否则false)
4)入队函数(传入指针&Q,数据&x;若队列满<(end+1)%MaxSize=front>,则false;否则Q.data[end++]=x 放入数据并返回显示)
5)出队函数(传入指针&Q,数据&x;若队列空<end%MaxSize=front>,则false;否则x=Q.data[front++] 数据出队并返回显示)

5、队列的链式存储

1)定义结构体1(变量data,指针next)

定义结构体2(指针front,指针end)
2)初始化函数(传入指针&Q,malloc分配空间给Q.front和Q.end并指向同一个地方,Q.end->next置NULL,头节点的next置NULL)
3)入队函数:尾插法(传入指针&Q,数据x,分配空间指向p,front->next=p,p->data=x)
4)出队函数:尾部删除法(传入指针&Q,数据&x,x=Q.front->data,p=Q.front->next,Q.front->next=p.next)

6、层次建立二叉树

1)定义结构体1(链式存储,变量data、指针*left_child,right_child)
定义结构体2(链式队列,记录插入到哪个节点,指针
front,*end,*now)
2)建树根(创建结构体变量,并置NULL)
3)添加
判断now.left是否为空,空则将申请的点地址放入,并将该点加入队列end;
判断now.right是否为空,空则将申请的点地址放入,并将该点加入队列end,还要将队列now指向下一个节点;
4)删除(使用遍历的方式)
5)查找(使用遍历的方式)

学习申请空间新函数:(int)calloc(1,sizeof(int))会自动将其空间都置0,申请的空间大小为 1sizeof(int)。*

7、遍历二叉树

(一)遍历
1)前序:深度优先遍历(因为一直在往下找左孩子,相当于一直深入下去)
父亲->左儿子->右儿子(按照顺序写好3个点后,再逐个插入他们的儿子)
在这里插入图片描述

2)中序:左儿子->父亲->右儿子(相当于将二叉树压扁,从左往右写过来)

3)后序:左儿子->右儿子->父亲
在这里插入图片描述

4)层次遍历(广度优先)
从上到下,从左到右的顺序逐层排下去。

8、线索二叉树

(埋个坑)

9、二叉查找树

(埋个坑)

10、哈希查找(散列)

概念:散列函数——通过某个输入(如字符串、数字)可以计算出一个对应的地址
记作:Hash(key)=Addr
实际使用注意:算出的下标要取余。
散列冲突——输入不同key但算出相同数值;
解决方法:使用链表存放在其后;

散列表——根据关键字能直接访问的数据结构(key与数据对应的表)

11、串

1)KMP算法

next数组求解方法:
(1)给模式串标号(从1开始或者从0开始)
(2)第一个置0,其后=最左边与最右边匹配的字符数+1
在这里插入图片描述

2)KMP改进算法:求Nextval数组

在这里插入图片描述

参考这里:1)三分钟搞定 数据结构 串 KMP算法next数组求值 考试抱佛脚系列_哔哩哔哩_bilibili

https://www.bilibili.com/video/BV1NJ411k7qw/?share_source=copy_web&vd_source=7d735355dd162d59dcebb187b0d9a720

2)四分钟搞定!数据结构 KMP改进算法 nextval数组求值_哔哩哔哩_bilibili

https://www.bilibili.com/video/BV1uJ411s7br/?share_source=copy_web&vd_source=7d735355dd162d59dcebb187b0d9a720

12、图

1)图的分类:有向图、无向图
2)图的表示方法:点+边

有向图:<v1,v2> v1为弧头(箭头直接指着的为头,而不是平常箭头的起始点),v2为弧尾;
无向图:<v1,v2> 此时v1与v2顺序可随意写。

3)存储结构:邻接矩阵、邻接表
(1)邻接表
下图为有向图与无向图存储方式(将每个点的与其相连的点用链表连接起来)
在这里插入图片描述

(2)邻接矩阵(使用二维数组将有点与之相连的位置置1,表示有连接;若是无向图则是关于斜对线对称矩阵),缺点是浪费空间。参考他人侵权删

4)遍历方式
(1)深度优先
在这里插入图片描述

(2)广度优先
(埋个坑)
.
.
.

5)最短路径算法
在这里插入图片描述

在这里插入图片描述

6)拓扑排序

拓扑排序:有向无环图才有,每次选入度为0的节点

逆拓扑排序:每次选出度为0的节点。(使用邻接矩阵存储时求解更快)

在这里插入图片描述

7)关键路径
在这里插入图片描述

【-------------------------------------------分割线-------------------------------------------】

13、排序算法(重要)

以下实现算法的存储结构都为顺序存储,即数组。

1)冒泡排序

从头到尾两两比较,找到大的就互换-------形成一趟循环找到一个最大的数。

2)快速排序

哨兵法:设第一个元素为标杆,其后的元素小的放其左边,大的放其右边,以此不断划分,然后可使用递归划分到只剩下一个元素【即最小的划分】从而实现排序。

在这里插入图片描述

挖坑法:在第0号元素处先作为坑,设置low、high代表数据最左、最右,low不断往后找,当low指向的元素比priot(先存着最右边的数据)的小时,把他插入high指向的位置,low结束后high不断往前找,直到找到比priot小的,把其填入low位置,由此不断循环找,直到low和high相等时排序结束。)

3)插入排序

哨兵法:0号元素作为暂存数据的地方,从2号元素开始,其后的元素不断向前找直到找到比它小的元素就插入它后面的位置,其他元素整体往后移。

另一种不使用哨兵的写法
在这里插入图片描述

4)折半插入排序

(埋坑)
在这里插入图片描述

5)希尔排序

在这里插入图片描述

6)堆排序(重点)

用数组表示二叉树的层次建树的结构。不断把最大的放在根节点,父亲要比孩子大,找到最大的就把其与最后一个节点交换;下一次从除了最后那些节点开始重新找最大。
在这里插入图片描述

7)归并排序

把两个或多个有序的子序列合并为一个。
(1)分类

2路归并——二合一
k路归并——k合一

(2)算法过程:

①若low<high,则将序列分从中间mid=(low+high)/2分开
②对左半部分[low, mid]递归地进行归并排序
③对右半部分[mid+1, high]递归地进行归并排序
④将左右两个有序子序列Merge为一个

(3)具有稳定性

8)基数排序

(1)算法思想:

①将整个关键字拆分为d 位(或组);
②按照各个关键字位权重递增的次序(如:个、十、百),做d趟“分配"和"收集”,若当前处理的关键字位可能取得┌个值,则需要建 r 个队列;
③“分配":顺序扫描各个元素,根据当前处理的关键字位,将元素插入相应队列,一趟分配耗时O(n);
④"收集”:把各个队列中的结点依次出队并链接。一趟收集耗O(n)。

(2)擅长领域

①数据元素的关键字可以方便地拆分为d组,且d较小。
eg:给6个人的身份证号排序
②每组关键字的取值范围不大,即r较小。
③数据元素个n较大。
eg:1亿个数据

9)八大排序算法时空复杂度分析

在这里插入图片描述

--------------------------结束撒花❀❀❀❀❀❀❀❀❀!!!!-----------------

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值