快速排序

快速排序算法在《数据结构(C语言版)》这本书的第272页至277页,有较为详细的介绍。

书本中提到,快速排序是对起泡排序的一种改进。它的基本思想是:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续排序,以达到整个序列有序。

具体步骤为:

  1. 从数列中挑出一个元素,称为 "基准"(pivot),
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

快速排序算法实现如下:

// 快速排序.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <exception>  // exception


/********************实现一**********************/
//用来生成一个在start和end之间的随机数
int RandomInRange(int start, int end)
{
	if(start <0 || end <0)
		throw new std:: exception("Invalid Parameters");
	//rand() 产生0~RAND_MAX间的整数
	//rand()%x 产生0到x之间的随机数,不包括x
	//产生[start,end]之间的随机数

	if( start == end)
		return start;
	else if( start > end)
	{	
		return rand()% (start - end + 1) + end;
	}
	else
	{	
		return rand()% (end - start + 1) + start;
	}
}

//用来交换两个数字
void Swap(int *p1, int *p2)
{
	int tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

//快速排序
int Partition(int data[], int length, int start, int end)
{
	if(data == NULL || length <=0 || start < 0 || end >= length)
		throw new std::exception("Invalid Parameters");

	int index = RandomInRange(start, end);
	Swap(&data[index], &data[end]);

	int small = start - 1;
	for(index = start; index < end; ++ index)
	{
		if(data[index] < data[end])
		{
			++ small;
			if(small != index)
				Swap(&data[index], &data[small]);
		}
	}

	++ small;
	Swap(&data[small], &data[end]);

	return small;
}

//快速排序
void QuickSort(int data[], int length, int start, int end)
{
	if(start == end)
		return;

	int index = Partition(data, length, start, end);
	if(index > start)
		QuickSort(data, length, start, index - 1);
	if(index < end)
		QuickSort(data, length, index + 1, end);
}

/******************实现二******************/
//划分区间
int Partition(int data[], int start, int end)
{
	int X = data[start];

	while(start < end)
	{  
		//从end开始向前找一个比X小X的树(后面如果有相同的值,默认大于它)
		while(start < end && data[end] >= X) --end;
		data[start] = data[end];

		//从start开始向后找一个大于X的树(如果前面有相同的值,默认大于它)
		while(start < end && data[start]<= X) ++start;
		data[end] = data[start];
	}

	data[start] = X;

	return start;
}

void QuickSort(int data[], int start, int end)
{
	if(start == end)
		return;

	int index = Partition(data, start, end);
	if(index > start)
		QuickSort(data, start, index - 1);
	if(index < end )
		QuickSort(data, index + 1, end);
}

//打印数组
void print(int data[], int length)
{
	for(int i=0; i< length; i++)
		printf("%d ", data[i]);
	printf("\n");
}

void main()
{
	int data [] = {72, 6, 57, 88, 60, 42, 83, 73, 48, 85};
	int data1 [] = {49, 38, 49, 97, 76, 13, 27, 49};

	//实现一
	QuickSort(data, sizeof(data)/sizeof(int), 0, 9);
	//实现二
	QuickSort(data1, 0, 7);	

	//打印数组
	print(data, sizeof(data)/sizeof(int));
	print(data1, sizeof(data1)/sizeof(int));	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值