C++ 八种排序算法总结及实现
C语言数组的五种简单排序,选择法排序,冒泡法排序、交换法排序、插入法排序、折半法排序
C语⾔数组的五种简单排序,选择法排序,冒泡法排序、交换法排序、插⼊法排序、折半法排序⽂章⽬录1、选择法排序选择法排序是指每次选择索要排序的数组中的最⼩值(这⾥是由⼩到⼤排序,如果是由⼤到⼩排序则需要选择最⼤值)的数组元素,将这些数组元素的值与前⾯没有进⾏排序的数组元素值进⾏互换代码实现需要注意的是:声明⼀个数组和两个整形变量,数组⽤于存储输⼊的数字,⽽整形变量⽤于存储最⼩的数组元素的数值与该元素的位置,在我的代码中实现为a[] temp position。
代码具体如下#include<stdio.h>int main(){int m,n,k;printf("please input the length of the array:");scanf("%d",&k);int a[k];int temp;int position;printf("please input the number of the array:\n");for(m=0;m<k;m++){printf("a[%d]=",m+1);scanf("%d",&a[m]);}/*从⼩到⼤排序*/for(m=0;m<k-1;m++){temp=a[m]; //设置当前的值为最⼩值position=m; //记录当前的位置for(n=m+1;n<k;n++){if(a[n]<temp){temp=a[n]; //如果找到⽐当前的还要⼩的数值,则更换最⼩的数值与位置position=n;}}a[position]=a[m];a[m]=temp;}for(m=0;m<k;m++){printf("%d\t",a[m]);}return 0;}结果如下2、冒泡法排序冒泡法排序就是值在排序时,每次⽐较数组中相邻的两个数组元素的值,将⽐较⼩的(从⼩到⼤排序算法,如果是从⼤到⼩排序算法就是将较⼤的数排在较⼩的数前⾯)排在⽐较⼤的前⾯在代码实现的过程中:声明⼀个数组与⼀个整型变量,数组⽤于存放数据元素,整型变量⽤于交换时作为中间变量。
C语言--常见排序算法
49
2 j 49
08
0
25* 3 49 25
16 4
21
5
08
25
25*
16
21
i k 49
j 25* 25
08
25
25*
16
21
算法实例:
1.1.5 选择排序
49 2
08 0
25 1 i
25* 3
16 4 k
21 5 j 21 16
k 指示当前序列中最小者
算法实现:
08 5 temp
16 21 25 25* 49 08 0 1 2 3 4 5
算法实现:
1.1.3 直接插入排序
void InsertSort (int r[ ], int n ) { // 假设关键字为整型,放在向量r[]中 int i, j, temp; for (i = 1;i< n;i++ ) { temp = r[i]; for(j = i;j>0;j- -) {//从后向前顺序比较,并依次后移 if ( temp < r[j-1] ) r[j] = r[j-1]; else break; } r[j] = temp; } }
输入n 个数给a[1] 到 a[n]
for j=1 to n-1
for i=1 to n-j
真 a[i]>a[i+1]
a[i]a[i+1]
输出a[1] 到 a[n]
main() { int a[11],i,j,t; printf("Input 10 numbers:\n"); for(i=1;i<11;i++) scanf("%d",&a[i]); printf("\n"); 假 for(j=1;j<=9;j++) for(i=1;i<=10-j;i++) if(a[i]>a[i+1]) {t=a[i]; a[i]=a[i+1]; a[i+1]=t;} printf("The sorted numbers:\n"); for(i=1;i<11;i++) printf("%d ",a[i]); }
c语言中排序的各种方法解析
c语言中排序的各种方法解析一、引言在计算机编程中,排序是一个重要的操作,它按照一定的顺序排列数据元素,使得数据元素按照从小到大的顺序排列。
在C语言中,有多种方法可以实现排序,包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。
这些排序算法都有各自的优缺点,适合不同的应用场景。
二、冒泡排序冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
算法步骤:1. 比较相邻的元素。
如果第一个比第二个大(升序),就交换它们两个。
2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
这步做完后,最后的元素会是最大的数。
3. 针对所有的元素重复以上的步骤,除了最后一个。
4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
三、选择排序选择排序是一种简单直观的排序算法。
它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
算法步骤:1. 在未排序序列中找到最小元素,存放到排序序列的起始位置。
2. 再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。
3. 以此类推,直到所有元素均排序完毕。
四、插入排序插入排序的工作方式是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序在实现上通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
五、快速排序快速排序使用了分治的原则,它在每一层划分都比前面方法有所改进和精进,当切分到两边的子序列长度都大于某个值时,或者一个大于一个小于这个值时再进行交换的操作来结束此层的递归过程。
这层的结果又成为下一层的两个子数组来处理,最后就得到递归式的最终结果。
排列组合c的算法
排列组合c的算法排列组合是组合数学中的经典概念,也是计算机科学中常用的算法之一。
在算法设计中,排列组合算法可以用于解决很多实际问题,比如密码破解、图形排列等。
本文将介绍排列组合的基本概念和常见的算法。
排列是指从给定的n个元素中,按照一定顺序选取k个元素的方式。
对于有序的排列,我们可以使用递归或者循环的方法来实现。
递归方法可以通过以下步骤来完成:1. 若k=0,则返回一个空列表。
2. 若k=1,则将n个元素依次加入列表中,并返回。
3. 若k>1,则从n个元素中选取第一个元素,然后递归地选取剩下的n-1个元素中的k-1个,将两部分结果合并。
以下是一个使用递归方法实现排列的伪代码:```function permute(list, k):if k = 0:return []if k = 1:return [[x] for x in list]result = []for i in range(len(list)):rest = permute(list[:i] + list[i+1:], k-1)for p in rest:result.append([list[i]] + p)return result```循环方法可以通过以下步骤来完成:1. 创建一个二维数组result,用于存储所有的排列结果。
2. 创建一个长度为n的布尔类型的数组used,用于标记元素是否已经被选取。
3. 创建一个列表p,用于存储当前的排列。
4. 使用循环遍历数组中的每一个元素,对于每个元素,检查是否已经被选取。
5. 如果元素已经被选取,则跳过该元素。
6. 如果元素未被选取,则将其加入当前的排列p中,并标记元素为已选取。
7. 如果k=1(即已选取了k个元素),则将当前排列加入结果result中。
8. 否则,递归地调用自身,进入下一层递归。
9. 在递归返回后,将当前元素标记为未选取,将其从排列p中移除,以便进行下一个元素的选择。
C语言常用算法总结
C语言常用算法总结1、冒泡排序算法:冒泡排序是一种简单的排序算法,它重复地遍历要排序的序列,一次比较两个相邻的元素如果他们的顺序错误就把他们交换过来。
时间复杂度为O(n^2)。
2、快速排序算法:快速排序是一种基于分治的排序算法,通过递归的方式将数组划分为两个子数组,然后对子数组进行排序最后将排好序的子数组合并起来。
时间复杂度为O(nlogn)。
3、插入排序算法:插入排序是一种简单直观的排序算法,通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描找到相应位置并插入。
时间复杂度为O(n^2)。
4、选择排序算法:选择排序是一种简单的排序算法,每次循环选择未排序部分的最小元素,并放置在已排序部分的末尾。
时间复杂度为O(n^2)。
5、归并排序算法:归并排序是一种稳定的排序算法,基于分治思想,将数组递归地分为两个子数组,将子数组排序后再进行合并最终得到有序的数组。
时间复杂度为O(nlogn)。
6、堆排序算法:堆排序是一种基于完全二叉堆的排序算法,通过构建最大堆或最小堆,然后依次将堆顶元素与末尾元素交换再调整堆,得到有序的数组。
时间复杂度为O(nlogn)。
7、二分查找算法:二分查找是一种在有序数组中查找目标元素的算法,每次将待查找范围缩小一半,直到找到目标元素或范围为空。
时间复杂度为O(logn)。
8、KMP算法:KMP算法是一种字符串匹配算法,通过利用模式字符串的自重复性,避免不必要的比较提高匹配效率。
时间复杂度为O(m+n),其中m为文本串长度,n为模式串长度。
9、动态规划算法:动态规划是一种通过将问题分解为子问题,并通过组合子问题的解来求解原问题的方法。
动态规划算法通常使用内存空间来存储中间结果,从而避免重复计算。
时间复杂度取决于问题规模。
10、贪心算法:贪心算法是一种通过选择局部最优解来构建全局最优解的算法并以此构建最终解。
时间复杂度取决于问题规模。
11、最短路径算法:最短路径算法用于求解图中两个节点之间的最短路径,常见的算法包括Dijkstra算法和Floyd-Warshall算法。
使用C语言实现12种排序方法
使⽤C语⾔实现12种排序⽅法⽬录1.冒泡排序2.插⼊排序3.折半插⼊排序4.希尔排序5.选择排序6.鸡尾酒排序7.堆排序8.快速排序9.归并排序10.计数排序11.桶排序12.基数排序1.冒泡排序思路:⽐较相邻的两个数字,如果前⼀个数字⼤,那么就交换两个数字,直到有序。
时间复杂度O(n^2),稳定性:这是⼀种稳定的算法。
代码实现:void bubble_sort(int arr[],size_t len){size_t i,j;for(i=0;i<len;i++){bool hasSwap = false; //优化,判断数组是否已经有序,如果有序可以提前退出循环for(j=1;j<len-i;j++){ //这⾥j<len-i是因为最后⾯的肯定都是最⼤的,不需要多进⾏⽐较if(arr[j-1]>arr[j]){ //如果前⼀个⽐后⼀个⼤swap(&arr[j-1],&arr[j]); //交换两个数据hasSwap = true;}}if(!hasSwap){break;}}}2.插⼊排序思路:把⼀个数字插⼊⼀个有序的序列中,使之仍然保持有序,如对于需要我们进⾏排序的数组,我们可以使它的前i个数字有序,然后再插⼊i+1个数字,插⼊到合适的位置使之仍然保持有序,直到所有的数字有序。
时间复杂度:O(n^2) 稳定性:稳定的算法代码实现:void insert_sort(int arr[],int len){int i,j;for(i=1;i<len;i++){int key = arr[i]; //记录当前需要插⼊的数据for(j= i-1;i>=0&&arr[j]>key;j--){ //找到插⼊的位置arr[j+1] = arr[j]; //把需要插⼊的元素后⾯的元素往后移}arr[j+1] = key; //插⼊该元素}}3.折半插⼊排序思路:本质上是插⼊排序,但是通过半分查找法找到插⼊的位置,让效率稍微快⼀点。
C语言八大排序算法
C语⾔⼋⼤排序算法C语⾔⼋⼤排序算法,附动图和详细代码解释!来源:C语⾔与程序设计、⽵⾬听闲等⼀前⾔如果说各种编程语⾔是程序员的招式,那么数据结构和算法就相当于程序员的内功。
想写出精炼、优秀的代码,不通过不断的锤炼,是很难做到的。
⼆⼋⼤排序算法排序算法作为数据结构的重要部分,系统地学习⼀下是很有必要的。
1、排序的概念排序是计算机内经常进⾏的⼀种操作,其⽬的是将⼀组“⽆序”的记录序列调整为“有序”的记录序列。
排序分为内部排序和外部排序。
若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。
反之,若参加排序的记录数量很⼤,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。
2、排序分类⼋⼤排序算法均属于内部排序。
如果按照策略来分类,⼤致可分为:交换排序、插⼊排序、选择排序、归并排序和基数排序。
如下图所⽰:3、算法分析1.插⼊排序*直接插⼊排序*希尔排序2.选择排序*简单选择排序*堆排序3.交换排序*冒泡排序*快速排序4.归并排序5.基数排序不稳定排序:简单选择排序,快速排序,希尔排序,堆排序稳定排序:冒泡排序,直接插⼊排序,归并排序,奇数排序1、插⼊排序将第⼀个和第⼆个元素排好序,然后将第3个元素插⼊到已经排好序的元素中,依次类推(插⼊排序最好的情况就是数组已经有序了)因为插⼊排序每次只能操作⼀个元素,效率低。
元素个数N,取奇数k=N/2,将下标差值为k的数分为⼀组(⼀组元素个数看总元素个数决定),在组内构成有序序列,再取k=k/2,将下标差值为k的数分为⼀组,构成有序序列,直到k=1,然后再进⾏直接插⼊排序。
3、简单选择排序选出最⼩的数和第⼀个数交换,再在剩余的数中⼜选择最⼩的和第⼆个数交换,依次类推4、堆排序以升序排序为例,利⽤⼩根堆的性质(堆顶元素最⼩)不断输出最⼩元素,直到堆中没有元素1.构建⼩根堆2.输出堆顶元素3.将堆低元素放⼀个到堆顶,再重新构造成⼩根堆,再输出堆顶元素,以此类推5、冒泡排序改进1:如果某次冒泡不存在数据交换,则说明已经排序好了,可以直接退出排序改进2:头尾进⾏冒泡,每次把最⼤的沉底,最⼩的浮上去,两边往中间靠16、快速排序选择⼀个基准元素,⽐基准元素⼩的放基准元素的前⾯,⽐基准元素⼤的放基准元素的后⾯,这种动作叫分区,每次分区都把⼀个数列分成了两部分,每次分区都使得⼀个数字有序,然后将基准元素前⾯部分和后⾯部分继续分区,⼀直分区直到分区的区间中只有⼀个元素的时候,⼀个元素的序列肯定是有序的嘛,所以最后⼀个升序的序列就完成啦。
c语言数字从大到小排列
c语言数字从大到小排列C语言数字从大到小排列C语言中,数字的排序是程序员需要掌握的计算机技能之一。
下面将介绍如何使用C语言编写程序来实现数字从大到小的排序。
I. 程序思路1. 输入需要排序的数字,将其存储在数组中;2. 从数组中选择一个数字作为基准点,将比基准点小的数字放在基准点左边,比基准点大的数字放在基准点右边;3. 对基准点左边和右边的数字重复第2步,直到所有数字都排列完成。
II. 编程实现1. 定义函数来实现数字排序:```void sort(int arr[], int left, int right){int i, j, pivot, temp;if (left < right) {pivot = left;i = left;j = right;while (i < j) {while (arr[i] >= arr[pivot] && i < right)i++;while (arr[j] < arr[pivot])j--;if (i < j) {temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}temp = arr[pivot];arr[pivot] = arr[j];arr[j] = temp;sort(arr, left, j - 1);sort(arr, j + 1, right);}}```2. 在主函数中输入需要排序的数字,并输出排序结果:```int main(){int arr[100], i, n;printf("请输入数字的个数:");scanf("%d", &n);for (i = 0; i < n; i++) {printf("请输入第 %d 个数字:", i + 1);scanf("%d", &arr[i]);}sort(arr, 0, n - 1);printf("数字按从大到小排列的结果:\n");for (i = 0; i < n; i++)printf("%d ", arr[i]);return 0;}```在上述代码中,sort函数使用快速排序算法实现数字从大到小的排列。
C语言中的算法实现
C语言中的算法实现算法是计算机科学中非常重要的概念,它是解决问题的一系列步骤或指令集。
在C语言中,我们可以使用不同的方法来实现算法。
本文将介绍一些常见的C语言算法实现方式。
一、排序算法1. 冒泡排序冒泡排序是一种简单但效率较低的排序算法。
它通过不断比较相邻的元素,并按照规则交换它们的位置,直到整个序列排序完成。
2. 选择排序选择排序是一种简单而直观的排序算法。
它每次从未排序的序列中选择最小(或最大)的元素,并将其放置在已排序序列的末尾。
3. 插入排序插入排序是一种简单且高效的排序算法。
它通过构建有序序列,对未排序的元素逐个插入到已排序的序列中,直到所有元素都被插入完成。
二、查找算法1. 顺序查找顺序查找是一种简单的查找算法。
它从列表的开头开始逐个比较元素,直到找到目标元素或查找完整个列表。
2. 二分查找二分查找是一种高效的查找算法,但要求列表必须是有序的。
它通过将待查找区域分成两部分,判断目标元素落在哪一部分,从而缩小查找范围,直到找到目标元素或确定不存在。
三、递归算法递归是一种常用的算法设计技巧。
它通过在函数内调用自身来解决相同问题的不同实例。
在C语言中,递归函数需要定义出口条件,以避免无限递归。
四、动态规划算法动态规划是一种用于解决具有重叠子问题和最优子结构性质的问题的方法。
它将问题分解为一系列子问题,并以自底向上的方式求解子问题,最终得到整体问题的解。
在C语言中,可以使用循环、数组和指针等特性来实现动态规划算法,从而有效地解决问题。
五、图算法图是一种用于描述对象之间关系的数据结构,图算法是解决图相关问题的一类算法。
常见的图算法包括深度优先搜索(DFS)和广度优先搜索(BFS)。
六、字符串算法字符串算法用于处理字符串相关的问题,如字符串匹配、编辑距离等。
C语言提供了一系列字符串处理函数,如strlen、strcpy等,可以方便地实现字符串算法。
七、数学算法C语言在数学算法方面提供了丰富的库函数支持,如求平方根、对数、指数等。
C语言奇偶排序算法详解及实例代码
C语言奇偶排序算法详解及实例代码奇偶排序(Odd-Even Sort)算法是一种简单的排序算法,它可以同时对数组中的奇数和偶数进行排序。
这个算法的原理比较简单,它的思想类似冒泡排序,只不过比较的对象从相邻的两个数变为了相隔一个位置的两个数。
奇偶排序算法的步骤如下:1.将数组分为两个部分,分别存放奇数和偶数。
2.在奇数部分中进行一轮冒泡排序,将较大的数往右移。
3.在偶数部分中进行一轮冒泡排序,将较小的数往左移。
4.重复执行步骤2和步骤3,直到数组完全有序。
下面我们来详细解析奇偶排序算法,并给出一个实例代码。
1. 定义一个函数 `void oddEvenSort(int arr[], int n)`,用于实现奇偶排序。
2. 在函数内部创建两个变量 `sorted` 和 `exchange`,分别表示数组是否已经完全有序和两个相邻元素是否发生交换。
3. 使用一个循环,首先将 `sorted` 和 `exchange` 初始化为`false`。
4. 使用两个嵌套循环,外层循环控制数组两个部分的排序,内层循环控制每个部分的冒泡排序。
5. 内层循环的初始条件为 `j = i % 2`,其中 `i` 表示当前循环的次数。
当 `i` 为偶数时,`j` 为 0,表示要对偶数部分排序;当`i` 为奇数时,`j` 为 1,表示要对奇数部分排序。
6. 内层循环用于对数组中的一部分进行冒泡排序,如果发生交换,则将 `exchange` 设置为 `true`。
冒泡排序的过程和一般的冒泡排序算法类似。
7. 当内层循环结束后,判断 `exchange` 是否为 `false`,如果是,则说明数组已经完全有序,将 `sorted` 设置为 `true`,并退出外层循环。
8. 最后,在函数末尾添加一个循环,用于输出排序后的数组。
下面是完整的实例代码:```c#include <stdio.h>void swap(int *a, int *b){int temp = *a;*a = *b;*b = temp;}void oddEvenSort(int arr[], int n)int sorted = 0; // 数组是否已经完全有序int exchange = 0; // 两个相邻元素是否发生交换 while (!sorted){sorted = 1;for (int i = 0; i < n - 1; i++){exchange = 0;int j = i % 2;for (; j < n - 1; j += 2){if (arr[j] > arr[j + 1]){swap(&arr[j], &arr[j + 1]);exchange = 1;sorted = 0;}}if (!exchange){break;}}}}int main(){int arr[] = {9, 2, 7, 4, 5, 6, 3, 8, 1};int n = sizeof(arr) / sizeof(arr[0]);oddEvenSort(arr, n);for (int i = 0; i < n; i++){printf("%d ", arr[i]);}return 0;}```以上是奇偶排序算法的详细解析及一个示例代码。
C语言常用算法大全
C语言常用算法大全1.排序算法-冒泡排序:依次比较相邻的两个元素,如果顺序不对则交换,每轮找出一个最大或最小的元素-选择排序:从未排序的元素中选择最小或最大的放到已排序的最后,以此类推-插入排序:将未排序的元素插入到已排序的合适位置,从后向前进行比较和交换-快速排序:选择一个基准元素,将小于基准元素的放在左边,大于基准元素的放在右边,然后对左右两边递归地进行快速排序-归并排序:将待排序的序列不断划分为左右两部分,分别排序后再将排序好的左右两部分按顺序合并-堆排序:构建大顶堆,将堆顶元素与末尾元素交换,然后重新调整堆,重复这个过程直到排序完成2.查找算法-顺序查找:从给定的元素序列中逐个比较,直到找到目标元素或遍历完整个序列-二分查找:对于有序序列,在序列的中间位置比较目标元素和中间元素的大小关系,通过每次缩小一半的范围来查找目标元素-插值查找:根据目标元素与有序序列的最小值和最大值的比例推测目标元素所在的位置,然后递归地进行查找-斐波那契查找:根据斐波那契数列的性质来确定目标元素所在的位置,然后递归地进行查找3.图算法-深度优先(DFS):从图的一些顶点出发,依次访问其未被访问过的邻接顶点,直到所有顶点都被访问过为止-广度优先(BFS):从图的一些顶点出发,逐层遍历图的顶点,直到所有顶点都被访问过为止- 最小生成树算法:Prim算法和Kruskal算法,用于找到连接图中所有顶点的最小权值边,构成一棵包含所有顶点的生成树- 最短路径算法:Dijkstra算法和Floyd-Warshall算法,用于找到图中两个顶点之间的最短路径-拓扑排序:用于有向无环图(DAG)中的顶点排序,确保排序后的顶点满足所有依赖关系-关键路径算法:找出网络中的关键路径,即使整个工程完成的最短时间4.字符串算法- KMP算法:通过预处理模式串构建next数组,利用next数组在匹配过程中跳过一部分不可能匹配的子串- Boyer-Moore算法:从模式串的末尾开始匹配,利用坏字符和好后缀规则进行跳跃匹配- Rabin-Karp算法:利用哈希函数对主串和匹配串的子串进行哈希计算,然后比较哈希值是否相等- 字符串匹配算法:BM算法、Shift-And算法、Sunday算法等,用于寻找模式串在主串中的出现位置5.动态规划算法-最长公共子序列(LCS):用于寻找两个序列中最长的公共子序列-最长递增子序列(LIS):用于寻找给定序列中最长的递增子序列-0-1背包问题:将有限的物品放入容量为C的背包中,使得物品的总价值最大-最大子数组和:用于求解给定数组中连续子数组的最大和-最大正方形:在给定的0-1矩阵中,找出只包含1的最大正方形的边长这些算法是在C语言中常用的算法,它们涵盖了排序、查找、图、字符串和动态规划等多个领域。
排序算法实验报告
数据结构实验报告八种排序算法实验报告一、实验内容编写关于八种排序算法的C语言程序,要求包含直接插入排序、希尔排序、简单项选择择排序、堆排序、冒泡排序、快速排序、归并排序和基数排序。
二、实验步骤各种内部排序算法的比较:1.八种排序算法的复杂度分析〔时间与空间〕。
2.八种排序算法的C语言编程实现。
3.八种排序算法的比较,包括比较次数、移动次数。
三、稳定性,时间复杂度和空间复杂度分析比较时间复杂度函数的情况:时间复杂度函数O(n)的增长情况所以对n较大的排序记录。
一般的选择都是时间复杂度为O(nlog2n)的排序方法。
时间复杂度来说:(1)平方阶(O(n2))排序各类简单排序:直接插入、直接选择和冒泡排序;(2)线性对数阶(O(nlog2n))排序快速排序、堆排序和归并排序;(3)O(n1+§))排序,§是介于0和1之间的常数。
希尔排序(4)线性阶(O(n))排序基数排序,此外还有桶、箱排序。
说明:当原表有序或基本有序时,直接插入排序和冒泡排序将大大减少比较次数和移动记录的次数,时间复杂度可降至O〔n〕;而快速排序则相反,当原表基本有序时,将蜕化为冒泡排序,时间复杂度提高为O〔n2〕;原表是否有序,对简单项选择择排序、堆排序、归并排序和基数排序的时间复杂度影响不大。
稳定性:排序算法的稳定性:假设待排序的序列中,存在多个具有相同关键字的记录,经过排序,这些记录的相对次序保持不变,则称该算法是稳定的;假设经排序后,记录的相对次序发生了改变,则称该算法是不稳定的。
稳定性的好处:排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。
基数排序就是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的。
另外,如果排序算法稳定,可以防止多余的比较;稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序四、设计细节排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。
C语言超算法大全
C语言超算法大全1.快速排序算法:快速排序是一种高效的排序算法,基于分治法的思想。
它通过选择一个基准元素,将数组划分为两个子数组,其中一个子数组的所有元素小于基准元素,另一个子数组的所有元素大于基准元素。
然后递归地对两个子数组进行快速排序,最终得到排序后的数组。
2.归并排序算法:归并排序也是一种高效的排序算法,基于分治法的思想。
它将数组分为两个子数组,然后递归地对每个子数组进行归并排序,最后将两个有序的子数组合并成一个有序的数组。
3.堆排序算法:堆排序是一种树形选择排序算法,利用堆数据结构来实现。
它通过构建一个最大堆,将堆顶元素与最后一个元素交换,然后重新调整堆,重复这个过程,最终得到排序后的数组。
4.二分查找算法:二分查找算法是一种在有序数组中查找特定元素的算法。
它通过将待查找区间的中间元素与目标元素进行比较,根据比较结果调整区间范围,直到找到目标元素或区间为空。
5.图的深度优先算法:图的深度优先算法是一种用于遍历图的算法。
它从一个顶点开始,递归地访问所有与该顶点相连的未访问过的顶点,直到所有顶点都被访问过为止。
6.图的广度优先算法:图的广度优先算法也是一种用于遍历图的算法。
它从一个顶点开始,依次访问与该顶点相邻的顶点,并将这些相邻顶点加入到一个队列中,然后继续对队列中的顶点进行同样的操作,直到队列为空为止。
7.迪杰斯特拉算法:迪杰斯特拉算法是一种用于求解单源最短路径问题的算法。
它通过动态规划的方式,逐步更新起始顶点到其他顶点的最短路径长度。
8.动态规划算法:动态规划算法是一种用于解决多阶段决策问题的算法。
它通过将原问题划分为若干个子问题,并记忆已经解决的子问题的结果,从而避免重复计算,提高计算效率。
9.最小生成树算法:最小生成树算法是一种用于求解连通图的最小成本生成树的算法。
它通过选择具有最小权值的边来构建最小生成树,直到所有顶点都被包含在生成树中。
10.拓扑排序算法:拓扑排序算法是一种用于对有向无环图进行排序的算法。
c语言几种数组排序方法
常用的c语言排序算法主要有三种即冒泡法排序、选择法排序、插入法排序。
一、冒泡排序冒泡排序:是从第一个数开始,依次往后比较,在满足判断条件下进行交换。
代码实现(以降序排序为例)#include<stdio.h>int main(){int array[10] = { 6,9,7,8,5,3,4,0,1,2 };int temp;for (int i = 0; i < 10; i++){//循环次数for (int j = 0; j <10 - i-1; j++){if (array[j] < array[j+1]){//前面一个数比后面的数大时发生交换temp = array[j];array[j] = array[j+1];array[j + 1] = temp;}}} //打印数组for (int i = 0; i < 10; i++) printf("%2d", array[i]); return 0;}}二、选择排序以升序排序为例:就是在指定下标的数组元素往后(指定下标的元素往往是从第一个元素开始,然后依次往后),找出除指定下标元素外的值与指定元素进行对比,满足条件就进行交换。
与冒泡排序的区别可以理解为冒泡排序是相邻的两个值对比,而选择排序是遍历数组,找出数组元素与指定的数组元素进行对比。
(以升序为例)#include<stdio.h>int main(){int array[10] = { 6,9,7,8,5,3,4,0,1,2 };int temp, index;for (int i = 0; i < 9; i++) {index = i;for (int j = i; j < 10; j++){if (array[j] < array[index])index = j;}if(i != index){temp = array[i]; array[i] = array[index]; array[index] = temp; }for(int i=0;i<10:i++) printf("%2d"array[i])return 0;}三、快速排序是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
C语言经典算法大全精选
C语言经典算法大全精选1.排序算法1.1冒泡排序:通过不断交换相邻元素的位置,将最大(最小)值“冒泡”到序列的末尾(开头)。
1.2插入排序:将未排序的元素逐个插入已排序的序列中,保持序列始终有序。
1.3选择排序:每次从未排序的元素中选择最小(最大)的元素,放到已排序序列的末尾(开头)。
1.4快速排序:通过递归地将序列分割为较小和较大的两部分,然后分别对两部分进行排序。
1.5归并排序:将序列递归地分割为两个子序列,分别排序后再将结果合并。
1.6堆排序:构建最大(最小)堆,然后逐步将堆顶元素与最后一个元素交换,并调整堆结构。
2.查找算法2.1顺序查找:逐个比较元素,直到找到目标元素或遍历完整个序列。
2.2二分查找:在有序序列中,通过不断缩小查找范围,找到目标元素。
2.3插值查找:根据目标元素与序列中最大、最小元素的关系,按比例选择查找范围。
2.4哈希查找:利用哈希函数将目标元素映射到一个唯一的位置,从而快速定位目标元素。
3.字符串算法3.1字符串匹配算法:在文本串中查找给定的模式串,并返回匹配位置。
3.2字符串翻转:将一个字符串逆序输出。
3.3字符串压缩:将连续出现多次的字符压缩为一个字符,并输出压缩后的字符串。
3.4字符串拆分:按照指定的分隔符将字符串拆分为多个子串,并返回子串列表。
3.5字符串反转单词:将一个句子中的单词顺序逆序输出。
4.图算法4.1深度优先:从起始顶点出发,递归地访问所有能到达的未访问顶点。
4.2广度优先:从起始顶点出发,逐层地访问与当前层相邻的未访问顶点。
4.3最小生成树:找到连接所有顶点的具有最小权值的无环边集合。
4.4最短路径:找到两个顶点之间最短路径的权值和。
4.5拓扑排序:找到一个顶点的线性序列,满足所有有向边的起点在终点之前。
5.数学算法5.1质数判断:判断一个数是否为质数(只能被1和自身整除)。
5.2求最大公约数:找到两个数的最大公约数。
5.3求最小公倍数:找到两个数的最小公倍数。
c语言排序与查找代码
c语言排序与查找代码在程序设计中,排序和查找是非常常见的操作。
排序是将一组数据按照特定规则进行重新排列的过程,而查找则是在已经排列好的数据中寻找某个特定的元素。
C语言提供了丰富的函数和算法来实现这两个操作。
一、排序代码实现:C语言中有多种排序算法可以选择,其中最常见和经典的有冒泡排序、选择排序、插入排序和快速排序等。
1. 冒泡排序代码实现:冒泡排序是一种简单直观的排序算法,它通过不断交换相邻元素的位置,将较大的元素逐渐往后移动。
具体实现代码如下:```cvoid bubbleSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}```2. 选择排序代码实现:选择排序是一种简单的排序算法,它每次从待排序的数据中选出最小(或最大)的元素,放到已排序序列的末尾。
具体实现代码如下:```cvoid selectionSort(int arr[], int n) {int i, j, minIndex, temp;for (i = 0; i < n - 1; i++) {minIndex = i;for (j = i + 1; j < n; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}}```3. 插入排序代码实现:插入排序是一种简单直观的排序算法,它将待排序的数据分为已排序和未排序两部分,每次从未排序部分取出一个元素插入到已排序部分的适当位置。
c语言常见排序算法
常见的C语言排序算法有以下几种:
1. 冒泡排序(Bubble Sort):比较相邻的元素,如果前一个元素大于后一个元素,则交换它们的位置,重复这个过程直到整个序列有序。
2. 插入排序(Insertion Sort):将未排序的元素逐个插入到已排序序列中的正确位置,直到整个序列有序。
3. 选择排序(Selection Sort):每次从未排序的元素中选择最小的元素,将其放到已排序序列的末尾,重复这个过程直到整个序列有序。
4. 快速排序(Quick Sort):选择一个基准元素,将序列分成两部分,一部分小于等于基准元素,一部分大于基准元素,然后对两部分递归地进行快速排序。
5. 归并排序(Merge Sort):将序列分成两部分,分别对两部分进行归并排序,然后将两个有序的子序列合并成一个有序的序列。
6. 堆排序(Heap Sort):将序列构建成一个最大堆,然后将堆顶元素与堆末尾元素交换,重复这个过程直到整个序列有序。
7. 希尔排序(Shell Sort):将序列按照一定的间隔分成若干个子序列,对每个子序列进行插入排序,然后逐渐减小间隔直到间隔为1,最后对整个序列进行插入排序。
8. 计数排序(Counting Sort):统计序列中每个元素出现的次数,然后按照元素的大小顺序将它们放入一个新的序列中。
9. 基数排序(Radix Sort):按照元素的个位、十位、百位等依次进行排序,直到所有位数都排完为止。
以上是常见的C语言排序算法,每种算法都有其特点和适用场景,选择合适的排序算法可以提高排序效率。
C语言常见排序算法.ppt
1.1.2 快速排序
算法实例:
始关键字
pivotkey 21 25 low
49 25* 16 08 high
一次交换
21
二次交换
三次交换
high-1 完成一趟排序
08 25 low
49 25* 16
high
08
49 25* 16 25
low
high
08 16 49 25*
25
low
08 16
low
常见排序算法
1.1 常见的排序算法
冒泡排序 快速排序 直接插入排序 希尔排序 选择排序 堆排序 归并排序
1.1.1 冒泡排序
算法描述
设待排序记录序列中的记录个数为n 一般地,第i趟起泡排序从1到n-i+1 依次比较相邻两个记录的关键字,如果发生逆序,则交换之 其结果是这n-i+1个记录中,关键字最大的记录被交换到第n-i+1的位 置上,最多作n-1趟。
08 16
21
high 25* 49 25
high 25* 49 25
low high
1.1.2 快速排序
算法实例:
完成一趟排序
08 16
21 25* 49 25
分别进行快速排序 有序序列
08 16
21 25* 25 49
08 16
21 25* 25 49
11
1.1.2 快速排序
算法分析:
快速排序是一个递归过程; 利用序列第一个记录作为基准,将整个序列划分为左右两个子序列。只要 是关键字小于基准记录关键字的记录都移到序列左侧; 快速排序的趟数取决于递归树的高度。 如果每次划分对一个记录定位后, 该记录的左侧子序列与右侧子序列的长 度相同, 则下一步将是对两个长度减半的子序列进行排序, 这是最理想的情 况
c语言常见算法
c语言常见算法C语言是一种非常流行的编程语言,广泛应用于软件开发和计算机科学领域。
在C语言中,算法是解决问题的关键步骤。
本文将介绍一些常见的C语言算法,包括排序算法、搜索算法和递归算法。
一、排序算法1. 冒泡排序算法冒泡排序是一种简单的排序算法,它重复地遍历要排序的列表,比较相邻的两个元素,并交换它们的位置,直到整个列表排序完成。
2. 插入排序算法插入排序算法通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
3. 快速排序算法快速排序是一种高效的排序算法,它通过选择一个元素作为基准,将列表分为两部分,一部分小于基准,一部分大于基准,然后递归地对两部分进行排序。
二、搜索算法1. 线性搜索算法线性搜索算法逐个地检查列表中的元素,直到找到目标元素或者遍历完整个列表。
2. 二分搜索算法二分搜索算法适用于已排序的列表。
它通过比较目标元素和列表的中间元素,将列表分为两部分,然后在适当的部分继续搜索,直到找到目标元素或者确定目标元素不存在。
三、递归算法递归算法是一种自我调用的算法,它将问题分解成更小的子问题,然后在子问题上递归地调用自身,直到达到基本情况。
对于C语言中的算法来说,递归函数的编写非常重要。
需要确保递归的终止条件,并正确处理递归调用中传递的参数。
四、其他常见算法1. 图算法图算法是解决与图相关的问题的算法。
它可以解决最短路径问题、最小生成树问题等。
2. 动态规划算法动态规划算法是一种通过将问题分解成更小的子问题来解决复杂问题的算法。
它通常用于解决最优化问题。
3. 贪心算法贪心算法通过每一步选择当前最优解来构建问题的解决方案。
它通常不能保证找到全局最优解,但在某些情况下可以得到较好的近似解。
总结C语言常见算法涵盖了排序算法、搜索算法、递归算法以及其他常用的算法。
对于每个算法,我们都介绍了其基本原理和应用场景。
在实际编程中,根据具体的问题,选择合适的算法是非常重要的。
熟悉C语言中的常见算法,可以帮助程序员更好地解决问题,提高代码的效率与质量。
c语言的排序方法
c语言的排序方法C语言的排序方法排序是计算机科学中常见的操作,它的作用是将一组数据按照特定的规则进行重新排列。
在C语言中,有多种排序方法可以实现这个目标。
本文将介绍几种常见的排序算法,包括冒泡排序、插入排序、选择排序、快速排序和归并排序。
一、冒泡排序冒泡排序是一种简单但效率较低的排序算法。
它的基本思想是多次遍历待排序的数据,每次比较相邻的两个元素,如果它们的顺序不对就交换它们的位置。
通过多次遍历,最大(或最小)的元素会逐渐“冒泡”到最后。
二、插入排序插入排序是一种稳定且效率较高的排序算法。
它的基本思想是将待排序的数据分为已排序和未排序两部分,每次从未排序部分选择一个元素插入到已排序部分的正确位置。
通过多次插入操作,最终得到完全有序的数据。
三、选择排序选择排序是一种简单但效率较低的排序算法。
它的基本思想是每次从待排序的数据中选择最小(或最大)的元素,然后放到已排序部分的末尾。
通过多次选择操作,最终得到完全有序的数据。
四、快速排序快速排序是一种常用且高效的排序算法。
它的基本思想是通过递归地将待排序的数据分为两部分,一部分小于某个基准值,另一部分大于该基准值。
然后对这两部分分别进行快速排序,直到每个部分只有一个元素或为空。
最后将所有部分合并起来,即得到完全有序的数据。
五、归并排序归并排序是一种稳定且效率较高的排序算法。
它的基本思想是将待排序的数据分成若干个长度相等(或接近)的子序列,然后对每个子序列进行排序。
最后将排好序的子序列两两合并,直到所有子序列合并成一个有序的序列。
不同的排序算法适用于不同的场景。
冒泡排序和选择排序适用于数据量较小的情况,插入排序适用于数据基本有序的情况,快速排序适用于数据量较大且无序的情况,归并排序适用于数据量较大且需要稳定排序的情况。
在C语言中,实现这些排序算法并不复杂。
通过使用循环和条件语句,可以很容易地编写出排序的代码。
同时,为了提高排序算法的效率,还可以使用一些优化技巧,例如设置哨兵、使用递归等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
八种排序算法总结之C++版本五种简单排序算法一、冒泡排序【稳定的】void BubbleSort( int* a,int Count ) //实现从小到大的最终结果{int temp;for(int i=1; i<Count; i++) //外层每循环一次,将最小的一个移动到最前面for(int j=Count-1; j>=i; j--)if( a[j] < a[j-1] ){temp = a[j];a[j] = a[j-1];a[j-1] = temp;}}现在注意,我们给出O方法的定义:若存在一常量K和起点n0,使当n>=n0时,有f(n)<=K*g(n),则f(n) = O(g(n))。
(呵呵,不要说没学好数学呀,对于编程数学是非常重要的!!!)现在我们来看1/2*(n-1)*n,当K=1/2,n0=1,g(n)=n*n时,1/2*(n-1)*n<=1/2*n*n=K*g(n)。
所以f(n) =O(g(n))=O(n*n)。
所以我们程序循环的复杂度为O(n*n)。
二、交换排序【稳定的】void ExchangeSort( int *a,int Count){int temp;for(int i=0; i<Count-1; i++)for(int j=i+1; j<Count; j++)if( a[j] < a[i] ){temp = a[j];a[j] = a[i];a[i] = temp;}}时间复杂度为O(n*n)。
三、选择法【不稳定的】void SelectSort( int *a,int Count){int temp; //一个存储值int pos; //一个存储下标for(int i=0; i<Count; i++){temp = a[i];pos = i;for(int j=i+1; j<Count; j++)if( a[j] < temp ) //选择排序法就是用第一个元素与最小的元素交换{temp = a[j];pos = j; //下标的交换赋值,记录当前最小元素的下标位置}a[pos] = a[i];a[i] = temp;}}遗憾的是算法需要的循环次数依然是1/2*(n-1)*n。
所以算法复杂度为O(n*n)。
我们来看他的交换。
由于每次外层循环只产生一次交换(只有一个最小值)。
所以f(n)<=n 所以我们有f(n)=O(n)。
所以,在数据较乱的时候,可以减少一定的交换次数。
四、插入法【稳定的】void InsertSort( int *a,int Count){int temp; //一个存储值int pos; //一个存储下标for(int i=1; i<Count; i++) //最多做n-1趟插入{temp = a[i]; //当前要插入的元素pos = i-1;while( pos>=0 && temp<a[pos] ){a[pos+1] = a[pos]; //将前一个元素后移一位pos--;}a[pos+1] = temp;}}其复杂度仍为O(n*n)。
最终,我个人认为,在简单排序算法中,直接插入排序是最好的。
五、希尔排序法【不稳定的】/** 希尔排序,n为数组的个数*/void ShellSort( int arr[], int n ){int temp,pos;int d = n; //增量初值do{d = d/3 + 1 ;for(int i= d; i<n; i++ ){temp = arr[i];pos = i-d;while( pos>=0 && temp < arr[pos] ) { //实现增量为d的插入排序arr[ pos + d ] = arr[pos];pos -= d;}arr[ pos + d ] = temp;}} while( d > 1 );}三种高级排序算法一、快速排序辅助空间复杂度为O(1)【不稳定的】void QuickSort( int *a,int left, int right){int i,j,middle,temp;i = left;j = right;middle = a[ (left+right)/2 ];do{while( a[i]<middle && i<right ) //从左扫描大于中值的数i++;while( a[j]>middle && j>left ) //从右扫描小于中值的数j--;if( i<=j ) //找到了一对值{temp = a[i];a[i] = a[j];a[j] = temp;i++;j--;}} while ( i<j ); //如果两边的下标交错,就停止(完成一次)//当左半边有值(left<j),递归左半边if( left < j )QuickSort( a, left, j);//当右半边有值(right>i),递归右半边if( i < right )QuickSort( a, i, right);}它的工作看起来象一个二叉树。
首先我们选择一个中间值middle,程序中我们使用数组中间值,然后把比它小的放在左边,大的放在右边(具体的实现是从两边找,找到一对后交换)。
然后对两边分别使用这个过程(最容易的方法——递归)。
注意,由于数据的随机性,对middle的选择并不会影响该算法的效率。
注意,在扫描过程中,对于给定参考值,对于向右(左)扫描,如果扫描值大(小)于或等于参考值,就需要进行交换。
最终得到的结果是,j左边的值都小于参考值,而i右边的值都大于参考值,j和i之间的值都等于参考值。
对j左边和i右边的分别使用递归,就可以完成最终的排序。
这里我没有给出行为的分析,因为这个很简单,我们直接来分析算法:首先我们考虑最理想的情况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=log2(n)*n所以算法复杂度为O(log2(n)*n)其他的情况只会比这种情况差,最差的情况是每次选择到的middle都是最小值或最大值,那么他将变成交换法(由于使用了递归,情况更糟),但是糟糕的情况只会持续一个流程,到下一个流程的时候就很可能已经避开了该中间的最大和最小值,因为数组下标变化了,于是中间值不在是那个最大或者最小值。
但是你认为这种情况发生的几率有多大??呵呵,你完全不必担心这个问题。
实践证明,大多数的情况,快速排序总是最好的。
如果你担心这个问题,你可以使用堆排序,这是一种稳定的O(log2(n)*n)算法,但是通常情况下速度要慢于快速排序(因为要重组堆)。
二、归并排序(两种实现方法均要掌握)【稳定的】归并排序是一种极好的外部排序方法,即针对数据保存在磁盘上而不是高速内存中的问题。
//以下程序参考数据结构课本P286页的模板,为使用指针链表实现的#include<iostream>using namespace std;struct node{ //链表的节点数据int value;node *next;};node * divide_from( node * head ){node * position, * midpoint, * second_half;if( (midpoint=head) == NULL ) //List is emptyreturn NULL;position = midpoint->next;while( position != NULL ) //Move position twice for midpoint's one move {position = position->next;if( position != NULL ){midpoint = midpoint->next;position = position->next;}}second_half = midpoint->next;midpoint->next = NULL; //在这里将原链拆断,分为两段return second_half;}node * merge( node * first, node * second){node * last_sorted; //当前已经链接好的有序链中的最后一个节点node combined; //哑节点last_sorted = &combined;while( first!=NULL && second!=NULL ){if( first->value < second->value ) {last_sorted->next = first;last_sorted = first;first = first->next;}else {last_sorted->next = second;last_sorted = second;second = second->next;}}if( first==NULL )last_sorted->next = second;elselast_sorted->next = first;return combined.next; //返回哑节点的后继指针,即为合并后的链表的头指针}//这里的参数必须是引用调用,需要这个指引去允许函数修改调用自变量void MergeSort( node * &head){if( head != NULL && head->next != NULL ) //如果只有一个元素,则不需排序{node * second_half = divide_from( head );MergeSort( head );MergeSort( second_half );head = merge( head, second_half );}}int main(){node a,b,c,d;node *p1, *p2, *p3, *p4,*head;p1 = &a;p2 = &b;p3 = &c;p4 = &d;a.value = 2;b.value = 4;c.value = 3;d.value = 1;a.next = p2;b.next = p3;c.next = p4;d.next = NULL;//调用归并排序前的结果head = p1;while( head != NULL ){cout<<head->value<<" ";head = head->next;}cout<<endl;MergeSort( p1 );//调用归并排序后的结果head = p1;while( head != NULL ){cout<<head->value<<" ";head = head->next;}cout<<endl;}//以下程序为使用数组实现的归并排序,辅助空间复杂度为O(n)#include<iostream>using namespace std;void Merge( int data[], int left, int mid, int right ){int n1,n2,k,i,j;n1 = mid - left + 1;n2 = right - mid;int *L = new int[n1]; //两个指针指向两个动态数组的首地址int *R = new int[n2];for( i=0,k=left; i<n1; i++,k++)L[i] = data[k];for( i=0,k=mid+1; i<n2; i++,k++)R[i] = data[k];for( k=left,i=0,j=0; i<n1 && j<n2; k++) {if( L[i] < R[j] ) { //取小者放前面data[k] = L[i];i++;} else {data[k] = R[j];j++;}}if( i<n1 ) //左边的数组尚未取尽for( j=i; j < n1; j++,k++)data[k] = L[j];else//if( j<n2 ) //右边的数组尚未取尽 ,这句话可要可不要for( i=j; i<n2; i++,k++)data[k] = R[i];delete []L; //回收内存delete []R;}/** left:数组的开始下标,一般为0;right:数组的结束下标,一般为(n-1)*/void MergeSort( int data[], int left, int right ){if( left < right ){int mid = left + ( right-left ) / 2; //mid=(right+left)/2,防止溢出MergeSort( data, left, mid );MergeSort( data , mid+1, right );Merge( data , left, mid , right );}}int main(){int data[] = {9,8,7,2,5,6,3,55,1};//排序前的输出for(int i=0; i<9; i++)cout<<data[i]<<" ";cout<<endl;MergeSort( data, 0, 8);//排序后的输出for(int i=0; i<9; i++)cout<<data[i]<<" ";cout<<endl;}三、堆排序【不稳定的】/** 向堆中插入current元素的函数*/void insert_heap( int data[], const int ¤t, int low, int high )int large; //元素data[low]左右儿子中,大者的位置large = 2*low + 1;while( large <= high ) {if( large < high && data[large] < data[ large+1] )large++;if( current > data[ large ] ) //待插入元素的值比它的两个儿子都大break;else {data[ low ] = data[ large ]; //将其左右儿子的大者上移low = large;large = 2 * large + 1;}}data[ low ] = current;}/** 建立堆函数,num为数组data的元素个数* 只有一个结点的<2-树>自动满足堆的属性,因此不必担心树中的任何树叶,即* 不必担心表的后一半中的元素。