快速排序、堆排序和归并排序的实现

    1、快速排序

    通过选择轴值,一次划分都能确定该轴值得位置,其时间复杂度最好的情况(每次划分都恰好将区间平分为等长的两半)下为Ο(nlgn),最差情况(每次划分将区间分成0与n-1)为O(n^2)。其空间复杂度考虑递归的栈深为O(lgn)。


 1 /*************************************************************************
2 **File Name :quicksort.c
3 **Author :
4 **Contact :
5 **Created Time :Mon 12 May 2014 02:12:57 PM CST
6 **Brief :
7 **Development note :
8 ************************************************************************/
9
10 /********************************include*********************************/
11 #include<stdio.h>
12
13 int partition(int a[],int start,int end)
14 {
15 int i,j,tmp;
16 i = start;
17 j = end;
18 while(i < j){
19 while(a[i] < a[j] && i < j){
20 j--;
21 }
22 if(i < j){
23 tmp = a[i];
24 a[i] = a[j];
25 a[j] = tmp;
26 i++;
27 }
28 while(a[i] < a[j] && i < j){
29 i++;
30 }
31 if(i < j){
32 tmp = a[i];
33 a[i] = a[j];
34 a[j] = tmp;
35 j--;
36 }
37 }
38 return i;
39 }
40 int quicksort(int a[],int start,int end)
41 {
42 if(start >= end)
43 return 0;
44 int mid;
45 mid = partition(a,start,end);
46 quicksort(a,start,mid-1);
47 quicksort(a,mid+1,end);
48 }

    2、堆排序

    堆排序通过堆顶的对换和堆的不断调整实现。其时间复杂度为O(nlgn),与初始序列无关。


 1 /*************************************************************************
2 **File Name :heapsort.c
3 **Author :
4 **Contact :[email protected]
5 **Created Time :Mon 12 May 2014 02:40:23 PM CST
6 **Brief :
7 **Development note :
8 ************************************************************************/
9 /*
10 *澶ф牴鍫*鏁扮粍浠寮€濮*/
11 /********************************include*********************************/
12 #include<stdio.h>
13 void sift(int a[],int k,int m)
14 {
15 int i = 2*k,tmp;
16 /*
17 * 璋冩暣浜唅 = 2*i鐨勪綅缃紝鏀惧埌寰幆鐨勬渶鍚庛€傚惁鍒欏嚭閿欍€ * */
18 while(i <= m){
19 if(a[i] < a[i+1]&& i+1 <= m)
20 i = i+1;
21 if(a[i] > a[k]){
22 a[0] = a[i];
23 a[i] = a[k];
24 a[k] = a[0];
25 k = i;
26 i = 2*i;
27 }
28 else
29 break;
30 }
31 }
32 void heapsort(int a[],int m)
33 {
34 int i,tmp,j=0;
35 for(i = m/2; i > 0; i--){
36 sift(a,i,m);
37 }
38 for(i = 1;i < m; i++){
39 a[0] = a[1];
40 a[1] = a[m-i+1];
41 a[m-i+1] = a[0];
42 sift(a,1,m-i);
43 }
44 }

    3、归并排序

    归并的思想在于,每次合并两个相邻的一排序的序列,多次归并实现排序。其时间复杂度为O(nlgn)与初始序列无关,空间复杂度为O(n) 。


 1 /*************************************************************************
2 **File Name :mergesort.c
3 **Author :Shi Xuyong
4 **Contact :[email protected]
5 **Created Time :Mon 12 May 2014 08:23:27 PM CST
6 **Brief :
7 **Development note :
8 ************************************************************************/
9
10 /********************************include*********************************/
11 #include<stdio.h>
12 /*
13 */
14 void merge(int a[],int b[],int s,int m,int t)
15 {
16 int i,j,k;
17 i = s;
18 j = m+1;
19 k = i;
20 while(i <= m && j <= t){
21 if(a[i] < a[j]){
22 b[k++] = a[i++];
23 }
24 else{
25 b[k++] = a[j++];
26 }
27 }
28 if(j <= t){
29 while(j <= t ){
30 b[k++] = a[j++];
31 }
32 }
33 else{
34 while(i <= m){
35 b[k++] = a[i++];
36 }
37 }
38 }
39 void mergepass(int a[],int b[],int n,int h)
40 {
41 int i = 1;
42 while(i <= n-2*h+1){
43 merge(a,b,i,i+h-1,i+2*h-1);
44 i = i+2*h;
45 }
46 if(i < n-h+1)
47 merge(a,b,i,i+h-1,n);
48 else{
49 int k;
50 for(k = i; k<=n; k++)
51 b[k] = a[k];
52 }
53 }
54 void mergesort(int a[],int b[],int n)
55 {
56 int h = 1;
57 while(h < n){
58 mergepass(a,b,n,h);
59 h = h*2;
60 mergepass(b,a,n,h);
61 h = h*2;
62 }
63 }

