C/C++语言重温------排序之快速排序

C/C++语言重温------排序之快速排序


#include<iostream>

using namespace std;

// 获取(a,b)之间随机数
#define random(a,b) (rand()%(b-a)+a)

// 模板获取数组长度的方法
template <typename T, int N>

int getSize(T(&input)[N]) {
	return sizeof(input) / sizeof(T);
}

// 定义数组长度为全局变量
int arr_length = 0;

// 输出数组
void display_arr(int *arr) 
{

	for (int i = 0; i < arr_length; i++)
	{
		cout << "arr[" << i << "]:" << arr[i] << endl;
	}
}

/*
	快速排序:
		采用了分治的思想;
		把原始的数组筛选成较小和较大的两个子数组,然后递归地排序两个子数组;
		在分成较大和较小的两个子数组的过程中,如何选定一个基准值尤为关键!!!!!!

	时间复杂度:
		最优情况下为 O(nlogn)
		最复杂的情况下为 O(n^2)

	空间复杂度:O(logn)
		
*/

int getKeyIndex(int *arr, int start, int end)
{
	swap( arr[ random(start, end) ], arr[end] );  // 随机取一个值为基准值,并放到数组末尾

	int i, j;  // i 最终指向基准值所在下标 ,j 用来遍历所有值

	for (i = start, j = start; j < end; j++) 
	{
		if(arr[j] <= arr[end])   // 将比基准值小的值放在基准值所在下标左边
		{
			if (i != j)   // 出现比基准值大的值时 “i” 不会自增,直至 j 指向比基准值小的值时,将 i、j 所指向的值互换
			{
				swap(arr[i], arr[j]);
			}

			i++;  // i 所指向的值比基准值小时自增,比基准值大时停止自增。直至找到其他比基准值小的值与其交换,并继续自增。
		}
	}

	// 经过上述处理后,“i”指向比基准值大的值所组成“数组”的最小下标,“j”指向放在数组最后的基准值
	swap(arr[j], arr[i]);      // 将其进行交换,便得到基准值左侧数均小于基准值,右侧数均大于基准值
	//swap(arr[i], arr[end]);  //与上等同,因为 j == end

	return i;  // 返回基准值对应下标
}


void quick_sort(int *arr, int start, int end) 
{
	if (start >= end)  // 如果只剩最后一个元素,则直接返回
	{
		return;
	}
	
	int key = getKeyIndex(arr, start, end);  // 获取基准值所在下标,基准点左边的数都小于基准值,右边的数都大于基准值

	quick_sort(arr, start, key - 1);   // 递归的对基准点左边的树进行排序
	quick_sort(arr, key + 1, end);     // 递归的对基准点右边的树进行排序
}





int main(int argc, char const *argv[])
{
	int arr[]  = { 5, 6, 1, 9, 2, 4, 3, 7, 10, 8 };

	arr_length = getSize(arr);

	display_arr(arr);

	cout << endl;
	
	// 快排
	quick_sort(arr, 0, arr_length - 1);

	// 展示排序后数组
	display_arr(arr);

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值