快速排序

这篇博客介绍了快速排序算法,它是冒泡排序的一种优化。每一轮快速排序将一个数字放到其正确的位置,通过选取基准数并不断调整序列,使得基准数最终位于正确位置。文中给出了清晰的代码实现,并说明了如何修改代码以实现由大到小的排序。

快速排序实际上是改进的冒泡排序,冒泡排序每次交换相邻的两个位置的数据,而快速排序则可以跨位置交换顺序。每一轮快速排序会将一个数字安排到其正确的位置,若每次取第一个数字为基准数,则首先从最后一个位置查找并将当前查找位置记为s1,后从最前面的位置查找并将当前查找位置记为s2,重复这两个步骤,直至s1<=s2,退出进行下一轮快速排序。

/**
 *Copyright @ 2019 Zhang Peng. All Right Reserved.
 *Filename:
 *Author: Zhang Peng
 *Date:
 *Version:
 *Description:快速排序
**/

#include<iostream>
using namespace std;
void swap(int * data, int order1, int order2)
{
	int temp = data[order1];
	data[order1] = data[order2];
	data[order2] = temp;
}

int partition(int *data,int length, int start, int end)
{
	int compareVlaue = data[start],compareIndex=start;
	int forward = start, back = end;

	cout << "待排序元素" << endl;
	for (int i = start; i <= end; i++)
	{
		cout << data[i] << " ";
	}
	cout << endl;

	int num = 0;

	while (forward < back)
	{
		if (num % 2 == 0)
		{
			for (int i = back; i >= forward; i--)
			{
				if (data[i] < compareVlaue)
				{
					swap(data, compareIndex, i);
					back = i;
					compareIndex = i;
					break;
				}
				else
				{
					back = i;
				}
			}
		}
		else
		{
			for (int i = forward; i <= back; i++)
			{
				if (data[i] > compareVlaue)
				{
					swap(data, compareIndex, i);
					forward = i;
					compareIndex = i;
					break;
				}
				else
				{
					forward = i;
				}


			}
		}
		
		num++;
	}

	return compareIndex;
}

void quicksort(int * data, int length, int start, int end)
{
	if (start == end)
		return;
	int centerIndex = partition(data, length, start, end);
	int length_left = centerIndex - start;
	int length_right = end - centerIndex;
	if (length_left > 1)
	{
		quicksort(data, length_left, start, centerIndex - 1);
	}
	if (length_right > 1)
	{
		quicksort(data, length_right, centerIndex + 1, end);
	}
	
	
}
int main()
{
	int originaldata[] = { 6,1,2,7,9,3,4,5,10,8};
	

	//partition(originaldata, 4, 6, 9);
	quicksort(originaldata, 10, 0, 9);
	
	cout << "排序后" << endl;
	for (int i = 0; i < 10; i++)
	{
		cout << originaldata[i] << " ";
	}
	cout << endl;

    system("pause");
    return 0;
}

前面的程序是自己根据快速排序的思想写的比较乱,以下程序参照教科书上的算法来写,简洁易懂。
由于**只有在一趟排序结束时,即low=high的位置才是枢轴记录的最后位置。**所以可以将枢轴元素暂存起来,最后再进行赋值。
代码如下:

/**
 *Copyright @ 2019 Zhang Peng. All Right Reserved.
 *Filename:
 *Author: Zhang Peng
 *Date:
 *Version:
 *Description:
**/

#include<iostream>
using namespace std;

int RandomInRange(int start, int end)
{
	int add = rand() % (end - start);
	return start + add;
}

void Swap(int data[], int index1, int index2)
{
	int temp = data[index1];
	data[index1] = data[index2];
	data[index2] = temp;
}

// 剑指offer书上的
int Partition1(int data[], int start, int end)
{
	int index = RandomInRange(start,end);  // 随机取一个标准元素
	Swap(data, index, end);  // 交换元素
	int small = start - 1;
	for (int i = start; i<end; ++i) {
		if (data[i]<data[end]) {
			++small;
			if (small != i)
				Swap(data, i, small);
		}
	}
	++small;
	Swap(data, small, end);
	return small;
}

// 一般数据结构书上的
int Partition2(int data[] ,int start, int end) 
{
	int temp = data[start];  // 保存标准元素
	int i = start, j = end;
	while (i<j){
		while (i<j&&data[j] >= temp) j--;
			data[i] = data[j];

		while (i<j&&data[i] <= temp) i++;
			data[j] = data[i];
	}
	data[i] = temp;
	return i;
}


void QuickSort(int data[], int start, int end)
{
	if (start == end)
		return;
	int index = Partition2(data, start, end);
	if (index > start)
		QuickSort(data, start, index - 1);
	if (index < end)
		QuickSort(data, index + 1, end);
}

int main()
{
	const int len = 20;
	int testcase[len] = { 2, 3, 4, 5, 3, 56, 77, 23, 4, 34, 4 };

	cout << "排序前" << endl;
	for (int i = 0; i < len; i++)
		cout << testcase[i] << " ";
	cout << endl;

	QuickSort(testcase, 0, len - 1);


	cout << "排序后" << endl;
	for (int i = 0; i < len; i++)
		cout << testcase[i] << " ";
	cout << endl;

    system("pause");
    return 0;
}

相对而言,Partition2原理比较好懂,编写起来也容易。
在这里插入图片描述
上述程序为由小到大排序,如果要将其改为由大到小排序,只需将其 >=和<=符号互换即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值