霍尔快排的C语言实现

专题的前一篇讲了快速排序的始祖——霍尔快排,那么这里就简单地实现一下霍尔快排。

补充说明下,快排的一个核心步骤是选取枢纽元,通常的做法是将第一个元素用作枢纽元,《算法导论》里的快排例子和Hoare快排都是这种枢纽元选择。先撇开效率不说,我们先看看Hoare快排的实现:香格里拉娱乐城

01 #include "stdio.h"
02 #include "math.h"
03 #include "stdlib.h"
04  
05 int num = 10;
06  
07 void PrintArray(int arr[])
08 {
09     int i;
10     for(i=0; i < num; ++i)
11     {
12         printf("%d ", arr[i]);
13     }
14 }
15  
16 //一趟快排之后,以枢纽为分隔,左边的<=枢纽, 右边的>=枢纽
17 int Partition(int *arr, int beg, int end)
18 {
19     int low = beg, high = end;
20     //选定枢轴
21     int sentinel = arr[beg];
22     while(low < high)
23     {
24         //printf("\n    定点取arr[%d]的值,设为 sentinel(%d)", low, sentinel );
25         //printf("\n    比sentinel(%d)大的都丢到右边", sentinel);
26         //比枢纽小的交换到低端
27         while(low < high && arr[high]>=sentinel)
28         {
29             //printf("\n    arr[%d](%d) >= sentinel(%d)", high, arr[high], sentinel);
30             --high;
31             //printf(". high自减为%d, 此时 arr[high] 为 %d", high, arr[high]);
32         }
33         arr[low] = arr[high];
34         //printf("\n    赋值-> arr[low](arr[%d]) = arr[high](arr[%d]) = %d", low, high, arr[low]);
35         //printf("\n    比sentinel(%d)小的都丢到左边", sentinel);
36         //比枢纽大的交换到高端
37         while(low < high && arr[low]<=sentinel)
38         {
39  
40             //printf("\n    arr[%d](%d) <= sentinel(%d)", low, arr[low], sentinel);
41             ++low;
42             //printf(". low自增为%d, 此时 arr[low] 为 %d", low, arr[low]);
43         }
44         arr[high] = arr[low];
45         //printf("\n    赋值-> arr[high](arr[%d]) = arr[low](arr[%d]) = %d", high, low, arr[high]);
46     }
47     arr[low] = sentinel;
48  
49     printf("\n排序过程:");
50     PrintArray(arr);
51     return low;
52 }
53  
54 void QuickSort(int *arr, int beg, int end)
55 {
56     if(beg < end)
57     {
58         int pivot = Partition(arr, beg, end);
59         //分治思想,递归排序
60         QuickSort(arr, beg, pivot-1);
61         QuickSort(arr, pivot+1, end);
62     }
63 }
64  
65 int main()
66 {
67     int i;
68     int arr[10];
69  
70     srand(time(0));
71     for(i=0; i < 10; i++)
72     {
73         arr[i] = rand()%100+1;
74         //printf("%d ", rand()%100+1);
75     }
76     printf("初始数组:");
77     PrintArray(arr);
78  
79     QuickSort(arr, 0, num-1);
80  
81     printf("\n最后结果:");
82     PrintArray(arr);
83  
84     return 0;
85 }

程序运行结果为:

1 初始数组:80 16 97 6 12 92 31 52 54 89
2 排序过程: [ 54 16 52 6 12 31 ] 80 [ 92 97 89 ]
3 排序过程:[ 31 16 52 6 12 ] 54 [ 80 92 97 89 ]
4 排序过程:[ 12 16 6 ] 31 [ 52 54 80 92 97 89 ]
5 排序过程:[ 6 ] 12 [ 16 31 52 54 80 92 97 89 ])
6 排序过程:[ 6 12 16 31 52 54 80 89 ] 92 [ 97 ]
7 最后结果:6 12 16 31 52 54 80 89 92 97
8 Process returned 0 (0x0)   execution time : 0.384 s
9 Press any key to continue.

排序的思路是,选定一个枢纽元,比枢纽元大的全部丢到右边,比枢纽元小的全部丢到左边,可以看看下图:

霍尔快排的思路清晰了吧?

前面提到了,《算法导论》里的快排例子和Hoare快排都是将第一个元素用作枢纽元的排序,当然也有其它选择法,后面会介绍到。

时间: 2024-12-16 21:45:42

霍尔快排的C语言实现的相关文章

