这几种排序方法分别为:冒泡排序,选择排序,插入排序,快速排序
1.冒泡排序:
思想:简单的说就是想办法把一堆数据中最大的数不停地往后边排。
代码:
class Bubble{
// /**
// * 测试方法
// */
// public void test(int i){
// i++;
// System.out.println(i);
// }
public void sort(int arr[]){
int temp = 0;//设置这个变量的目的是为了实现数值的交换
//冒泡排序
for(int i=0;i arr[j+1]){
//交换
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
// //遍历数组输出最后结果
// for(int i=0;i
排序方法一般都就那几种。像冒泡排序,直接插入排序,快速排序,简单选择排序,希尔排序,堆排序。其排序介绍自己看吧。
1、冒泡排序属于稳定排序,是一种借助“交换”进行排序的方法。首先要将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换之,然后比较第二个记录与第三个记录的关键字,以此类推,直至第n-1个记录与第n个记录的关键字进行比较为止,这一过程称为第一趟冒泡排序,其结果使得关键字最大的记录被安置在最后一个记录的位置上;然后进行第二趟冒泡排序,对前N-1个记录进行同样操作;以此类推,直到在一趟排序过程中没有进行过交换记录的操作为止。
2、直接插入排序属于稳定的排序,每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。第一趟将待比较的数值与它的前一个数值进行比较,当前一数值比待比较数值大的情况下继续循环比较,依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程,结束该次循环。
3、快速排序属于不稳定排序,是对起泡排序的一种改进。它的基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。假设待排序的序列为{R.[s],R.[s+1],…….,R.[t]},首先任意选取一个记录,然后按下述原则从新排序记录:将关键字较他小的记录都安置在他的位置之前,将所有关键字较他大的记录都安置在他的位置后面。由此可以该“枢轴”记录最后所落的位置i作为分界线,将序列{R[s],R[s+1]…….R[t]}分割成两个子序列{R[s],R[s+1]…..R[i-1]}和{R[i+1]……R[t]},这个过程称作一趟快速排序。一趟快速排序的具体做法是:附设两个指针low和high,它们的初值分别指向数组第一个数据和最后一个数据,将枢轴记录暂存在R[0]的位置上排序过程中只作R[low]或R[high]的单向移动,直至一趟排序结束后再将枢轴记录移至正确位置上。
4、简单选择排序属于不稳定排序,基本思想是,每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。第i趟简单选择排序是指通过n-i次关键字的比较,从n-i+1个记录中选出关键字最小的记录,并和第i个记录进行交换。共需进行n-1趟比较,直到所有记录排序完成为止。例如:进行第i趟选择时,从当前候选记录中选出关键字最小的k号记录,并和第i个记录进行交换。
5、希尔排序属于不稳定排序,也是一种属插入排序类,它的基本思想是:先将整个待排记录序列分割称为若干个子序列分别进行直接插入排序,待整个序列中记录“基本有序”时,再对全体记录进行一次直接插入排序。希尔排序的一个特点是:子序列的构成不是简单的“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。
6、堆排序属于不稳定排序,它的基本思想是,先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区,再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key;由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆,然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n- 2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。直到无序区只有一个元素为止
这两天复习了一下排序方面的知识,现将目前比较常见的整理一下。
选择排序选择排序的思想是首先先找到序列中最大元素并将它与序列中最后一个元素交换,然后找下一个最大元素并与倒数第二个元素交换,依次类推。此排序很简单,这不做多说,代码实现如下:View Code插入排序算法流程: 1. 从第一个元素开始,该元素可以认为已经被排序
2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5. 将新元素插入到下一位置中
6. 重复步骤2View Code冒泡排序依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。
View Code合并排序 在介绍合并排序之前,首先介绍下递归设计的技术,称为分治法。分治法的核心思想是:当问题比较小时,直接解决。当问题比较大时,将问题分为两个较小的子问题,每个子问题约为原来的一半。使用递归调用解决每个子问题。递归调用结束后,常常需要额外的处理,将较小的问题的结果合并,得到较大的问题的答案。
合并排序算法在接近数组中间的位置划分数组,然后使用递归运算对两个一半元素构成的数组进行排序,最后将两个子数组进行合并,形成一个新的已排好序的数组。
代码如下:View Code快速排序 快速排序与合并排序有着很多相似性。将要排序的数组分成两个子数组,通过两次递归调用分别对两个数组进行排序,再将已经排好序的两个数组合并成一个独立的有序数组。但是,将数组一分为二的做法比合并排序中使用的简单方法复杂的多。它需要将所有小于或者等于基准元素的元素放置到基准元素前面的位置,将大于基准的元素放置到基准后面的位置。
1234
1243
1324
1342
1423
1432
2134
2143
2341
2314
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4231
4213
4312
4321
排序算法 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
分类 在计算机科学所使用的排序算法通常被分类为: 计算的复杂度(最差、平均、和最好表现),依据串列(list)的大小(n)。一般而言,好的表现是O。
(n log n),且坏的行为是Ω(n2)。对於一个排序理想的表现是O(n)。
仅使用一个抽象关键比较运算的排序算法总平均上总是至少需要Ω(n log n)。 记忆体使用量(以及其他电脑资源的使用) 稳定度:稳定排序算法会依照相等的关键(换言之就是值)维持纪录的相对次序。
也就是一个排序算法是稳定的,就是当有两个有相等关键的纪录R和S,且在原本的串列中R出现在S之前,在排序过的串列中R也将会是在S之前。 一般的方法:插入、交换、选择、合并等等。
交换排序包含冒泡排序(bubble sort)和快速排序(quicksort)。选择排序包含shaker排序和堆排序(heapsort)。
当相等的元素是无法分辨的,比如像是整数,稳定度并不是一个问题。然而,假设以下的数对将要以他们的第一个数字来排序。
(4, 1) (3, 1) (3, 7) (5, 6) 在这个状况下,有可能产生两种不同的结果,一个是依照相等的键值维持相对的次序,而另外一个则没有: (3, 1) (3, 7) (4, 1) (5, 6) (维持次序) (3, 7) (3, 1) (4, 1) (5, 6) (次序被改变) 不稳定排序算法可能会在相等的键值中改变纪录的相对次序,但是稳定排序算法从来不会如此。不稳定排序算法可以被特别地时作为稳定。
作这件事情的一个方式是人工扩充键值的比较,如此在其他方面相同键值的两个物件间之比较,就会被决定使用在原先资料次序中的条目,当作一个同分决赛。然而,要记住这种次序通常牵涉到额外的空间负担。
排列算法列表 在这个表格中,n是要被排序的纪录数量以及k是不同键值的数量。 稳定的 冒泡排序(bubble sort) — O(n2) 鸡尾酒排序 (Cocktail sort, 双向的冒泡排序) — O(n2) 插入排序 (insertion sort)— O(n2) 桶排序 (bucket sort)— O(n); 需要 O(k) 额外 记忆体 计数排序 (counting sort) — O(n+k); 需要 O(n+k) 额外 记忆体 归并排序 (merge sort)— O(n log n); 需要 O(n) 额外记忆体 原地归并排序 — O(n2) 二叉树排序 (Binary tree sort) — O(n log n); 需要 O(n) 额外记忆体 鸽巢排序 (Pigeonhole sort) — O(n+k); 需要 O(k) 额外记忆体 基数排序 (radix sort)— O(n·k); 需要 O(n) 额外记忆体 Gnome sort — O(n2) Library sort — O(n log n) with high probability, 需要 (1+ε)n 额外记忆体 不稳定 选择排序 (selection sort)— O(n2) 希尔排序 (shell sort)— O(n log n) 如果使用最佳的现在版本 Comb sort — O(n log n) 堆排序 (heapsort)— O(n log n) Smoothsort — O(n log n) 快速排序 (quicksort)— O(n log n) 期望时间, O(n2) 最坏情况; 对於大的、乱数串列一般相信是最快的已知排序 Introsort — O(n log n) Patience sorting — O(n log n + k) 最外情况时间, 需要 额外的 O(n + k) 空间, 也需要找到最长的递增子序列(longest increasing subsequence) 不实用的排序算法 Bogo排序 — O(n * n!) 期望时间, 无穷的最坏情况。
Stupid sort — O(n3); 递回版本需要 O(n2) 额外记忆体 Bead sort — O(n) or O(√n), 但需要特别的硬体 Pancake sorting — O(n), 但需要特别的硬体 排序的算法 排序的算法有很多,对空间的要求及其时间效率也不尽相同。下面列出了一些常见的排序算法。
这里面插入排序和冒泡排序又被称作简单排序,他们对空间的要求不高,但是时间效率却不稳定;而后面三种排序相对于简单排序对空间的要求稍高一点,但时间效率却能稳定在很高的水平。基数排序是针对关键字在一个较小范围内的排序算法。
插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序 插入排序 插入排序是这样实现的: 首先新建一个空列表,用于保存已排序的有序数列(我们称之为"有序列表")。 从原数列中取出一个数,将其插入"有序列表"中,使其仍旧保持有序状态。
重复2号步骤,直至原数列为空。 插入排序的平均时间复杂度为平方级的,效率不高,但是容易实现。
它借助了"逐步扩大成果"的思想,使有序列表的长度逐渐增加,直至其长度等于原列表的长度。 冒泡排序 冒泡排序是这样实现的: 首先将所有待排序的数字放入工作列表中。
从列表的第一个数字到倒数第二个数字,逐个检查:若某一位上的数字大于他的下一位,则将它与它的下一位交换。 重复2号步骤,直至再也不能交换。
冒泡排序的平均时间复杂度与插入排序相同,也是平方级的,但也是非常容易实现的算法。 选择排序 选择排序是这样实现的: 设数组内存放了n个待排数字,数组下标从1开始,到n结束。
i=1 从数组的第i个元素开始到第n个元素,寻找最小的元素。 将上一步找到的最小元素和第i位元素交换。
如果i=n-1算法结束,否则回到第3步 选择排序的平均时间复杂度也是O(n²)的。 快速排序 现在开始,我们要接触高效排序算法了。
实践证明,快速排序是所有排序算法中最高效的一种。它采用了分治的思想:先保证列表的前半部分。
一、插入排序(Insertion Sort)1. 基本思想:每次将一个待排序的数据元素,插入到前面已经排好序的数列中的适当位置,使数列依然有序;直到待排序数据元素全部插入完为止。
2. 排序过程: 【示例】:[初始关键字] [49] 38 65 97 76 13 27 49 J=2(38) [38 49] 65 97 76 13 27 49 J=3(65) [38 49 65] 97 76 13 27 49 J=4(97) [38 49 65 97] 76 13 27 49 J=5(76) [38 49 65 76 97] 13 27 49 J=6(13) [13 38 49 65 76 97] 27 49 J=7(27) [13 27 38 49 65 76 97] 49 J=8(49) [13 27 38 49 49 65 76 97] 1. Procedure InsertSort(Var R : FileType);2. //对R[1..N]按递增序进行插入排序, R[0]是监视哨//3. Begin4. for I := 2 To N Do //依次插入R[2],。,R[n]//5. begin6. R[0] := R; J := I - 1;7. While R[0] < R[J] Do //查找R的插入位置//8. begin9. R[J+1] := R[J]; //将大于R的元素后移//10. J := J - 111. end12. R[J + 1] := R[0] ; //插入R //13. end14. End; //InsertSort //复制代码二、选择排序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 1. Procedure SelectSort(Var R : FileType); //对R[1..N]进行直接选择排序 //2. Begin3. for I := 1 To N - 1 Do //做N - 1趟选择排序//4. begin5. K := I;6. For J := I + 1 To N Do //在当前无序区R[I..N]中选最小的元素R[K]//7. begin8. If R[J] < R[K] Then K := J9. end;10. If K I Then //交换R和R[K] //11. begin Temp := R; R := R[K]; R[K] := Temp; end;12. end13. End; //SelectSort //复制代码三、冒泡排序(BubbleSort)1. 基本思想: 两两比较待排序数据元素的大小,发现两个数据元素的次序相反时即进行交换,直到没有反序的数据元素为止。2. 排序过程: 设想被排序的数组R[1..N]垂直竖立,将每个数据元素看作有重量的气泡,根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R,凡扫描到违反本原则的轻气泡,就使其向上"漂浮",如此反复进行,直至最后任何两个气泡都是轻者在上,重者在下为止。
【示例】:49 13 13 13 13 13 13 1338 49 27 27 27 27 27 2765 38 49 38 38 38 38 3897 65 38 49 49 49 49 4976 97 65 49 49 49 49 4913 76 97 65 65 65 65 6527 27 76 97 76 76 76 7649 49 49 76 97 97 97 97 1. Procedure BubbleSort(Var R : FileType) //从下往上扫描的起泡排序//2. Begin3. For I := 1 To N-1 Do //做N-1趟排序//4. begin5. NoSwap := True; //置未排序的标志//6. For J := N - 1 DownTo 1 Do //从底部往上扫描//7. begin8. If R[J+1]= X) And (I < J) Do7. begin8. J := J - 1 //从右向左扫描,查找第1个小于 X的元素//9. If I < J Then //已找到R[J] 〈X//10. begin11. R := R[J]; //相当于交换R和R[J]//12. I := I + 113. end;14. While (R <= X) And (I < J) Do15. I := I + 1 //从左向右扫描,查找第1个大于 X的元素///16. end;17. If I X //18. begin R[J] := R; //相当于交换R和R[J]//19. J := J - 120. end21. Until I = J;22. R := X //基准X已被最终定位//23. End; //Parttion //复制代码1. Procedure 。
1.解排列组合的应用题,通常有以下几种途径
(1)以元素为主体,即先满足特殊元素的要求,再考虑其他元素;(2)以位置为主体,即先满足特殊位置的要求,再考虑其他元素;(3)先不考虑附加条件,计算出排列或组合数,再减去不合要求的排列或组合数。
2.典型题解法
相邻问题——捆绑法;相离问题——插空法;多元问题——分类法;标号排位问题——分步法;定序问题——消序法;多排问题——单排法;至少问题——间接法;选排问题——先取后排法;组排问题——先组后排法。
3.总原则
(1)弄清事件的情景:首先搞清有无“顺序”要求,有用Amn(A右上m右下n),反之用Cmn(C右上m右下n);其次弄清目标的实现,是分步还是分类达到,一个复杂问题往往是分步和分类交织在一起的;最后看元素是否重复。
(2)掌握“双向”解题途径,即“正面凑”与“反过来剔”。
(3)重视一题多解,提高分析能力。
声明:本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
蜀ICP备2020033479号-4 Copyright © 2016 学习鸟. 页面生成时间:3.306秒