快速排序
快速排序的基本思想就是通过一趟操作将一个无序的序列分割成相邻的两个区域,其中一个区域中数据的关键字都比另一个区域中的小,(即找到一个枢轴,以其为居中标杆,右边的都比它小,左边的都比它大)。然后对两个区域分别进行这样的操作,直到整个序列呈现有序状态。
对与本算法而言,要调用三个函数。第一个函数,int Partition(RcdType R[], int low, int high), 作用是将low...high序列进行一次划分并返回枢轴的位置。具体操作为定义pivotkey,将序列最左边数据关键字赋给它,然后将low的关键字放入R[0] 哨兵单元待定。对于high,如果其关键字比枢轴小,则将其赋给low,对于low,如果其关键字比枢轴大,则将其赋给high,同时注意对其进行自加自减操作,最后当low=high时结束,将R[0]的值赋给low,并返回low。第二个函数,void QSort(RcdType R[], int s, int t),作用是对序列 s...t 进行快速排序。函数体中首先是调用第一个函数对s..t 进行一次划分,然后得到枢轴位置后对左右两边区域递归进行划分,最终实现排序。第三个函数,通过调用第二个函数对顺序表L进行排序。
#include<stdio.h>
/******************************************************************************
对记录这个数据类型的定义
******************************************************************************/
typedef int KeyType;
typedef struct {
KeyType key;
char data;
}RcdType;
/*******************************************************************************
对每一个元素都是记录的顺序表的定义
********************************************************************************/
const int MAXSIZE = 10;
typedef struct {
RcdType *r; //r[0]是哨兵单元,不记录数值 r[i]表示记录
int length; //表示顺序表的实时长度
}SqList;
/*********************************************************************************
建表
**********************************************************************************/
void InitList_L(SqList &L)
{ //定义过数据类型后引用时要先给它分配内存空间
L.r = new RcdType[MAXSIZE + 1];
L.length = 0; //初始化表长为0
}
/********************************************************************************
排序
*********************************************************************************/
int Partition(RcdType R[], int low, int high)
{
//对记录子序列R[low...high]进行一趟快速排序,并返回枢轴记录所在位置
//使得在它之前的记录的关键字均不大于它的关键字,在它之后的记录的关键字
//均不小于它的关键字
int pivotkey;
R[0] = R[low]; //将枢轴记录移至数组的闲置分量 R[0]是哨兵单元
pivotkey = R[low].key; //枢轴记录关键字 相当于把pivotkey指向待处理序列low..high中最左边的low关键字
while (low < high) //从表的两端交替地向中间扫描
{
while (low < high&&R[high].key >= pivotkey)
high--;
if (low < high) //确保跳出循环时的high关键字比枢轴小
R[low++] = R[high]; //将比枢轴记录小的记录移到低端
while (low < high&&R[low].key <= pivotkey)
low++;
if (low < high)
R[high--] = R[low]; //将比枢轴记录大的记录移到高端
}
R[low] = R[0]; //将枢轴记录移到正确位置
return low; //返回枢轴位置
}
void QSort(RcdType R[], int s, int t)
{
//对记录序列R[s..t]进行快速排序
int pivotloc;
if (s < t) //长度大于1;
{
pivotloc = Partition(R, s, t); //对R[s..t]进行一次划分,并返回枢轴位置
QSort(R, s, pivotloc - 1); //对低端子序列递归排序
QSort(R, pivotloc + 1, t); //对高端子序列递归排序
}
}
void QuickSort(SqList &L)
{
//对顺序表L进行快速排序
QSort(L.r, 1, L.length);
}
void main()
{
int i;
SqList L;
InitList_L(L);
char a[MAXSIZE] = { 'Y','L','V','X','O','L','!','I','U','E' };
int key[MAXSIZE] = { 3,5,7,2,6,1,10,4,9,8 };
for (i = 1; i <= MAXSIZE; i++)
{
L.r[i].data = a[i - 1];
L.r[i].key = key[i - 1];
L.length++; //千万不要忘记每输入一个记录,表长要加一
}
printf("排序前顺序表中数据为:");
for (i = 1; i <= MAXSIZE; i++)
{
printf("%c ", L.r[i].data);
}
printf("\n");
QuickSort(L);
printf("排序后顺序表中数据为:");
for (i = 1; i <= MAXSIZE; i++)
printf("%c ", L.r[i].data);
}
|