MoreWindows白话经典算法之七大排序(高清版)

合集下载

十大经典排序算法总结

十大经典排序算法总结

⼗⼤经典排序算法总结最近⼏天在研究算法,将⼏种排序算法整理了⼀下,便于对这些排序算法进⾏⽐较,若有错误的地⽅,还请⼤家指正0、排序算法说明0.1 排序术语稳定:如果a=b,且a原本排在b前⾯,排序之后a仍排在b的前⾯不稳定:如果a=b,且a原本排在b前⾯,排序之后排在b的后⾯时间复杂度:⼀个算法执⾏所耗费的时间空间复杂度:⼀个算法执⾏完所需内存的⼤⼩内排序:所有排序操作都在内存中完成外排序:由于数据太⼤,因此把数据放在磁盘中,⽽排序通过磁盘和内存的数据传输才能进⾏0.2算法时间复杂度、空间复杂度⽐较0.3名词解释n:数据规模k:桶的个数In-place:占⽤常数内存,不占⽤额外内存Out-place:占⽤额外内存0.4算法分类1.冒泡排序冒泡排序是⼀种简单的排序算法。

它重复地⾛访过要排序的数列,⼀次⽐较两个元素,如果它们的顺序错误就把它们交换过来。

⾛访数列的⼯作是重复地进⾏直到没有再需要交换,也就是说该数列已经排序完成。

