快速排序算法 quick sort 的描述
2009-10-12 10:59
239 查看
/* quick sort algorithm */
/* snallie@tom.com */
/* Wed Apr 2 10:57:01 HKT 2008 */
/*
快速排序是基于交换和分划的思想进行排序的一种排序算法,是bubble sort的一种改进算法.
以如下的示例进行说明
下标 01 02 03 04 05 06 07 08 09 10 11
原始 [00] 91 82 71 98 00 76 54 60 88 77 30
(01)
[91] 30 82 71 98 00 76 54 60 88 77 -1 [i=02,j=11]
[91] 30 82 71 -1 00 76 54 60 88 77 98 [i=04,j=11]
[91] 30 82 71 77 00 76 54 60 88 -1 98 [i=05,j=10]
[91] 30 82 71 77 00 76 54 60 88 -1 98 [i=10,j=10]
(02)
[30] 00 82 71 77 -1 76 54 60 88 91 98 [i=02,j=05]
[30] 00 -1 71 77 82 76 54 60 88 91 98 [i=02,j=05]
(03)
[71] 00 30 60 77 82 76 54 -1 88 91 98 [i=04,j=08]
[71] 00 30 60 -1 82 76 54 77 88 91 98 [i=04,j=08]
[71] 00 30 60 54 82 76 -1 77 88 91 98 [i=05,j=07]
[71] 00 30 60 54 -1 76 82 77 88 91 98 [i=05,j=07]
(04)
[60] 00 30 54 -1 71 76 82 77 88 91 98 [i=04,j=04]
[60] 00 30 54 -1 71 76 82 77 88 91 98 [i=04,j=04]
(05)
(06)
[82] 00 30 54 60 71 76 77 -1 88 91 98 [i=08,j=08]
[82] 00 30 54 60 71 76 77 -1 88 91 98 [i=08,j=08]
qsort result below:
[82] 00 30 54 60 71 76 77 82 88 91 98 最终排序的结果
前提:升序排序
一般地,所谓的分划操作即是,任意选取一个枢轴记录ai,(一般为方便起见,选取待排序序列
的首元素为枢轴记录ai), 将待排序的记录序列分划为两部分:前半部分A1和后半部分A2,使得
A1中的元素都小于(或小于等于)枢轴记录ai, 而位于后半部分A2的记录元素都大于枢轴记录ai,
此时已经基本有序,这一分划的过程主要进行的即是交换的操作。 在分划的过程中主要是采
取从两边向中央进行扫描的方法,(一般地,先从后向前扫描,而从前向后扫描,反复进行,
直到前向扫描和后向扫面的指针碰到一起,则结束),在扫描的过程中,逐渐将小于枢轴记录的
元素移动至左半部,而 将大于枢轴记录的元素移动至右半部,在每个半部分中的元素可以无序,
上面所进行是一遍的分划。而后再递归地将前半部分A1进行如上的快速排序,再对后半部分A2
递归快速排序即可。所以,快速排序要进行递归的排序调用
如上面的排序示例数据所示:设数据存在数组data[12]中,其中的data[0]为辅助暂存单元,
下标为1~11区间的数据为有效的数据,原始状态如“原始”所示,以data[1]=91为枢轴记录,将
枢轴记录存放于暂存单元data[0],先从后向前扫描,即11~1的方向,查找小于91的第1个元素,
结果为data[11]=30,将30移动到data[1]中,(data[1]的数据被覆盖,但是先前已经被保存到
data[0]中,所以数据不会丢失),同时data[11]置为空闲待填充的单元(用-1进行表示),这
时后向的扫描的指针j指向11,此时再进行从前向后的扫描,即从2~11的方向,查找大于枢轴
记录91的第1个元素,结果找到data[4]=98,此时前向的扫描指针i指向4,将98移动至data[11],
同时data[4]置为空闲待填充的单元,再从后向扫描指针j=10的位置向低下标的方向进行扫描,
找到77<枢轴记录91,将77移动至刚才留下的空闲待填充单元data[4],而后再从i=5向高下标的
方向进行扫描,结果i与j碰到了一起, 这时i与j所指的位置10即为枢轴记录91应该落入的位置,
将暂存单元data[0]=91复制至data[10],这时第一遍分划即完成:位于data[10]前的数据均小于
91,位于data[10]后的数据均大于91。以下的过程即是上面过程的递归重复(但是数据的规模在
逐步缩小),将1~数轴的前一位置区块的数据进行快速排序;上面的过程完成后再将数轴的后一
位置区块(至数据区的结尾)数据进行快速排序。 最终完成排序。
*/
#include <stdio.h>
#define SIZE 20
/* 数组的初始化,产生一组随机数填充数组 */
void initAry(int data[])
{
int i;
data[0] = 0;
srand(time(&i));
for (i = 1; i < SIZE; i++) {
data[i] = rand() % 100;
}
}
/* */
void outputAry(int data[], int cr)
{
int i;
printf(" [%02d] ", data[0]);
for (i = 1; i < SIZE; i++) {
printf("%02d ", data[i]);
}
if (cr)
printf("/n");
}
/* data[]存放待排序的数据,其中的data[0]为暂存单元,start指示待排序数据起始下标,end为结束下标 */
void qsort(int data[], int start, int end)
{
int i, j, tmp;
static int invokeNum; /* 辅助变量,记录qsort函数被调用的次数 */
invokeNum++;
tmp = data[0] = data[start]; /* 枢轴记录于data[0] */
i = start; /* i为前向扫描指针,初始指向排序缓冲区的首部 */
printf("(%02d)/n", invokeNum); /* 显示qsort被调用的次数 */
for (j = end; j > i; j--) { /* j为后向扫描指针,先从后向前进行扫描 */
if (data[j] > tmp)
continue;
data[i] = data[j]; /* 找到小于枢轴记录的元素,存放缓冲区的前部 */
data[j] = -1; /* j所指单元置为空闲待填充状态,可有可无,为便于观察 */
i++;
outputAry(data, 0); /* 输出数据,便于查看,可有可无 */
printf(" [i=%02d,j=%02d]/n", i, j); /* 输出 i,j指向的位置。可有可无,为便于观察 */
for (; i < j; i++) { /* i为前向扫描指针,从前向后进行扫描 */
if (data[i] < tmp) /* 找大于枢轴记录的元素 */
continue; /* 没找到,返回继续找。 */
else
break; /* 找到,跳出 */
}
data[j] = data[i]; /* 找到的大于枢轴记录的元素存放至缓冲区的后部待填充的单元, */
data[i] = -1; /* i所指单元置为空闲待填充状态,可有可无,为便于观察 */
outputAry(data, 0); /* 输出数据,便于查看,可有可无 */
printf(" [i=%02d,j=%02d]/n", i, j); /* 输出 i,j指向的位置。可有可无,为便于观察 */
}
data[i] = tmp; /* i,j指针碰到一起,即枢轴记录应该落入的位置。 */
if (i - 1 > start)
qsort(data, start, i - 1); /* 递归调用 qsort 对枢轴记录前的元素进行快速排序 */
if (i + 1 < end)
qsort(data, i + 1, end); /* 递归调用 qsort 对枢轴记录后的元素进行快速排序 */
}
int main()
{
int data[SIZE], i;
initAry(data); /* 产生初始数据 */
printf(" "); /* 格式化显示输出。 */
for (i = 1; i < SIZE; i++) /* 输出下标。 */
printf("%02d ", i);
printf("/n");
outputAry(data, 1); /* 输出初始数据 */
qsort(data, 1, SIZE - 1);
printf("qsort result below:/n");
outputAry(data, 1); /* 输出排序数据 */
}
/* snallie@tom.com */
/* Wed Apr 2 10:57:01 HKT 2008 */
/*
快速排序是基于交换和分划的思想进行排序的一种排序算法,是bubble sort的一种改进算法.
以如下的示例进行说明
下标 01 02 03 04 05 06 07 08 09 10 11
原始 [00] 91 82 71 98 00 76 54 60 88 77 30
(01)
[91] 30 82 71 98 00 76 54 60 88 77 -1 [i=02,j=11]
[91] 30 82 71 -1 00 76 54 60 88 77 98 [i=04,j=11]
[91] 30 82 71 77 00 76 54 60 88 -1 98 [i=05,j=10]
[91] 30 82 71 77 00 76 54 60 88 -1 98 [i=10,j=10]
(02)
[30] 00 82 71 77 -1 76 54 60 88 91 98 [i=02,j=05]
[30] 00 -1 71 77 82 76 54 60 88 91 98 [i=02,j=05]
(03)
[71] 00 30 60 77 82 76 54 -1 88 91 98 [i=04,j=08]
[71] 00 30 60 -1 82 76 54 77 88 91 98 [i=04,j=08]
[71] 00 30 60 54 82 76 -1 77 88 91 98 [i=05,j=07]
[71] 00 30 60 54 -1 76 82 77 88 91 98 [i=05,j=07]
(04)
[60] 00 30 54 -1 71 76 82 77 88 91 98 [i=04,j=04]
[60] 00 30 54 -1 71 76 82 77 88 91 98 [i=04,j=04]
(05)
(06)
[82] 00 30 54 60 71 76 77 -1 88 91 98 [i=08,j=08]
[82] 00 30 54 60 71 76 77 -1 88 91 98 [i=08,j=08]
qsort result below:
[82] 00 30 54 60 71 76 77 82 88 91 98 最终排序的结果
前提:升序排序
一般地,所谓的分划操作即是,任意选取一个枢轴记录ai,(一般为方便起见,选取待排序序列
的首元素为枢轴记录ai), 将待排序的记录序列分划为两部分:前半部分A1和后半部分A2,使得
A1中的元素都小于(或小于等于)枢轴记录ai, 而位于后半部分A2的记录元素都大于枢轴记录ai,
此时已经基本有序,这一分划的过程主要进行的即是交换的操作。 在分划的过程中主要是采
取从两边向中央进行扫描的方法,(一般地,先从后向前扫描,而从前向后扫描,反复进行,
直到前向扫描和后向扫面的指针碰到一起,则结束),在扫描的过程中,逐渐将小于枢轴记录的
元素移动至左半部,而 将大于枢轴记录的元素移动至右半部,在每个半部分中的元素可以无序,
上面所进行是一遍的分划。而后再递归地将前半部分A1进行如上的快速排序,再对后半部分A2
递归快速排序即可。所以,快速排序要进行递归的排序调用
如上面的排序示例数据所示:设数据存在数组data[12]中,其中的data[0]为辅助暂存单元,
下标为1~11区间的数据为有效的数据,原始状态如“原始”所示,以data[1]=91为枢轴记录,将
枢轴记录存放于暂存单元data[0],先从后向前扫描,即11~1的方向,查找小于91的第1个元素,
结果为data[11]=30,将30移动到data[1]中,(data[1]的数据被覆盖,但是先前已经被保存到
data[0]中,所以数据不会丢失),同时data[11]置为空闲待填充的单元(用-1进行表示),这
时后向的扫描的指针j指向11,此时再进行从前向后的扫描,即从2~11的方向,查找大于枢轴
记录91的第1个元素,结果找到data[4]=98,此时前向的扫描指针i指向4,将98移动至data[11],
同时data[4]置为空闲待填充的单元,再从后向扫描指针j=10的位置向低下标的方向进行扫描,
找到77<枢轴记录91,将77移动至刚才留下的空闲待填充单元data[4],而后再从i=5向高下标的
方向进行扫描,结果i与j碰到了一起, 这时i与j所指的位置10即为枢轴记录91应该落入的位置,
将暂存单元data[0]=91复制至data[10],这时第一遍分划即完成:位于data[10]前的数据均小于
91,位于data[10]后的数据均大于91。以下的过程即是上面过程的递归重复(但是数据的规模在
逐步缩小),将1~数轴的前一位置区块的数据进行快速排序;上面的过程完成后再将数轴的后一
位置区块(至数据区的结尾)数据进行快速排序。 最终完成排序。
*/
#include <stdio.h>
#define SIZE 20
/* 数组的初始化,产生一组随机数填充数组 */
void initAry(int data[])
{
int i;
data[0] = 0;
srand(time(&i));
for (i = 1; i < SIZE; i++) {
data[i] = rand() % 100;
}
}
/* */
void outputAry(int data[], int cr)
{
int i;
printf(" [%02d] ", data[0]);
for (i = 1; i < SIZE; i++) {
printf("%02d ", data[i]);
}
if (cr)
printf("/n");
}
/* data[]存放待排序的数据,其中的data[0]为暂存单元,start指示待排序数据起始下标,end为结束下标 */
void qsort(int data[], int start, int end)
{
int i, j, tmp;
static int invokeNum; /* 辅助变量,记录qsort函数被调用的次数 */
invokeNum++;
tmp = data[0] = data[start]; /* 枢轴记录于data[0] */
i = start; /* i为前向扫描指针,初始指向排序缓冲区的首部 */
printf("(%02d)/n", invokeNum); /* 显示qsort被调用的次数 */
for (j = end; j > i; j--) { /* j为后向扫描指针,先从后向前进行扫描 */
if (data[j] > tmp)
continue;
data[i] = data[j]; /* 找到小于枢轴记录的元素,存放缓冲区的前部 */
data[j] = -1; /* j所指单元置为空闲待填充状态,可有可无,为便于观察 */
i++;
outputAry(data, 0); /* 输出数据,便于查看,可有可无 */
printf(" [i=%02d,j=%02d]/n", i, j); /* 输出 i,j指向的位置。可有可无,为便于观察 */
for (; i < j; i++) { /* i为前向扫描指针,从前向后进行扫描 */
if (data[i] < tmp) /* 找大于枢轴记录的元素 */
continue; /* 没找到,返回继续找。 */
else
break; /* 找到,跳出 */
}
data[j] = data[i]; /* 找到的大于枢轴记录的元素存放至缓冲区的后部待填充的单元, */
data[i] = -1; /* i所指单元置为空闲待填充状态,可有可无,为便于观察 */
outputAry(data, 0); /* 输出数据,便于查看,可有可无 */
printf(" [i=%02d,j=%02d]/n", i, j); /* 输出 i,j指向的位置。可有可无,为便于观察 */
}
data[i] = tmp; /* i,j指针碰到一起,即枢轴记录应该落入的位置。 */
if (i - 1 > start)
qsort(data, start, i - 1); /* 递归调用 qsort 对枢轴记录前的元素进行快速排序 */
if (i + 1 < end)
qsort(data, i + 1, end); /* 递归调用 qsort 对枢轴记录后的元素进行快速排序 */
}
int main()
{
int data[SIZE], i;
initAry(data); /* 产生初始数据 */
printf(" "); /* 格式化显示输出。 */
for (i = 1; i < SIZE; i++) /* 输出下标。 */
printf("%02d ", i);
printf("/n");
outputAry(data, 1); /* 输出初始数据 */
qsort(data, 1, SIZE - 1);
printf("qsort result below:/n");
outputAry(data, 1); /* 输出排序数据 */
}
相关文章推荐
- 快速排序算法(Quick Sort)
- [php] 数据结构&算法(PHP描述) 快速排序 quick sort
- php数据结构与算法(PHP描述) 快速排序 quick sort
- 快速排序算法 java语言描述
- 使用PHP描述冒泡排序和快速排序算法
- 快速排序算法-Quick Sort
- quick sort 快速排序算法
- 数据结构C语言描述———快速排序算法详解
- 快速排序算法 Quick sort
- [php] 数据结构&算法(PHP描述) 快速排序 quick sort
- 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
- 快速排序算法(Quick Sort)(java)
- php数据结构与算法(PHP描述) 快速排序 quick sort
- Algorithm backup ---- Quick Sort(快速排序算法)
- java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
- PHP描述冒泡排序和快速排序算法
- 快速排序算法的简短描述
- java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
- Quick Sort
- activiti简要描述