【数据结构】快速排序

数据结构 快速排序


/*
	名称:快速排序 
	语言:数据结构C语言版 
	编译环境:VC++ 6.0
	日期: 2014-3-26 
*/

#include <stdio.h>
#include <malloc.h>
#include<windows.h>


// 将a中整数序列重新排列成自小至大有序的整数序列(起泡排序) P273
void bubble_sort(int a[],int n)
{
	int i, j, t, change;

	for(i = n-1, change = 1; i > 1 && change; --i)
	{
		change = 0;

		for(j = 0; j < i; ++j)
			if(a[j]>a[j+1])
			{
				t = a[j];
				a[j] = a[j+1];
				a[j+1] = t;
				change = 1;
			}
	}
}

// 记录类型
typedef int KeyType;	// 定义关键字类型为整型
typedef int InfoType;	// 定义其它数据项的类型

typedef struct
{
	KeyType key;		// 关键字项
	InfoType otherinfo;	// 其它数据项
}RedType;

#define MAXSIZE 20	// 一个用作示例的小顺序表的最大长度

// 顺序表类型
typedef struct
{
	RedType r[MAXSIZE+1];	// r[0]闲置或用作哨兵单元
	int length;				// 顺序表长度
}SqList;


// 打印顺序表 
void print(SqList L)
{
	int i;
	
	for(i = 1; i <= L.length; i++)
		printf("(%d, %d) ", L.r[i].key, L.r[i].otherinfo);
	
	printf("\n\n");
}

#if 0

// 算法10.6(a)  P274
// 交换顺序表L中子表L.r[low..high]的记录,使枢轴记录到位, 
// 并返回其所在位置,此时在它之前(后)的记录均不大(小)于它。
int Partition(SqList *L,int low,int high)
{
	RedType t;
	KeyType pivotkey;
	
	pivotkey=(*L).r[low].key; // 用子表的第一个记录作枢轴记录 
	while(low<high)
	{
		// 从表的两端交替地向中间扫描 
		while(low<high&&(*L).r[high].key>=pivotkey)
			--high;
		t=(*L).r[low]; // 将比枢轴记录小的记录交换到低端 
		(*L).r[low]=(*L).r[high];
		(*L).r[high]=t;

		while(low<high&&(*L).r[low].key<=pivotkey)
			++low;
		t=(*L).r[low]; // 将比枢轴记录大的记录交换到高端 
		(*L).r[low]=(*L).r[high];
		(*L).r[high]=t;
	}
	
	return low; // 返回枢轴所在位置 
}
#endif

#if 1
// 算法10.6(b) P274
// 交换顺序表L中子表r[low..high]的记录,枢轴记录到位,并返回其 
// 所在位置,此时在它之前(后)的记录均不大(小)于它。
int Partition(SqList *L,int low,int high)
{
	KeyType pivotkey;
	
	(*L).r[0]=(*L).r[low];	// 用子表的第一个记录作枢轴记录 
	pivotkey=(*L).r[low].key; // 枢轴记录关键字 
	while(low< high)
	{
		// 从表的两端交替地向中间扫描 
		while(low<high&&(*L).r[high].key>=pivotkey)
			--high;
		(*L).r[low]=(*L).r[high]; // 将比枢轴记录小的记录移到低端 
		while(low<high&&(*L).r[low].key<=pivotkey)
			++low;
		(*L).r[high]=(*L).r[low]; // 将比枢轴记录大的记录移到高端 
	}
	(*L).r[low]=(*L).r[0]; // 枢轴记录到位 
	return low; // 返回枢轴位置 
}
#endif


// 算法10.7 P275  
// 对顺序表L中的子序列L.r[low..high]作快速排序。
void QSort(SqList *L,int low,int high)
{
	int pivotloc;
	
	if(low<high)
	{
		// 长度大于1 
		pivotloc=Partition(L,low,high); // 将L.r[low..high]一分为二 
		QSort(L,low,pivotloc-1); // 对低子表递归排序,pivotloc是枢轴位置 
		QSort(L,pivotloc+1,high); // 对高子表递归排序 
	}
}

// 算法10.8  P276
// 对顺序表L作快速排序。
void QuickSort(SqList *L)
{
	QSort(L,1,(*L).length);
}



#define N 8

int main()
{
/***************起泡排序****************/
#if 0
	int d[N] = { 49, 38, 65, 97, 76, 13, 27, 49 };
	int i;

	printf("\n起泡排序前:\n");
	for(i = 0; i < N; i++)
		printf("%d ", d[i]);
	
	bubble_sort(d,N);
	
	printf("\n起泡排序后:\n");
	for(i = 0; i < N; i++)
		printf("%d ", d[i]);
	printf("\n");
#endif

/***************快速排序****************/
#if 1
	RedType d[N] = {
		{ 49, 1}, { 38, 2}, { 65, 3}, { 97, 4},
		{ 76, 5}, { 13,6}, { 27, 7}, { 49, 8}
	};
	SqList l;
	int i;
	
	for(i=0;i<N;i++)
		l.r[i+1]=d[i];
	l.length = N;

/***************快速排序a****************/
#if 0
	printf("快速排序a前:\n");
	print(l);

	QuickSort(&l);
	
	printf("快速排序a后:\n");
	print(l);
#endif

/***************快速排序b****************/
#if 1
	printf("快速排序b前:\n");
	print(l);

	QuickSort(&l);
	
	printf("快速排序b后:\n");
	print(l);
#endif

#endif

	system("pause");
	return 0;
}
/*
输出效果:


***************起泡排序****************

起泡排序前:
49 38 65 97 76 13 27 49
起泡排序后:
13 27 38 49 49 65 76 97
请按任意键继续. . .


***************快速排序a****************

快速排序a前:
(49, 1) (38, 2) (65, 3) (97, 4) (76, 5) (13, 6) (27, 7) (49, 8)

快速排序a后:
(13, 6) (27, 7) (38, 2) (49, 1) (49, 8) (65, 3) (76, 5) (97, 4)

请按任意键继续. . .


***************快速排序b****************

快速排序b前:
(49, 1) (38, 2) (65, 3) (97, 4) (76, 5) (13, 6) (27, 7) (49, 8)

快速排序b后:
(13, 6) (27, 7) (38, 2) (49, 1) (49, 8) (65, 3) (76, 5) (97, 4)

请按任意键继续. . .


*/

运行结果如下:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐刘根

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值