这个算法的名字由来是因为越⼩的元素会经由交换慢慢“浮”到数列的顶端1.1算法描述⽐较相邻的元素,如果前⼀个⽐后⼀个打,就交换对每⼀对相邻元素做同样的⼯作,从开始第⼀对到结尾最后⼀对,这样在最后的元素应该会是最⼤的数针对所有的元素重复以上的步骤,除了最后⼀个重复步骤1-3,知道排序完成1.2动图演⽰1.3代码实现public static int[] bubbleSort(int[] array) {if (array.length == 0)return array;for (int i = 0; i < array.length; i++)for (int j = 0; j < array.length - 1 - i; j++)if (array[j + 1] < array[j]) {int temp = array[j + 1];array[j + 1] = array[j];array[j] = temp;}return array;}1.4算法分析最佳情况:T(n) = O(n) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)2.选择排序表现简单直观的最稳定的排序算法之⼀,因为⽆论什么数据都是O(n2)的时间复杂度,⾸先在未排序序列中找到最⼩(⼤)元素,与数组中第⼀个元素交换位置,作为排序序列的起始位置,然后再从剩余未排序元素中继续寻找最⼩(⼤)的元素,与数组中的下⼀个元素交换位置,也就是放在已排序序列的末尾2.1算法描述1.初始状态:⽆序区为R[1..n],有序区为空2.第i躺排序开始时,当前有序区和⽆序区R[1..i-1]、R[i..n]3.n-1趟结束,数组有序化2.2动图演⽰2.3代码实现public static int[] selectionSort(int[] array) {if (array.length == 0)return array;for (int i = 0; i < array.length; i++) {int minIndex = i;for (int j = i; j < array.length; j++) {if (array[j] < array[minIndex]) //找到最⼩的数minIndex = j; //将最⼩数的索引保存}int temp = array[minIndex];array[minIndex] = array[i];array[i] = temp;}return array;}2.4算法分析最佳情况:T(n) = O(n2) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)3、插⼊排序是⼀种简单直观的排序算法,通过构建有序序列,对于未排序序列,在已排序序列中从后向前扫描,找到相应位置并插⼊,需要反复把已排序元素逐步向后挪位,为最新元素腾出插⼊空间3.1算法描述1.从第⼀个元素开始,该元素可以认为已经被排序2.取出下⼀个元素(h),在已排序的元素序列中从后往前扫描3.如果当前元素⼤于h,将当前元素移到下⼀位置4.重复步骤3,直到找到已排序的元素⼩于等于h的位置5.将h插⼊到该位置6.重复步骤2-53.2动图演⽰3.3代码实现public static int[] insertionSort(int[] array) {if (array.length == 0)return array;int current;for (int i = 0; i < array.length - 1; i++) {current = array[i + 1];int preIndex = i;while (preIndex >= 0 && current < array[preIndex]) {array[preIndex + 1] = array[preIndex];preIndex--;}array[preIndex + 1] = current;}return array;}3.4算法分析最佳情况:T(n) = O(n) 最坏情况:T(n) = O(n2) 平均情况:T(n) = O(n2)4、希尔排序是简单插⼊排序经过改进之后的⼀个更⾼效的版本,也称为缩⼩增量排序,同时该算法是冲破O(n2)的第⼀批算法之⼀。

计算机算法设计与分析课程设计文件

计算机算法设计与分析课程设计文件

成绩评定表学生姓名吴旭东班级学号1309010236分治法解决棋盘覆专业信息与计算课程设计题目盖问题;回溯法解科学决数字拆分问题评语组长签字:成绩日期20 年月日课程设计任务书学院理学院专业信息与计算科学学生姓名吴旭东班级学号1309010236课程设计题目分治法解决棋盘覆盖问题;回溯法解决数字拆分问题实践教学要求与任务:要求:1.巩固和加深对基本算法的理解和运用,提高综合运用课程知识进行算法设计与分析的能力。

2.培养学生自学参考书籍,查阅手册、和文献资料的能力。

3.通过实际课程设计,掌握利用分治法或动态规划算法,回溯法或分支限界法等方法的算法的基本思想,并能运用这些方法设计算法并编写程序解决实际问题。

4.了解与课程有关的知识,能正确解释和分析实验结果。

任务:按照算法设计方法和原理,设计算法,编写程序并分析结果,完成如下内容:1. 运用分治算法求解排序问题。

2. 运用回溯算法求解N 后问题。

工作计划与进度安排:第12 周:查阅资料。

掌握算法设计思想,进行算法设计。

第13 周:算法实现,调试程序并进行结果分析。

撰写课程设计报告,验收与答辩。

指导教师:专业负责人:学院教学副院长:201 年月日201 年月日201 年月日算法分析是对一个算法需要多少计作定量的分析。

算法和存储空间算时间问题成解一确定类的任意一种特,可以把算法定义(Algorithm)是解题的步骤算殊的方法。

在计算机科学中,算法要用计算机算法语言描述,算法代表用计的精确、有效的方法。

机解一类问题题分成两个或更多分治法字面上的解释是“分而治之”,就是把一个复杂的问题⋯⋯直到最后子问题可以题分成更小的子问,再把子问的相同或相似的子问题的直接求解,原问题的解即子问题的解的合并。

在一个2^k*2^k 的棋盘上,简单。

为特殊棋盘恰有一个放歌与其他方格不同,且称该棋盘回溯法的基本做法是深度优先搜索,是一种组织得井井有条的、能避免不多个整数必要重复搜索的穷举式搜索算法。

各种经典排序算法

各种经典排序算法

希尔插入排序——过程
设待排序共有10个记录,其关键字分别为47, 33, 61, 82, 71,
11, 25, 47, 57, 02,增量序列取值依次为5, 3, 1。
排 序
希尔插入排序——特点
希尔排序实质上还是一种插入排序,其主要特点是: 每一趟以不同的增量进行排序。在每趟的插入排序中,记录 的关键字是和同一组中的前一个关键字进行比较,所以关键
排 序
3、排序的基本操作
排序的概念:就是要整理文件中的记录,使之按关键字 递增(或递减)次序排列起来。
排序过程的组成步骤:首先比较两个关键字的大小; 然 后将记录从一个位置移动到另一个位置。 对记录的关键字大小进行比较 将记录从一个位置移动到另一个位置 当待排序记录的关键字均不相同时,则排序结果是唯一 的,否则排序的结果不一定唯一。
3.将L.r[i] 插入到L.r[j+1]的位臵上。
具体方法:先将第一个数据看成是一个有序的子序列, 然后从第2个数据起逐个插入到这个有序的子序列中去, 相应的元素要移动。
排 序
例:
待排元素序列:[53] 第一次排序: 第二次排序: 第三次排序: 第四次排序: 第五次排序: [27 [27 [15 [15 [15 27 53] 36 27 27 27 36 36 53] 36 36 36 15 15 15 53] 53 42 69 69 69 69 69] 53 42 42 42 42 42 69] 对于有n个数 据元素的待排 序列,插入操 作要进行n-1 次
有序序列L.r[1..i-1]
L.r[i]
无序序列 L.r[i..n]
有序序列L.r[1..i]
无序序列 L.r[i+1..n]

各种排序方法总结

各种排序方法总结

选择排序、‎快速排序、‎希尔排序、‎堆排序不是‎稳定的排序‎算法,冒‎泡排序、插‎入排序、归‎并排序和基‎数排序是稳‎定的排序算‎法。

‎冒泡法‎:这‎是最原始,‎也是众所周‎知的最慢的‎算法了。

他‎的名字的由‎来因为它的‎工作看来象‎是冒泡:‎复杂度为‎O(n*n‎)。

当数据‎为正序,将‎不会有交换‎。

复杂度为‎O(0)。

‎直接插‎入排序:O‎(n*n)‎选择排‎序:O(n‎*n)‎快速排序:‎平均时间复‎杂度log‎2(n)*‎n,所有内‎部排序方法‎中最高好的‎,大多数情‎况下总是最‎好的。

‎归并排序:‎l og2(‎n)*n‎堆排序:‎l og2(‎n)*n‎希尔排序‎:算法的复‎杂度为n的‎1.2次幂‎‎这里我没‎有给出行为‎的分析,因‎为这个很简‎单,我们直‎接来分析算‎法:首‎先我们考虑‎最理想的情‎况1.‎数组的大小‎是2的幂,‎这样分下去‎始终可以被‎2整除。

假‎设为2的k‎次方,即k‎=log2‎(n)。

‎2.每次‎我们选择的‎值刚好是中‎间值,这样‎,数组才可‎以被等分。

‎第一层‎递归,循环‎n次,第二‎层循环2*‎(n/2)‎.....‎.所以‎共有n+2‎(n/2)‎+4(n/‎4)+..‎.+n*(‎n/n) ‎= n+n‎+n+..‎.+n=k‎*n=lo‎g2(n)‎*n所‎以算法复杂‎度为O(l‎o g2(n‎)*n) ‎其他的情‎况只会比这‎种情况差,‎最差的情况‎是每次选择‎到的mid‎d le都是‎最小值或最‎大值,那么‎他将变成交‎换法(由于‎使用了递归‎,情况更糟‎)。

但是你‎认为这种情‎况发生的几‎率有多大?‎?呵呵,你‎完全不必担‎心这个问题‎。

实践证明‎,大多数的‎情况,快速‎排序总是最‎好的。

‎如果你担心‎这个问题,‎你可以使用‎堆排序,这‎是一种稳定‎的O(lo‎g2(n)‎*n)算法‎,但是通常‎情况下速度‎要慢于快‎速排序(因‎为要重组堆‎)。

十大经典排序算法(动图演示)

十大经典排序算法(动图演示)

⼗⼤经典排序算法(动图演⽰)0、算法概述0.1 算法分类⼗种常见排序算法可以分为两⼤类:⽐较类排序:通过⽐较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为⾮线性时间⽐较类排序。

⾮⽐较类排序:不通过⽐较来决定元素间的相对次序,它可以突破基于⽐较排序的时间下界,以线性时间运⾏,因此也称为线性时间⾮⽐较类排序。

0.2 算法复杂度0.3 相关概念稳定:如果a原本在b前⾯,⽽a=b,排序之后a仍然在b的前⾯。

不稳定:如果a原本在b的前⾯,⽽a=b,排序之后 a 可能会出现在 b 的后⾯。

时间复杂度:对排序数据的总的操作次数。

反映当n变化时,操作次数呈现什么规律。

空间复杂度:是指算法在计算机内执⾏时所需存储空间的度量,它也是数据规模n的函数。

1、冒泡排序(Bubble Sort)冒泡排序是⼀种简单的排序算法。

它重复地⾛访过要排序的数列,⼀次⽐较两个元素,如果它们的顺序错误就把它们交换过来。

⾛访数列的⼯作是重复地进⾏直到没有再需要交换,也就是说该数列已经排序完成。

这个算法的名字由来是因为越⼩的元素会经由交换慢慢“浮”到数列的顶端。

1.1 算法描述⽐较相邻的元素。

如果第⼀个⽐第⼆个⼤,就交换它们两个;对每⼀对相邻元素作同样的⼯作,从开始第⼀对到结尾的最后⼀对,这样在最后的元素应该会是最⼤的数;针对所有的元素重复以上的步骤,除了最后⼀个;重复步骤1~3,直到排序完成。

1.2 动图演⽰1.3 代码实现function bubbleSort(arr) {var len = arr.length;for (var i = 0; i < len - 1; i++) {for (var j = 0; j < len - 1 - i; j++) {if (arr[j] > arr[j+1]) { // 相邻元素两两对⽐var temp = arr[j+1]; // 元素交换arr[j+1] = arr[j];arr[j] = temp;}}}return arr;}2、选择排序(Selection Sort)选择排序(Selection-sort)是⼀种简单直观的排序算法。

七大基本排序算法

七大基本排序算法

一.七大排序算法基本属性1.稳定性KMP模糊匹配算法二叉树的建立顺序查找:哨兵设置二.七大排序算法()/jingmoxukong/p/4329079.html1.冒泡排序:冒泡排序是一种交换排序。

什么是交换排序呢?交换排序:两两比较待排序的关键字,并交换不满足次序要求的那对数,直到整个表都满足次序要求为止。

算法思想它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名。

假设有一个大小为N 的无序序列。

冒泡排序就是要每趟排序过程中通过两两比较,找到第i 个小(大)的元素,将其往上排。

图-冒泡排序示例图以上图为例,演示一下冒泡排序的实际流程:假设有一个无序序列{ 4. 3. 1. 2, 5 }第一趟排序:通过两两比较,找到第一小的数值1 ,将其放在序列的第一位。

第二趟排序:通过两两比较,找到第二小的数值2 ,将其放在序列的第二位。

第三趟排序:通过两两比较,找到第三小的数值3 ,将其放在序列的第三位。

至此,所有元素已经有序,排序结束。

要将以上流程转化为代码,我们需要像机器一样去思考,不然编译器可看不懂。

假设要对一个大小为N 的无序序列进行升序排序(即从小到大)。

(1) 每趟排序过程中需要通过比较找到第i 个小的元素。

所以,我们需要一个外部循环,从数组首端(下标0) 开始,一直扫描到倒数第二个元素(即下标N - 2) ,剩下最后一个元素,必然为最大。

(2) 假设是第i 趟排序,可知,前i-1 个元素已经有序。

现在要找第i 个元素,只需从数组末端开始,扫描到第i 个元素,将它们两两比较即可。

所以,需要一个内部循环,从数组末端开始(下标N - 1),扫描到(下标i + 1)。

核心代码public void bubbleSort(int[] list) {int temp = 0; // 用来交换的临时数// 要遍历的次数for (int i = 0; i < list.length - 1; i++) {// 从后向前依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上for (int j = list.length - 1; j > i; j--) {// 比较相邻的元素,如果前面的数大于后面的数,则交换if (list[j - 1] > list[j]) {temp = list[j - 1];list[j - 1] = list[j];list[j] = temp;}}}}时间复杂度若文件的初始状态是正序的,一趟扫描即可完成排序。

世界十大经典算法

世界十大经典算法

世界十大经典算法世界十大经典算法算法是计算机科学中非常重要的概念,它是一种解决问题的方法和步骤的描述。

以下是世界上广泛应用且被业界认可的十大经典算法: 1. 二分查找算法(Binary Search Algorithm):在有序数组中查找目标元素的算法。

通过将目标元素与数组中间元素进行比较,可以将搜索范围缩小一半,从而提高搜索效率。

2. 快速排序算法(Quick Sort Algorithm):一种基于分治法的排序算法。

它通过选择一个基准元素,将数组分为两个子数组,其中一个子数组的元素都小于等于基准元素,另一个子数组的元素都大于等于基准元素,然后递归地对子数组进行排序。

3. 归并排序算法(Merge Sort Algorithm):一种基于分治法的排序算法。

它将数组分成两个子数组,然后递归地对子数组进行排序,并将排序好的子数组合并成一个有序的数组。

4. 广度优先搜索算法(Breadth-First Search Algorithm):用于图遍历的一种算法。

它从图的某个顶点开始,逐层遍历其邻接顶点,直到遍历完所有顶点。

广度优先搜索常用于寻找最短路径或解决迷宫等问题。

5. 深度优先搜索算法(Depth-First Search Algorithm):用于图遍历的一种算法。

它从图的某个顶点开始,沿着一条路径一直向下遍历,直到无法继续为止,然后回溯到上一个没有遍历完的邻接顶点,继续遍历其他路径。

深度优先搜索常用于生成迷宫、图的连通性问题等。

6. Dijkstra算法(Dijkstra's Algorithm):用于求解单源最短路径问题的一种算法。

它根据权重赋值给每条边,计算出从源节点到其他节点的最短路径。

7. 动态规划算法(Dynamic Programming Algorithm):一种基于分治法的优化算法。

动态规划在问题可分解为重叠子问题时,通过保存子问题的解,避免重复计算,从而提高算法效率。

常见排序算法归纳总结

常见排序算法归纳总结

常见排序算法归纳总结排序算法是计算机科学中的重要基础知识,通过对一组数据进行排序,可以快速查找、统计和比较数据。

常见的排序算法包括冒泡排序、选择排序、插入排序、归并排序、快速排序等等。

本文将对这些常见排序算法进行归纳总结,以便读者更好地理解和应用这些算法。

一、冒泡排序(Bubble Sort)冒泡排序是一种简单直观的排序算法。

它的基本思想是重复地遍历要排序的序列,每次比较相邻的元素,如果顺序不对则交换它们。

经过一轮遍历,最大(或最小)的元素就会移动到序列的末尾,然后再对剩下的元素进行排序,直到整个序列有序。

冒泡排序的时间复杂度为O(n^2),其中n为要排序的元素数量。

虽然冒泡排序算法简单,但是对于大规模数据的排序效率较低,通常用于教学和简单的排序场景。

二、选择排序(Selection Sort)选择排序是一种简单但低效的排序算法。

它的基本思想是在序列中找到最小(或最大)的元素,将其放到序列的起始位置,然后再在剩下的元素中寻找最小(或最大)的元素,放到已排序的子序列的末尾。

重复进行这个过程,直到整个序列有序。

选择排序的时间复杂度也为O(n^2),它的交换次数较冒泡排序要少,因此在一些特殊场景下,选择排序可能会比冒泡排序稍微高效一些。

三、插入排序(Insertion Sort)插入排序是一种简单且稳定的排序算法。

它的基本思想是将待排序的序列分为两部分,一部分是已排序的序列,另一部分是未排序的序列。

每次从未排序的序列中取出一个元素,插入到已排序的序列中的合适位置,直到所有元素都插入完毕。

插入排序的时间复杂度也为O(n^2),但是在某些特定情况下,插入排序的性能要优于冒泡排序和选择排序。

例如,当序列几乎有序时,插入排序的时间复杂度可以接近O(n)。

四、归并排序(Merge Sort)归并排序是一种高效的排序算法,它基于分治的思想。

它的基本思路是将待排序的序列一分为二,对每个子序列进行排序,然后将排好序的子序列合并,最终得到完全有序的序列。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
换。 2.这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就
“沉”到数组第N-1个位置。 3.N=N-1,如果N不为0就重复前面二步,否则排序完成。
按照定义很容易写出代码: //冒泡排序1 void BubbleSort1(int a[], int n) {
int i, j;
for (i = 0; i < n; i++) for (j = 1; j < n - i; j++) if (a[j - 1] > a[j]) Swap(a[j - 1], a[j]);
int j, k; int flag;
flag = n; while (flag > 0) {
k = flag; flag = 0; for (j = 1; j < k; j++)
if (a[j - 1] > a[j]) {
Swap(a[j - 1], a[j]); flag = j; } } } 冒泡排序毕竟是一种效率低下的排序方法,在数据规模很小时,可以采用。数据 规模比较大时,最好用其它排序方法。
for (gap = n / 2; gap > 0; gap /= 2) for (j = gap; j < n; j++) //从数组第gap个元素开始 if (a[j] < a[j - gap]) //每个元素与自己组内的数据进行直接插入排序 { int temp = a[j]; int k = j - gap; while (k >= 0 && a[k] > temp) { a[k + gap] = a[k]; k -= gap; } a[k + gap] = temp; }
下面给出严格按照定义书写的代码(由小到大排序): void Insertsort1(int a[], int n) {
int i, j, k; for (i = 1; i < n; i++) {
//为a[i]在前面的a[0...i-1]有序区间中找一个合适的位置 for (j = i - 1; j >= 0; j--)
{ int temp = a[i]; for (j = i - 1; j >= 0 && a[j] > temp; j--) a[j + 1] = a[j]; a[j + 1] = temp;
} } 再对将a[j]插入到前面a[0…j-1]的有序区间所用的方法进行改写,用数据交换代 替数据后移。如果a[j]前一个数据a[j-1] > a[j],就交换a[j]和a[j-1],再j--直到a[j-1] <= a[j]。这样也可以实现将一个新数据新并入到有序区间。 //直接插入排序 // By MoreWindows (/MoreWindows) void Insertsort3(int a[], int n) {
二.白话经典算法系列之二 直接插入排序的三种实现
直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关 键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成 为止。
设数组为 a[0…n-1]。 1. 初始时,a[0]自成 1 个有序区,无序区为 a[1..n-1]。令 i=1 2. 将 a[i]并入当前的有序区 a[0…i-1]中形成 a[0…i]的有序区间。 3. i++并重复第二步直到 i==n-1。排序完成。
以 n=10 的一个数组 49, 38, 65, 97, 26, 13, 27, 49, 55, 4 为例
第一次 gap = 10 / 2 = 5
49 38 65 97 26 13 27 49 55 4
1A
1B
2A
2B
3A
3B
4A
4B
5A
5B
1A,1B,2A,2B 等为分组标记,数字相同的表示在同一组,大写字母表示是该组的第几个元
素, 每次对同一组的数据进行直接插入排序。即分成了五组(49, 13) (38, 27) (65, 49) (97, 55)
(26, 4)这样每组排序后就变成了(13, 49) (27, 38) (49, 65) (55, 97) (4, 26),下同。
第二次 gap = 5 / 2 = 2
排序后
13 27 49 55 4 49 38 65 97 26
1A 2A
1B
1C
1D
1E
2B
2C
2D
2E
第三次 gap = 2 / 2 = 1
4 26 13 27 38 49 49 55 97 65
1A 1B
1C 1D 1E
1F
1G 1H
1I
1J
第四次 gap = 1 / 2 = 0 排序完成得到数组:
4 13 26 27 38 49 49 55 65 97
下面给出严格按照定义来写的希尔排序 void shellsort1(int a[], int n)
{ int i, j, gap;
for (gap = n / 2; gap > 0; gap /= 2) //步长
for (i = 0; i < gap; i++)
//按组排序
{
for (j = i + gap; j < n; j += gap)
{
if (a[j] < a[j - gap])
{
int temp = a[j];
flag = false; for (j = 1; j < k; j++)
if (a[j - 1] > a[j]) {
Swap(a[j - 1], a[j]); flag = true; } k--; } }
再做进一步的优化。如果有100个数的数组,仅前面10个无序,后面90个都已排 好序且都大于前面10个数字,那么在第一趟遍历后,最后发生交换的位置必定小 于10,且这个位置之后的数据必定已经有序了,记录下这位置,第二次只要从数 组头部遍历到这个位置就可以了。 //冒泡排序3 // By MoreWindows (/MoreWindows) void BubbleSort3(int a[], int n) {
} 这样代码就变得非常简洁了。
附注:上面希尔排序的步长选择都是从 n/2 开始,每次再减半,直到最后为 1。 其实也可以有另外的更高效的步长选择,如果读者有兴趣了解,请参阅维基百科 上对希尔排序步长的说明: /wiki/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8 F
int i, j, gap;
for (gap = n / 2; gap > 0; gap /= 2) for (i = gap; i < n; i++) for (j = i - gap; j >= 0 && a[j] > a[j + gap]; j -= gap) Swap(a[j], a[j + gap]);
四.白话经典算法系列之四 直接选择排序
直接选择排序和直接插入排序类似,都将数据分为有序区和无序区,所不同的是 直接插入排序是将无序区的第一个元素直接插入到有序区以形成一个更大的有 序区,而直接选择排序是从无序区选一个最小的元素直接放到有序区的最后。
设数组为 a[0…n-1]。 4. 初始时,数组全为无序区为 a[0..n-1]。令 i=0 5. 在无序区 a[i…n-1]中选取一个最小的元素,将其与 a[i]交换。交换之后 a[0…i]
if (a[j] < a[i]) break;
//如找到了一个合适的位置 if (j != i - 1) {
//将比a[i]大的数据向后移 int temp = a[i]; for (k = i - 1; k > j; k--)
a[k + 1] = a[k]; //将a[i]放到正确位置上 a[k + 1] = temp; } } } 这样的代码太长了,不够清晰。现在进行一下改写,将搜索和数据后移这二个步 骤合并。即每次a[i]先和前面一个数据a[i-1]比较,如果a[i] > a[i-1]说明a[0…i]也 是有序的,无须调整。否则就令j=i-1,temp=a[i]。然后一边将数据a[j]向后移动一 边向前搜索,当有数据a[j]<a[i]时停止并将temp放到a[j + 1]处。 void Insertsort2(int a[], int n) { int i, j; for (i = 1; i < n; i++) if (a[i] < a[i - 1])
} 下面对其进行优化,设置一个标志,如果这一趟发生了交换,则为true,否则为 false。明显如果有一趟没有发生交换,说明排序已经完成。 //冒泡排序2 void BubbleSort2(int a[], int n) {
int j, k; bool flag;
k = n; flag = true; while (flag) {
MoreWindows 白话经典算法之七大排序
这是本人在研一上课时所整理的文档,包括冒泡排序,直接 插入排序,直接选择排序,希尔排序,归并排序,快速排序和堆 排序这七种常用的排序方法,这些文章不仅使我在考试中取了不 错的成绩,也为后来顺利面过迅雷,腾讯,微软打下了良好的基 础,现在整理成电子书形式,希望能对大家有所帮助。
int k = j - gap;
while (k >= 0 && a[k] > temp)
{
a[k + gap] = a[k];
相关文档
最新文档