排序方法有哪些?
1.?基本理念:
一次将一个要排序的数据元素插入到先前排序的序列中的适当位置,以便该序列仍然有序;直到插入所有要排序的数据元素。
2.?分类过程:
示例:
【初始关键词】?[49]?38?65?97?76?13?27?四十九个
J=2(38)?[38?49]?65?97?76?13?27?四十九个
J=3(65)?[38?49?65]?97?76?13?27?四十九个
J=4(97)?[38?49?65?97]?76?13?27?四十九个
J=5(76)?[38?49?65?76?97]?13?27?四十九个
J=6(13)?[13?38?49?65?76?97]?27?四十九个
J=7(27)?[13?27?38?49?65?76?97]?四十九个
J=8(49)?[13?27?38?49?49?65?76?97]?
程序?InsertSort(Var?r?:?FileType);
//Sort R [1...n]按升序排列。R[0]是监控岗//
开始
为了什么?我?:=?2?去哪?n?做什么?//插入R[2],...,R[n]//
开始
?R[0]?:=?r;?j?:=?我?-?1;
?什么时候?R[0]?& lt?R[J]?做什么?//找到r//的插入位置
开始
R[J+1]?:=?r[J];?//向后移动大于r//的元素
j?:=?j?-?1
结束
?R[J?+?1]?:=?R[0]?;?//插入r?//
结束
结束;?//InsertSort?//复制代码II。选择排序。
1.?基本理念:
每次行程从要排序的数据元素中选择最小(或最大)的元素,顺序放在排序后的数据序列的末尾,直到所有要排序的数据元素都排列好。
2.?分类过程:
示例:
初始关键字?[49?38?65?97?76?13?27?49]
第一次排序后?13?[38?65?97?76?49?27?49]
第二次排序后?13?27?[65?97?76?49?38?49]
第三次排序后?13?27?38?[97?76?49?65?49]
第四次排序后?13?27?38?49?[49?97?65?76]
第五次排序后?13?27?38?49?49?[97?97?76]
第六次排序后?13?27?38?49?49?76?[76?97]
第七次排序后?13?27?38?49?49?76?76?[?97]
最终排序结果?13?27?38?49?49?76?76?97?
程序?选择排序(Var?r?:?FileType);?//Sort R [1...n]直接?//
开始
为了什么?我?:=?1?去哪?n?-?1?做什么?//不要n?-?1遍选择排序//
?开始
?k?:=?我;
?为了什么?j?:=?我?+?1?去哪?n?做什么?//选择当前无序区域R[I]中最小的元素R [k]...n]//
开始
如果?R[J]?& lt?R[K]?然后呢?k?:=?J
结束;
?如果?k?& lt& gt?我?然后呢?//交换R和R[K]?//
开始?临时工?:=?r;?r?:=?r[K];?R[K]?:=?温度;?结束;
?结束
结束;?//SelectSort?//复制代码III。气泡排序
1.?基本理念:
比较要成对排序的数据元素的大小,当发现两个数据元素的顺序相反时就交换,直到没有逆序的数据元素为止。
2.?分类过程:
假设排序后的数组r [1...n]竖着站,把每个数据元素看成一个有重量的泡泡。根据轻气泡不能在重气泡下面的原则,自下而上扫描数组r。当扫描到违反这个原则的轻气泡时,让它们向上“浮动”,以此类推,直到任意两个气泡上面轻下面重。
示例:
49?13?13?13?13?13?13?13
38?49?27?27?27?27?27?27
65?38?49?38?38?38?38?38
97?65?38?49?49?49?49?四十九个
76?97?65?49?49?49?49?四十九个
13?76?97?65?65?65?65?65
27?27?76?97?76?76?76?76
49?49?49?76?97?97?97?97?
程序?BubbleSort(Var?r?:?FileType)?//自下而上冒泡排序//
开始
为了什么?我?:=?1?去哪?N-1?做什么?//不进行N-1排序//
开始
?NoSwap?:=?真实;?//设置未排序标志//
?为了什么?j?:=?n?-?1?唐托?1?做什么?//自下而上扫描//
?开始
如果?r[J+1]& lt;?R[J]?然后呢?//交换元素//
开始
?临时工?:=?r[J+1];?R[J+1?:=?r[J];?R[J]?:=?温度;
?NoSwap?:=?错误的
结束;
?结束;
?如果?NoSwap?然后呢?Return//如果本次排序没有交换,算法将终止//
结束
结束;?//BubbleSort//复制代码IV。快速排序(快速?排序)
1.?基本理念:
取当前无序区R [1中的任意数据元素...h]作为比较的“基准”(不妨记为X),并用这个基准把当前的无序区分成两个更小的无序区:R[1..I-1]和R [I+1...右边未排序子区域的数据元素都大于等于引用元素,引用X位于最终排序位置,即R[1..I-1] ≤ X. Key ≤ R[I+1..H] (1 ≤ I ≤ h),当R [
2.?分类过程:
示例:
初始关键字?[49?38?65?97?76?13?27?49]
第一次交换后
[27?38?65?97?76?13?49?49]
第二次交换后
[27?38?49?97?76?13?65?49]
第三次交换后,向左扫描,位置不变。
[27?38?13?97?76?49?65?49]
第四次交换后,我向右扫描,位置不变。
[27?38?13?49?76?97?65?49]
向左扫描
[27?38?13?49?76?97?65?49]
(分裂过程)
初始关键字
[49?38?65?97?76?13?27?49]
在一次分类旅行后,
[27?38?13]?49?[76?97?65?49]
经过两次分拣后。
[13]?27?[38]?49?[49?65]76?[97]
经过三次分拣旅行?13?27?38?49?49?[65]76?97
最终排名结果?13?27?38?49?49?65?76?97
每次行程整理后是什么状态?
程序?partition(Var?r?:?文件类型;?l,?h?:?整数;?Var?我?:?整数);
//划分无序区域R[1,H],我给出这个划分后已经定位的参考元素的位置?//
开始
我?:=?1;?j?:=?h;?x?:=?r?;//初始化,以x为基准//
重复
什么时候?(R[J]?& gt=?x)?然后呢。(我?& lt?j)?做
?开始
j?:=?j?-?1?//从右向左扫描找到第1个小于?x//的元素
如果?我?& lt?j?然后呢?//R[J]已经找到了?〈X//
?开始
?r?:=?r[J];?//相当于交换R和R[J]//
?我?:=?我?+?1
?结束;
什么时候?(R?& lt=?x)?然后呢。(我?& lt?j)?做
?我?:=?我?+?1?//从左向右扫描找到第1个大于?x///的元素
?结束;
?如果?我?& lt?j?然后呢?//r找到了?& gt?x?//
开始?R[J]?:=?r;?//相当于交换R和R[J]//
j?:=?j?-?1
结束
直到?我?=?j;
r?:=?x?//基准X已最终定位//
结束;?//partition?//复制代码程序?快速排序(Var?r?:文件类型;?s,T:?整数);?//排序R [s...t]快点//
开始
如果?s?& lt?t?然后呢?//当r [s...t]为空或者只有一个元素没有排序//
开始
?Partion(R,s,?t,?I);?//除R [s...t]//
?快速排序(R,s,?I-1);//递归处理左区间R[S,I-1]//
?快速排序(R,I+1,T);//递归处理右区间R[I+1..T]?//
结束;
结束;?//快速排序//复制代码五、堆排序(Heap?排序)
1.?基本理念:
堆排序是一种树选择排序。在排序过程中,R [1...n]视为完全二叉树的顺序存储结构,利用完全二叉树中父节点与子节点的内在关系选择最小元素。
2.?堆的定义:?n个元素的序列K1,K2,K3,...,Kn。当且仅当序列满足以下特征时,称为堆:
Ki≤K2i?Ki?≤K2i+1(1≤?我≤?[N/2])
Heap本质上是一棵满足以下性质的完全二叉树:树中任意非叶节点的关键字大于或等于其子节点的关键字。比如序列10,15,56,25,30,70是堆,其对应的完整二叉树如上图所示。这个堆中的根节点(称为堆顶)的关键字最小,所以我们称之为小根堆。另一方面,如果完全二叉树中任意非叶节点的关键字大于或等于其子节点的关键字,则称为大根堆。
3.?分类过程:
堆排序是用小根堆(或大根堆)在当前无序区域选择关键字小(或最大)的记录来实现排序。我们不妨用大堆来排序。每一遍排序的基本操作是:将当前未排序区域调整为一个大的根堆,选择关键字最大的最上面的记录,与未排序区域的最后一条记录交换。这样正好与直接选择排序相反,在原记录区域的末端形成有序区域,并逐渐扩展到整个记录区域。
例如:堆关键字序列42,13,91,23,24,16,05,88?
程序?Sift(Var?r?:文件类型;?我,?m?:?整数);
//调用数组R[I中的R..M]使其成为完整的二叉树形成堆。它的左右子树(2I+1?& lt=M)都是堆//
开始
x?:=?r;?j?:=?2 * I;?//如果j?& lt=M,?R[J]是R的左子//
什么时候?j?& lt=?m?做什么?//如果当前调整的节点R有一个左子节点R[J]//
开始
如果?(J?& lt?m)?然后呢。R[J]。钥匙?& lt?R[J+1]。钥匙?然后
?j?:=?j?+?1?//用更大的关键字//使J指向正确的子节点
//J指向R的左右子节点,它们具有更大的关键字//
如果?十.钥匙?& lt?R[J]。钥匙?然后呢?//子节点关键字大//
?开始
r?:=?r[J];?//将R[J]更改为父位置//
我?:=?j?;?j?:=?2*I?//以R[J]为当前调整节点继续调整到下一级//
?结束;
?其他
?退出//调整后,退出循环//
结束
r?:=?x;//将最初调整的节点放在正确的位置//
结束;//Sift//复制代码程序?HeapSort(Var?r?:?FileType);?//Sort R [1...n]在堆中//
开始
为了什么?我?:=?n?Div?唐托?1?做什么?//建立初始堆//
Sift(R,我?,?n)
为了什么?我?:=?n?唐托?2?做什么?//排序N-1次//
开始
t?:=?r[1];?R[1]?:=?r;?r?:=?t;//将堆顶部的当前记录与堆中的最后一条记录交换//
Sift(R,1,?I-1)?//重新堆R [1...I-1]//
结束
结束;?//HeapSort//复制代码VI。几种排序算法的比较与选择
1.?选择分类方法时需要考虑的因素:
(1)?要排序的元素数量n;
(2)?元素本身的信息量;
(3)?关键词的结构和分布;
(4)?语言工具的条件,辅助空间的大小等。
2.?总结:
(1)?如果n很小(n?& lt=?50),可以使用直接插入排序或者直接选择排序。因为直接插入排序比直接选择排序需要更多的记录移动操作,所以当记录本身的信息量较大时,直接选择排序更好。
(2)?如果文件的初始状态已经基本按关键字排序,选择直接插入或者冒泡排序比较合适。
(3)?如果n较大,应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序。
在目前基于比较的内部排序方法中,快速排序被认为是最好的方法。
(4)?在基于比较的排序方法中,每次比较两个关键字的大小后,只出现两个可能的转移,因此可以用一棵二叉树来描述比较决策过程,可以证明当一个文件的n个关键字随机分布时,任何借助“比较”的排序算法至少需要O(nlog2n)时间。
这句话很重要?它告诉我们写的算法?是不是提高到最好了?当然也没必要总是追求最好。
(5)?当记录本身包含大量信息时,为了避免花费大量时间移动记录,可以使用链表作为存储结构。?