快排C语言实现

快速排序也是典型的分治策略实现,与归并排序不同,快排的关键部分在于 分 也就是partition部分,快排平均时间复杂度是O(nlgn),最差时间是O(n^2),属于不稳定排序 下面是快排的C语言实现. //p, r分别是数组中元素的下标 int partition(int A[], int p, int r) { int i, j; i = p - 1; for(j = p; j < r; j++) { if (A[j] <= A[r]) { swap(&A[++i], &A

快排 快速排序 qsort quicksort C语言

现在网上搜到的快排和我以前打的不太一样,感觉有点复杂,我用的快排是FreePascal里/demo/text/qsort.pp的风格,感觉特别简洁. 1 #include<stdio.h> 2 #define MAXN 10000 3 int a[MAXN]; 4 int n; 5 void Mysort(int l, int r) { 6 int x,y,mid,t; 7 mid = a[(l+r)/2]; 8 x=l; 9 y=r; 10 do { 11 while(a[x]<mid

C语言实现单向链表及其各种排序(含快排,选择,插入,冒泡)

#include<stdio.h> #include<malloc.h> #define LEN sizeof(struct Student) struct Student //结构体声明 { long num; int score; struct Student* next; }; int n; struct Student* creat() //创建单向链表 { struct Student *head=NULL, *p_before, *p_later; p_before =

快速排序—三路快排 vs 双基准

快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Java 7发布两年后)快速排序实现的Arrays.sort被双基准(dual-pivot)排序的一种变体取代了.这篇文章不仅展示了为什么这个变化如此优秀,而且让我们看到Jon Bentley和Joshua Bloch的谦逊. 我当时做了什么? 与所有人一样,我想实现这个算法并且对一千万个数值排序(随机

poj 2804 词典 (字典树 或者 快排+二分)

2804:词典 总时间限制:  3000ms  内存限制:  65536kB 描述 你旅游到了一个国外的城市.那里的人们说的外国语言你不能理解.不过幸运的是,你有一本词典可以帮助你. 输入 首先输入一个词典,词典中包含不超过100000个词条,每个词条占据一行.每一个词条包括一个英文单词和一个外语单词,两个单词之间用一个空格隔开.而且在词典中不会有某个外语单词出现超过两次.词典之后是一个空行,然后给出一个由外语单词组成的文档,文档不超过100000行,而且每行只包括一个外语单词.输入中出现单词只

常见经典排序算法学习总结,附算法原理及实现代码(插入、shell、冒泡、选择、归并、快排等)

博主在学习过程中深感基础的重要,经典排序算法是数据结构与算法学习过程中重要的一环,这里对笔试面试最常涉及到的7种排序算法(包括插入排序.希尔排序.选择排序.冒泡排序.快速排序.堆排序.归并排序)进行了详解.每一种算法都有基本介绍.算法原理分析.算法代码. 转载请注明出处:http://blog.csdn.net/lsh_2013/article/details/47280135 插入排序 1)算法简介 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过

快速排序--QuickSort,看完五分彩开奖网平台搭建自己就能写出来的快排思路推演

快速五分彩开奖网平台搭建论坛:haozbbs.com Q1446595067排序(QuickSort)介绍首先发明者竟然敢给自己发明的算法叫做QuickSort,这个名字闪不闪亮?好比别的武功叫做六脉神剑.降龙十八掌,我这个叫做"天下无敌神功".别的排序算法都是按照特点来起的,你这个不是应该叫分块递归排序法吗?或者和希尔一样,叫做霍尔排序也可以啊,这么高调是要干啥啊?我给了他一次机会,特意去查了一下,这个名字并不是江湖朋友抬爱给的,就是发明者自己起的,社会社会...不过看完这篇博客,理

四中基本排序算法几Java实现(冒泡、选择、插入、快排)

1.1 冒泡排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉.冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序

gogo闯SEO快排教程及应用编程(同步官方)

https://www.zygx8.com/thread-11604-1-1.html 授课内容简介: 两个模块:「SEO套路」和「SEO应用编程」 「SEO套路」模块,分 "域名.内容&模板.关键词.链接.点击" 五个章节,所有的SEO动作都是从这5个点中入手 多一些思路和实战,即:经过分析,出于前提条件X(思路),对网站做Y这个动作(实战),可以大概率提升排名&流量.其中实战部分,大站和灰色站的套路居多 「SEO应用编程」模块,分"基础.SEO数据分析.快