上述三种算法只有归并排序是稳定的,其余两个都不稳定。

堆排序用在筛选数组中最大(小)的K个数,快速排序用在查找数组的第K大(小)数。归并排序性能相对较好。

时间: 2024-10-15 04:27:04

快速排序、堆排序和归并排序的实现的相关文章

插入排序 | 冒泡排序 | 希尔排序 | 堆排序 | 快速排序 | 选择排序 | 归并排序

以下是最近学习各种算法的代码实现: #include <stdlib.h> #include <stdio.h> #include <time.h> #include <limits.h> typedef int EleType; typedef int (*CompFunc)(void *,void *); int IntComp(void * a,void *b) { if(*(int *)a > *(int *)b) return 1; if(*

快速排序、堆排序、归并排序比较

快速排序是二叉查找树(二叉查找树)的一个空间最优化版本.不是循序地把数据项插入到一个明确的树中,而是由快速排序组织这些数据项到一个由递归调用所隐含的树中.这两个算法完全地产生相同的比较次数,但是顺序不同.对于排序算法的稳定性指标,原地分区版本的快速排序算法是不稳定的.其他变种是可以通过牺牲性能和空间来维护稳定性的. 快速排序的最直接竞争者是堆排序(Heapsort).堆排序通常比快速排序稍微慢,但是最坏情况的运行时间总是O(n log n).快速排序是经常比较快,除了introsort变化版本外

C# 插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序

下面列出了数据结构与算法的八种基本排序:插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序,然后是测试的例子.代码位置:http://download.csdn.net/detail/luozuolincool/8040027 排序类: public class Sortings { //插入排序 public void insertSort(int[] array) { int temp = 0; int index = 0; for (int i = 0; i <

插入排序,希尔排序,堆排序,归并排序,快速排序Java实现

参看:数据结构与算法分析-c语言描述 public class Main { public static void main(String[] args) { String[] a = { "a", "d", "e", "f", "m" }; String[] b = { "a", "h", "g", "l", "z&

Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。

Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法.插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素).在第一部分排序完成后,再将这

常用的较优排序之快速排序,堆排序,归并排序

1.快速排序 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序.可以用递归和非递归的方法分别实现. int _QuickSort(int* a,int left,int right,int key) { while (left < right) { while (left < right&&a[left] <=a[key]) { left++; //找出比a[key]大的下标 }

8大排序算法---我熟知3(归并排序/快速排序/堆排序)

排序算法: 快排: o(nlogn) o(1)不稳定 归并:o(nlogn) o(n) 稳定 基数: 冒泡 睡眠 面条 烙饼 1.quicksort: 返回条件:start >=end private = a[start]+a[end]/2 while(left <= right) while(left <= right && a[left] < privot) while(left <= right && a[right] > priv

算法基础--快排序,堆排序,归并排序

这是笔记; 快速排序的思想:先说一趟划分:一个数组a[0...(length-1)],把数组的第一个元素当作枢轴v(是vlaue,不是下标),将数组中所有比k小的元素都移动到k的左侧,将所有比v大的元素都移动到元素的右边. 我们需要得到一个数组划分后,枢轴v现在的位置下标(这是下一步进行划分的边界); 长度为n的数组,平均需要log(n)次划分. 代码实现: 1 ///quick sort 2 void quick_sort(int a[],int s,int t){//这是算法的开始,我们看到

排序之选择排序、堆排序、归并排序、高速排序

本学习笔记内容部分来自网易云课堂浙江大学数据结构视频,及海子的博客:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html以及~大器晚成~的博客http://www.cnblogs.com/luchen927/archive/2012/02/29/2368070.html 1.选择排序 基本思想:在一个长度为N的无序数组中.在第一趟遍历N个数据,找出当中最小的数值与第一个元素交换,第二趟遍历剩下的N-1个数据,找出当中