——————二,顺序表————————————————————————————————
前驱与后继的关系。
InitList(&L) 初始化表
Length(L) 求表长
LocateElem(L,e) 在表L中查找有没有e这个元素,有的话就把该元素的位序返回
GetElem(L,i) 按位查找操作,返回第i个元素
ListInsert(&L,i,e) 插入操作
ListDelete(&L,i,&e) 删除操作
PrintList(L) 输出操作
Empty(L) 判空操作 ,判断是否为空列表
DestroyList(&L) 销毁操作
---------------------------------------------------
顺序表的结构
#define MaxSize 50 #定义一个数组,最大长度为50 。后边这四行是结构体
typedef struct { #typedef 是改名的,把struct改成SqList
ElemType date[MaxSize]; #把数组定义为ElemType 类型,最大容量为MaxSize
int length; #
}SqList; #
--------------------------------------
顺序表的特点:
1.最主要的特点就是随机存取,通过首地址和元素序号在时间O(1)内找到指定元素
2.顺序表的储存密度高,每个节点只存储数据元素
3.顺序表逻辑上相邻的元素物理上也相邻,所以插入和删除需要移动大量元素
-----------------------------
插入操作的代码实现:
bool ListInsert(SqList &L,int i ,ElemType e){
if(i<1||i>L.length+1)
return false;
for(int j=L.length;j>=i;j--)
L.data[j]=L.data[j-1];
L.data[i-1]=e;
L.length++;
return true;
}
--------------------------------------------
删除操作
bool ListDeiete(SqList &L, int i,EiemType &e){
if (i<1||i>L.length)
return false;
e=L.date[i-1];
for(int j=i;j<L.length;j++)
L.date[j-1]=L.data[j];
L.length--;
return true;
}
#移动结点的平均次数(n-1)/2 所以移动的次数为O(n)
------------------------------------------------
顺序表的实现:
按位查找操作:
int GGetEiem(SqList L,int i){
if(i<1||i>L.lrngth)
return 0;
ruturn L.data[i-1]:
}
-------------------------------------------
顺序表的实现:
将两个有序表AB合并为一个新的有序顺序表C
bool Merge (SqList A,SqList B, SqList &C){
if (A.length+B.length>C.MaxSize)
return false;
int i=0,j=0,k=0;
while(i<A.length && j<B.length){
if(A.data[i]<=B.data[j])
C.data[k++]=A.data[i++];
else
C.data[k++]=B.data[j++];
}
while(i<A.length)
C.data[k++]=A.data[i++];
while(j<B.length)
C.data[k++]=B.data[j++];
C.length=k;
return true;
—————三链表——————————————————————————————————
LNode *GetElem(LinkLit L,int i){
int j=1;
LNode *p=L->next;
if(i==0) return L;
if(i<0) return NULL;
while(p&&j<i){
p=p->next; j++;
}
return p;
}
时间复杂度为O(n)
-----------------------------------------------------
按值查找表节点:
LNode *LocateElem(LinkList L,ElemType e){
LNode *p=L->next;
while(p!=NULL&&p->data!=e)
p=p->next;
return p;
}
时间复杂度为:O(n)
--------------------------------------------------
把q的后继改成s,再给s加上后继p。就相当于把s插到qp之间了。
---------------------------------------
删除结点:
p = GetElem(L,i-1);
q=p->next;
p->next=q->next;
free(q);
把i-1个的后继改成i+1,然后再删除第i个元素
---------------------------------
双链表结点中有两个指针prior和next,分别指向其前驱结点和后继结点。
循环单链表:最后的结点是指向第一个结点的
循环双链表:也是首尾相连了起来。
---------------------------------------------------------
所以,循环链表中每一个元素都有后继。
——————四栈和队列———————————————————————————————
栈:
只允许在一端进行插入或删除的线性表,栈顶和栈底。
空栈:不含任何元素的空表。
特性:先进后出。
-----------------------------------------
栈的基本操作:
InitStack(&S) 初始化一个空栈
StackEmpty(S) 判断一个栈是否为空
Push(&S,x) 进栈
Pop(&S,&x) 出栈
GetTop(S,&x) 读栈顶元素
DestroyStack(&S) 销毁栈,并释放栈S占用的存储空间
-------------------------------------------------------------
栈的顺序储存类型可描述为:
#define MaxSize 50
typedef struct{
ElemType data[MaxSize];
int top;
}SqStack;
-----------------------------------------
初始化:
void InitStack(SqStack &S){
S.top = -1;
}
判断栈空:
bool StackEmpty(SqStack S){
if(S,top ==-1)
return true;
else
return false;
}
进栈:
bool Push(SqStack &S,ElemType x){
if (S.top == MaxSize-1)
return false;
S.data[++S.top]=x;
return true;
}
向顺序栈中压入新元素的时候,应当先移动栈顶指针,再存入元素。
------------------------------------------------------------
出栈操作:#栈非空时,先取栈顶元素值,再将栈顶指针减一。
bool Pop(SqStack S,ElemType &x){
if(S.top==-1)
return false;
x=S.data[S.top--];
return true;
}
读栈顶的元素:
bool GetTop(SqStack S.ElemType &x){
if(S.top ==-1)
return false;
x=S.data[S.top];
return true;
}
-------------------------------------------------------
共享栈:两个栈对着,栈A顶+1等于栈B顶,则俩栈都满了。
链栈:便于多个栈共享储存空间和提高其效率,且不存在栈满上溢的情况。
# 栈能适用于递归算法,表达式求值以及括号匹配等问题:
将一个递归算法改为对应的非递归算法时,通常需要使用栈。
------------------------------------------------------------
队列的基本概念:
队列:只能在表的一端进行插入,在表的另一端进行删除。
入队或进队,队尾
出队或离队。队头
特性:先进先出。
-------------------------------------------------
基本操作:
InitQueue(&Q) 初始化队列
QueueEmpty(Q) 判断队列是否为空
EnQueue(&Q,x) 入队
DeQueue(&Q,&x) 出队
GetHead(Q,&x) 读对头元素
------------------------------------------------------------------------------
循环队列:
初始状态跟之前没有区别,队首指针进一,队尾指针进一,队列长度
循环队列的队满和队空条件。:队空条件:Q.front==Q.rear
队满条件 (Q.rear+1) %MaxSize ==Q.front
队列的链式存储结构:
——————五、串——————————————————————————————————
串的基本概念: 由零个或多个字符组成的有限序列。
串的长度: 串中字符的个数n
子串: 串中任意个连续的字符组成的子序列
字符在串中的位置: 该字符在串中的序号
子串在主串中的位置以子串的第一个字符在主串中的位置来表示
当两个串的长度相等,且每个对应位置的字符都相等时,称这两个串是相等的。
#从数据结构来看,串是一种特殊的线性表,其特殊性体现在、数据元素可以是一个字符
串的基本操作:
StrCopy(&T,S) 将串S赋值给T
StrEmpty(S) 判断S是否为空
StrCompare(T,S) 比较串T与S
StrLength(S) 判断串S的长度是多少
SubString(&Sub,S,pos,len) 求主串S中第pos个字符起,长度为len的字串,赋值给Sub,然后返回出来
Concat(&T,S1,S2) 将S1与S2两个字串连接起来,赋值给T
Index(S,T) 定位,如果能从串S中找到与串T相同的话,就返回第一个出现的位置,如果找不到的话,就返回0
-----------------------------
串的简单模式匹配算法:
模式匹配: 字串的定位操作,它求的是子串在主串中的位置。
------------------------------------------------
压缩存储: 为多个值相同的元素值分配一个存储空间,对零元素不分配存储空间,其目的是为了节省存储空间。
特殊矩阵: 具有许多相同矩阵元素或零元素,并且这些相同矩阵元素或零元素的分布有一定规律性的矩阵。 常见的特殊矩阵有对称矩阵、上(下)三角矩阵、稀疏矩阵等。
------------------------------------------------------
矩阵的压缩存储:
对称矩阵的计算存储的地址:
三角矩阵的存储计算公式:
稀疏矩阵: 矩阵中非零元素的个数t,远小于矩阵元素的个数s
将非零元素及其行和列构成一个三元组(行标,列表,值)
#稀疏矩阵的三元组既可以采用三元组(数组)存储,也可以采用十字链表法存储。
———————六 树和二叉树————————————————————————————
树:n(n>=0)个结点的有限集。
有且仅有一个特定的根结点。与下边的有关系。树是递归定义的。根结点有后继没有前驱,最后的结点有前驱没有后继。
1.祖先,双亲,孩子 双亲与孩子。。类似前驱与后继。祖先就是根结点。
2.结点的度:该点孩子的个数
树的度:这个树种结点最大的度(谁的孩子最多,就是几)
3.分支结点(非终端结点):度大于0
叶子结点(终端结点):度为0
兄弟:具有相同双亲的结点。
4.深度,高度。都是指,结点最高的层数。
5.有序树,无序树: 这棵树,从左到右,各结点是有次序的,如果交换了有变化,就是有序树,否则就是无序树。
6.路径,路径长度:路径:两个结点之间的序列。abek。
路径长度:这个路径经过的边的条数。
-------------------------------------
树的性质:
1.树中的结点数等于所有结点的度数+1
2.度为m的树中第i层上至多有m的i-1次方个结点
3.高度为h的m叉树至多有【(m的h次方)-1】(m-1)个结点
4.具有n个结点的m叉树的最小高度为
---------------------------------
二叉树: 二叉树是n(n>=0)个结点的有限集合:
1.或者为空二叉树
2.或者由一个根结点和两个互不相交的被称为根的左子树和右子树组成,左右子树又分别是一颗二叉树。
----------------------
1.满二叉树: 对于一个h层的二叉树,它的结点数是的话,就是一个满二叉树了。
2.完全二叉树: 在满二叉树的情况下,从右往左减去一些结点。当i<=(n/2)的话,就是分支结点,否则则是叶子结点。
3.二叉排序树: 左边结点的关键字总是小于结点的关键字,右结点的关键字总是大于结点的关键字。
4.平衡二叉树: 树上任一结点的左子树和右子树的深度之差绝对值不超过一
---------------------------------------------
二叉树的性质:
1.非空二叉树上的叶子结点数等于度为2的结点数+1,即
2.非空二叉树上第k层上至多有
3.高度为h的二叉树至多有
4.完全二叉树(就是看结点编号后的样子。)
5.具有n>0个结点的完全二叉树的高度为
----------------------------------------
假设度为0的个数为n0、度为2的个数为n2、啧n0=n2+1
因为一共有67个结点,所以n0+n2=67 解出:n2=33
------------------------------------
二叉树的存储结构:
顺序存储结构: 指用一组地址连续的存储单元依次自上而下、自左至右存储完全二叉树的结点元素,即将完全二叉树编号为i的结点元素存储在一维数组下标i-1的分量中。
即:
二叉树链式存储结构: 用链表结点来存储二叉树中的每个结点。
#写程序的时候是空,none还是啥,就是空
----------------------------------------
二叉树的遍历: 按照某条搜索路径访问树中每个结点,使得每个结点均被访问一次,而且仅被访问一次。 按照先遍历左子树再遍历右子树的原则,常见的遍历次序有先序(NLR)、中序(LNR)、后序(LRN)三种遍历算法 #N是结点
先序:若二叉树为空,则什么也不做。否则1.访问根结点,2.先序遍历左子树3.先序遍历右子树
中序:若二叉树为空,则什么也不做。否则1.中序遍历左子树2.访问根结点3.中序遍历右子树
后序:若二叉树为空,则什么也不做。否则1.后序遍历左子树2.后序遍历右子树3.访问根结点
4.层次遍历。
队列先把根结点入队,再出队,再让左子树入队,右子树入队。再出队一个,再让最左边的左右子树入队,再出队一个,再访问出队元素的俩子树。……直到队列为空
——————————七、树和二叉树二————————————————————————
1.树和森林:
树的存储结构: 双亲表示法、孩子表示法、孩子兄弟表示法
1.将树转化为二叉树:
#由树转换为二叉树,其根结点的右子树总是空的。
2.将森林转换成二叉树(森林就是好几颗树,树与树之间没有线相连)
----------------------------------------------------
树的遍历: 用某种方式访问树中的每个结点,且仅访问一次
1.先根遍历 先根后子树
2.后根遍历 先子树后根
森林的遍历:
1.先序遍历 先根后子树
2.中序遍历 先子树后根
二叉排序树:
二叉排序树(二叉查找树)或者是一颗空树,或者是具有以下性质的二叉树
1.若左子树非空,则左子树上所有结点的值均小于根结点的值
2.若右子树非空,则右子树上所有结点的值均大于根结点的值
3.左右子树也分别是一颗二叉排序树
----------------------------------
二叉排序树的插入: 若原二叉排序树为空、则之间插入结点;否则,若关键字小于根结点值,则插入到左子树,若关键字大于根节点值,则插入到右子树。
#向二叉排序树插入一个新结点时,新节点一定会成为二叉排序树的一个叶子结点
二叉排序树的构造:
从一颗空树出发,依次输入元素,将它们插入二叉排序树的合适位置
二叉排序树的删除:
若被删除的结点是叶子节点,则之间删除
若结点只有一颗左子树后者右子树,则让该结点的子树成为其父结点的子树
若结点有左右两颗子树,则令该结点的直接后继(直接前驱),这样就转换成了前两种情况
-----------------------------------------------------
哈夫曼树: 权: 树中结点常被赋予一个代表某种意义的数值
结点带权路径长度: 从树的根到任意结点的路径长度与该结点上权值的乘积
树的带权路径长度: 树中所有叶结点的带权路径长度之和,记为
哈夫曼树:带权路径长度最小(树的)的二叉树
---------------------------------------------------------
——————————八、图—————————————————————————————
图的基本概念:
1.有向图:
即都是有方向的。边写作:<v,w> 即从v指向w
2.无向图:
边写作(v,w) 或(w,v) 因为是没有方向的,所以顺序可以互换。
3.简单图: 不能存在重复边
不能存在顶点到自身的边
4.多重图: 存在重复边,也存在顶点到自身的边
5.完全图(简单完全图): 对于无向图,任意两个顶点之间都存在边。
(边数:n*(n-1)/2)
对于有向图,任意两个顶点之间都存在方向相反的两条弧
(边数:n*(n-1))
6. 子图、生成子图: B的边与顶点都是A的子集,所以B是A的子图 C的顶点与A是相同的,但C的边是A的子集,所以C是A的生成子图
7.连通、连通图:两个顶点之间可以通过边相连。
连通图:图中的任意两个点都可以通过边相连,则这个图是连通图
极小连通子图:既要保持图连同又要使得边数最少的子图
8.生成树:包含图中全部顶点的一个极小连通子图
9.顶点的度、入度和出度: 无向图的全部顶点的度的和等于边数的两倍
对于有向图,入度是以顶点v为终点的又向边的数目
出度是以顶点v为起点的有向边的数目
顶点的度等于入度和出度之和。
有向图的全部顶点的入度之和与出度之和相等,并且等于边数
10.边的权和网: 这些边上的数就是,边的权。都有边的权就称为网
11.路径、路径长度和回路: 路径就是,从一个到另一个的路径。回路是从一个顶点出去再回来。
-----------------------------------------
图的存储结构:邻接矩阵法、邻接表发、十字链表法、邻接多重表法
邻接矩阵法:
1.无向图:
2.有向图:注意方向,可能有边,但方向不对、则为0.
3.带权图:几个顶点就是几阶矩阵。这里与上边的不一样,数字写权。
--------------------------------
邻接表法:
无向图的存储方法:
有向图的存储方法:
与无向图的区别就是,只有指向的指针,没有指回来的指针。所以,存储空间:O(|V|+|E|)
-------------
邻接表法特点:
1.若G为无向图,则所需的存储空间为O(|V|+2|E|)
若G为有向图,则所需的存储空间为O(|V|+|E|)
2.对于稀疏图,采用邻接表表示能极大地节省存储空间
3.图的邻接表表示不唯一
4.在有向图的邻接表表示中,求一个给定顶点的出度只需计算其邻接表中的结点个数
-----------------------------------------------------
图的遍历: 从图中的某一顶点出发,按照某种搜索方法沿着图中的所有顶点访问一次,且仅访问一次
图的遍历算法主要有两种,广度优先搜索和深度优先搜索
1.广度优先搜索: 类似二叉树的层序遍历算法。
层序遍历,, 第一个是1;与1相邻的有3.5.4.2.依次填上。第二个数是几,就看几的连线有几,前面已经填上了就算了,没填上就加上。
直到最后都填上。这种写法,得到的结果可能不同。
1354276;1532476;1354267;1245376…… #例:第一个,与1相连的是3542,都写上,第二个数字是3(此时,13542);与3相连的是15,已经有了,跳过,下一个数字是5,与5相连的是134,有了,跳过;下一个数字是4;与4相连的是256,加上6(此时,135426),下一个数字是2,与2相连的数字是17,加上7;此时已经都有了,就不用再看了。
-----------------------------------------------
2.深度优先搜索: 类似于树的先序遍历。
根据所给出的E画出无向图。然后根据选项走一遍。A是对的。B: 从a出发,c,f,于f相邻的是d且d没有被访问,所以下一个应该是d,但B的下一个的e,所以错误。
C a出发,eb,b的下一个,于b相邻的是d,且d没有被访问,所以C错误。
D aedf,于f相邻且未被访问的是c,应该是,aedfc,然后依次往回退,cfd,与d相邻的有b未被访问,加在最后,所以D应该是aedfcb
#一个图,只要能被广度优先搜索或者深度优先搜索访问所有顶点,则该图一定是连通图
————————九 图的应用—————————————————————————————
最小生成树: 带权连同无向图中,所有生成树中权值之和最小的生成树
prim算法:就是连最短的权,且不能形成回路。还要连起所有的顶点。
Kruskal算法:只要最短的权,但不能形成回路。图中还差最后一条线,即2与3之间的5.因为只有这条不会形成回路
---------------------------------------------------------------
2.最短路径:
列一个表格,根据下边这俩规则,算出从第一个到后边的依次最短的权是多少。
----------------------------------------------
拓扑排序:
AOV网: 定点表示活动<Vi,Vj>
拓扑排序: 每个顶点出现且只出现一次。
若存在一条从顶点A到顶点B的路径则在排序中顶点B出现在顶点A的后边
每删去一个没有前驱的顶点,就记下这个顶点。
--------------------------------------
关键路径: AOE网: 以顶点表示事件,以有向边表示活动,以边上的权值表示完成该活动的开销。
关键路径: 从开始顶点到结束顶点的所有路径中,具有最大路径长度的路径
关键活动:关键路径上的活动
--1.事件Vk的最早发生时间Ve(k) 指从源点V1到顶点Vk的最长长度。
从前往后
--2.事件Vk的最迟发生时间Vl(k) 指在不推迟整个工程完成的前提下,即保证它的后续事件Vj在其最迟发生时间Vl(j)能够发生时,该事件最迟必须发生的时间
Vl(汇点)=Ve(汇点)
Vl(k)=Min{Vl(j)—Weight(Vk,Vj)} 从后往前
--3.活动Ai的最早开始时间E(i) 指该活动弧的起点所表示的事件的最早发生时间
<Vk,Vj> ai
--4.活动Ai的最迟开始时间L(i) 指该活动弧的终点所表示事件的最迟发生时间与该活动所需时间之差
<Vk,Vj> ai
--5.一个活动Ai的最迟开始时间L(i)和其最早考试时间E(i)的差额
如果这个d(i)==0、则这个活动为关键活动 。
-----------------------------------------------------------例题:
——————10、查找————————————————————————————————
-------查找:
1.查找: 在数据集合中,寻找满足某种条件的数据元素的过程
2.查找表(查找结构): 用于查找的数据集合
3.关键字: 数据元素中某个数据项的值、用它可以标识一个数据元素
主关键字: 关键字可以唯一地标识一个记录
4.平均查找长度: 所有查找过程中进行关键字的比较次数的平均值ASL=
----------------------------------------------------
---------------顺序查找
基本思想: 从线性表的一端开始,逐个检查关键字是否满足给定的条件。若查找到某个元素的关键字满足条件,则查找成功,返回该元素在线性表中的位置。若查找到表的另一端,仍未找到符合给定条件的元素,则返回查找失败的信息。
# 定义一个数组 最后一个元素是TableLen
typedef structl{
ElemType *elem:
int TableLen;
}SSTable
# 查找的代码(key 是要查找的元素。这里是从后往前查找):
int Search_Seq(SSTable ST,ElemType key){
ST.elem[0]=key;
for(i =ST.TableLen;ST.elem[i]!=key;--1);
return i;
} #对于线性链表只能进行顺序查找
---------------------------------------------------
折半查找: 折半查找(二分查找),仅适用于有序的顺序表
折半查找的代码:
int Binary_Search(SeqList L,ElemType key){
int low = 0,high = L.TableLen-1.mid;
while(low<=high){
mid = (low+high)/2;
if(L.elem[mid] == key)
return mid;
else if(L.elem[mid]>key)
high = mid-1;
else
low = mid+1;
}
}
关于需要查找多少次:
-------------------------------------------------------
散列表:
散列函数: Hash(key) = Addr #将数值对应称散列 地址
同义词: 散列函数可能会把两个或两个以上的不同关键字映射到同一地址。
1.直接定址法:
2.除留余数法: m 取一个不大于但最接近或等于m的质数p
得到关键字的对应地址
3.数字分析法
4.平方取中法
-------解决冲突的方法:
(1)开放定址法: 可存放新表项的空闲地址既向它的同义词表项开放,又向它的非同义词表项开放。 其数学递推公式为
H:散列函数、m散列表表长、d:增量的序列(根据不同的增量序列,会产生不同的地址)
①线性探测法 d的值分别为0.12.3.4.5.6.......m-1
②平方探测法 d的值分别为 k<=m/2
③再散列法 d等于一个新的散列函数即
因为1/13的余数1已经有数字了,所以冲突了。根据题目用线性探测处理。所以d=1
注意从前往后依次排序。有个数字排了9次,就写9次
---------------------(二)、拉链法:
为了避免非同义词发生冲突。把所有的同义词存储在一个线性链表中(直接存)
散列表的查找长度取决于三个因素:散列函数、处理冲突的方法和填装因子
装填因子a = 表中记录数n/散列表长度m
散列表的平均查找长度依赖于散列表的填装因子a,不直接依赖于n或m
a越大,表示装填的记录越“满”、发生冲突的可能性就越大
————————11、排序上——————————————————————————————
排序的基本概念:
排序: 重新排列表中的元素,使表中的元素满足按关键字有序
稳定性: 经过一个排序算法后,相对位置没有发生变化
内部排序: 指在排序期间元素全部存在内存中的排序 比较和移动
插入排序、交换排序、选择排序、归并排序和基数排序(特殊)
外部排序: 指在排序期间元素无法全部同时存放在内存中,必须在排序的过程中根据要求不断的在内、外存之间移动的排序
-------------------------------------------
插入排序: 基本思想是每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中,直到全部记录插入完成
(1)直接插入排序
void lnsertSort(ElemType A[],int n){
int i ,j;
for(i=2;i<=n;i++)
if(A[i]<A[i-1]){
A[0]=A[i];
for(j=i-1;A[0]<A[j];--j)
A[j+1]=A[j];
A[j+1]=A[0]
}
}
(二)希尔排序: 把相隔某个增量的记录组成一个子表,对各个子表分别进行直接插入排序,当整个表中的元素已呈基本有序时,再对全体记录进行一次直接插入排序
空间效率: O(1)
稳定性: 不稳定
时间效率:
(三)交换排序
冒泡排序: 从后往前(或从前往后)两两比较相邻元素的值,若为逆序,则进行交换,直到序列比较完,第一趟冒泡结束,结果是将最小的元素交换到待排序列的第一个位置(或将最大的元素交换到待排序列的最后一个位置)
空间效率:O(1)
时间效率:O(n的平方)
稳定性: 稳定
void BubbleSort(ElemType A[].int n){
for (i=0;i<n-1;i++)
flag=false;
for(j=n-1;j>i;j--)
if(A[j-1]>A[j]){
swap(A[j-1],A[j]);
flag=true;
}
if(flag==false)
return;
}
快速排序: 在待排序表L[1…n]中任取一个元素pivot作为枢纽(通常取首元素),
通过一趟快速排序将待排序表划分为独立的两个部分
pivot放在了最终位置L[k]中
#快速排序是所有内部排序算法中平均性能最优的排列算法
#快速排序并不适用于原本有序或者基本有序的记录序列进行排序
————————12、排序下—————————————————————————————
选择排序
1.简单选择排序: 基本思想:假设排序表为L[1...n],第i趟排序即从L[i...n]中选择关键字最小的元素与L[i]交换
void SelectSort(ElemType A[],int n){
for(i=0;i<n-1;i++){
min=i;
for(j=i+1;j<n;j++)
if(A[j]<A[min])
min=j;
if(min!=i)
swap(A[i],A[min]);
}
}
空间效率:O(1)
时间效率:O(n的平方)、
稳定性:不稳定
2.堆排序: 小根堆与大根堆(小根堆就是最小的在最上边,往下依次增大;大根堆则相反。)构造方法: 从下往上,从后往前依次比较结点与俩孩子的值。若不符合则交换。
这里要么小根堆,要么大根堆。不符合的就不是。注意是如何把数组转换成堆的。
同时,堆也支持插入操作。对堆进行插入操作时,先将新结点放在堆的末端,再对这个新结点向上执行调整操作。
空间效率:O(1)
时间效率:O()
稳定性:不稳定
归并排序: “归并”的含义是将两个或两个以上的有序表组合成一个新的有序表
2路归并排序
空间效率:O(n)
时间效率:()
稳定性:稳定
基数排序: 基数排序不基于比较和移动进行排序,而基于关键字各位的大小排序
空闲效率:O(r)
时间效率:
稳定性:稳定
-----------------------------------------------------------------------
各种排序算法的比较:
速成课到此结束