算法快速排序法

Posted 数据库SQL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法快速排序法相关的知识,希望对你有一定的参考价值。

Algorithm Gossip: 快速排序法 ( )
说明快速排序法 (quick sort) 是目前所公认最快的排序方法之一 ( 视解题的对象而定 ) , 虽然
2
快速排序法在最差状况下可以达 O(n ), 但是在多数的情况下 , 快速排序法的效率表现是相当不
错的。
快速排序法的基本精神是在数列中找出适当的轴心 , 然后将数列一分为二 , 分别对左边与右边
数列进行排序 , 而影响快速排序法效率的正是轴心的选择。
这边所介绍的第一个快速排序法版本 , 是在多数的教科书上所提及的版本 , 因为它最容易理解 ,
也最符合轴心分割与左右进行排序的概念 , 适合对初学者进行讲解。
解法这边所介绍的快速演算如下 : 将最左边的数设定为轴 , 并记录其值为 s
廻圈处理 :
令索引 i 从数列左方往右方找 , 直到找到大于 s 的数
令索引 j 从数列左右方往左方找 , 直到找到小于 s 的数
如果 i >= j, 则离开回圈
如果 i < j, 则交换索引 i j 两处的值
将左侧的轴与 j 进行交换
对轴左边进行递回
对轴右边进行递回
透过以下演算法 , 则轴左边的值都会小于 s, 轴右边的值都会大于 s, 如此再对轴左右两边进行
递回 , 就可以对完成排序的目的 , 例如下面的实例 ,* 表示要交换的数 ,[] 表示轴 :
[41] 24 76* 11 45 64 21 69 19 36*
[41] 24 36 11 45* 64 21 69 19* 76
[41] 24 36 11 19 64* 21* 69 45 76
[41] 24 36 11 19 21 64 69 45 76
21 24 36 11 19 [41] 64 69 45 76
在上面的例子中 ,41 左边的值都比它小 , 而右边的值都比它大 , 如此左右再进行递回至排序完
成。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SWAP(x,y) {int t; t = x; x = y; y = t;}
void quicksort(int[], int, int);
int main(void) {
int number[MAX] = {0};
int i, num;
srand(time(NULL));
printf("
排序前 :");
for(i = 0; i < MAX; i++) {
number[i] =rand() % 100;
printf("%d ", number[i]);
}
quicksort(number, 0, MAX-1);
printf("\n
排序后 :");
for(i = 0; i < MAX; i++)
printf("%d ", number[i]);
printf("\n");
return 0;
}
void quicksort(int number[], int left, int right) {
int i, j, s;
if(left < right) {
s =number[left];
i = left;
j = right +1;
while(1) {
//
向右找
while(i + 1 < number.length && number[++i] < s) ;
//
向左找
while(j -1 > -1 && number[--j] > s) ;
if(i >= j)
break;
SWAP(number[i], number[j]);
}
number[left] = number[j];
number[j] = s;
quicksort(number, left, j-1);//
对左边进行递回
quicksort(number, j+1, right);//
对右边进行递回
}
}
Algorithm Gossip:
快速排序法 ( )
说明在快速排序法 ( ) , 每次将最左边的元素设为轴 , 而之前曾经说过 , 快速排序法的
加速在于轴的选择 , 在这个例子中 , 只将轴设定为中间的元素 , 依这个元素作基准进行比较 ,
这可以增加快速排序法的效率。
解法在这个例子中 , 取中间的元素 s 作比较 , 同样的先得右找比 s 大的索引 i, 然后找比 s 小的
索引 j, 只要两边的索引还没有交会 , 就交换 i j 的元素值 , 这次不用再进行轴的交换了 ,
因为在寻找交换的过程中 , 轴位置的元素也会参与交换的动作 , 例如 :
41 24 76 11 45 64 21 69 19 36
首先 left 0,right 9,(left+right)/2 = 4( 取整数的商 ) , 所以轴为索引 4 的位置 , 比较的元素是
45,
您往右找比 45 大的 , 往左找比 45 小的进行交换 :
41 24 76* 11 [45] 64 21 69 19 *36
41 24 36 11 45* 64 21 69 19* 76
41 24 36 11 19 64* 21* 69 45 76
[41 24 36 11 19 21] [64 69 45 76]
完成以上之后 , 再初别对左边括号与右边括号的部份进行递回 , 如此就可以完成排序的目的。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SWAP(x,y) {int t; t = x; x = y; y = t;}
void quicksort(int[], int, int);
int main(void) {
int number[MAX] = {0};
int i, num;
srand(time(NULL));
printf("
排序前 :");
for(i = 0; i < MAX; i++) {
number[i] =rand() % 100;
printf("%d ", number[i]);
}
quicksort(number, 0, MAX-1);
printf("\n
排序后 :");
for(i = 0; i < MAX; i++)
printf("%d ", number[i]);
printf("\n");
return 0;
}
void quicksort(int number[], int left, int right) {
int i, j, s;
if(left < right) {
s =number[(left+right)/2];
i = left -1;
j = right +1;
while(1) {
while(number[++i] < s) ; //
向右找
while(number[--j] > s) ; //
向左找
if(i >= j)
break;
SWAP(number[i], number[j]);
}
quicksort(number, left, i-1); //
对左边进行递回
quicksort(number, j+1, right); //
对右边进行递回
}
}
Algorithm Gossip:
快速排序法 ( )
说明
之前说过轴的选择是快速排序法的效率关键之一 , 在这边的快速排序法的轴选择方式更加快了
快速排序法的效率 , 它是来自演算法名书 Introduction to Algorithms 之中。
解法
先说明这个快速排序法的概念 , 它以最右边的值 s 作比较的标准 , 将整个数列分为三个部份 ,
一个是小于 s 的部份 , 一个是大于 s 的部份 , 一个是未处理的部份 , 如下所示 :
在排序的过程中 ,i j 都会不断的往右进行比较与交换 , 最后数列会变为以下的状态 :
然后将 s 的值置于中间 , 接下来就以相同的步骤会左右两边的数列进行排序的动作 , 如下所示 :
整个演算的过程 , 直接摘录书中的虚拟码来作说明 :
QUICKSORT(A, p, r)
if p < r
then q <-PARTITION(A, p, r)
QUICKSORT(A, p, q-1)
QUICKSORT(A, q+1, r)
end QUICKSORT
PARTITION(A, p, r)
x <- A[r]
i <- p-1
for j <- p to r-1
do ifA[j] <= x
then i <- i+1
exchange A[i]<->A[j]
exchange A[i+1]<->A[r]
return i+1
end PARTITION
一个实际例子的演算如下所示 :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
#define SWAP(x,y) {int t; t = x; x = y; y = t;}
int partition(int[], int, int);
void quicksort(int[], int, int);
int main(void) {
int number[MAX] = {0};
int i, num;
srand(time(NULL));
printf("
排序前 :");
for(i = 0; i < MAX; i++) {
number[i] = rand() % 100;
printf("%d ", number[i]);
}
quicksort(number, 0, MAX-1);
printf("\n
排序后 :");
for(i = 0; i < MAX; i++)
printf("%d ", number[i]);
printf("\n");
return 0;
}
int partition(int number[], int left, int right) {
int i, j, s;
s = number[right];
i = left - 1;
for(j = left; j < right; j++) {
if(number[j] <= s) {
i++;
SWAP(number[i], number[j]);
}
}
SWAP(number[i+1], number[right]);
return i+1;
}
void quicksort(int number[], int left, int right) {
int q;
if(left < right) {
q =partition(number, left, right);
quicksort(number, left, q-1);
quicksort(number, q+1, right);
}
}

以上是关于算法快速排序法的主要内容,如果未能解决你的问题,请参考以下文章

排序算法之JAVA终极快速排序法

算法 之 快速排序法

重温基础算法内部排序之快速排序法

重温基础算法内部排序之快速排序法

php四种基础算法:冒泡,选择,插入和快速排序法

双路快速排序法