【自我笔记之数据结构】排序---快排以及优化

快排的的原理

//方案一:直接插入排序
/*
void InsertSort1(int arr[], int s, int l)
{
    for(int i = s; i < l+1; ++i)
	{
		int index = arr[i];//记录下要对比的数
		int j = i - 1;//对比前一个数
		while(j > -1 && index < arr[j])
		{
			//不匹配把数字向后移动
			arr[i--] = arr[j--];
		}
		arr[j+1] = index;
	}
}
*/

//方案二:三数取中(0,mid,end)放基准值位

void Swap(int arr[], int swap1, int swap2)
{
	int tmp = arr[swap1];
	arr[swap1] = arr[swap2];
	arr[swap2] = tmp;
}

void GetMidNum(int arr[], int left, int midd, int right)
{
	//使得最后三数的位置是 前(中数) 中(小数) 后(大数)
	if(arr[midd] > arr[left])
		Swap(arr, midd, left);
	if(arr[midd] > arr[right])
		Swap(arr, midd, right);
	if(arr[left] > arr[right])
		Swap(arr, left, right);
}

int Partition(int arr[], int s, int l)//将数组分区
{
	int tmp = arr[s];//拿到基准值

	while(s < l)
	{
		while(s < l && arr[l] >= tmp) l--;//否则就去覆盖前面的数值
		arr[s] = arr[l];
		while(s < l && arr[s] <= tmp) s++;//同上
		arr[l] = arr[s];
	}//记得把基准值放到他的位置
	arr[s] = tmp;

	return s;
}

//递归实现
void Quick(int arr[], int s, int l)
{
	if(s < l)
	{
		//方案一 直接插排
		/*
		if(l - s + 1 <= 20)
		{
			InsertSort1(arr, s, l);
		}
		*/

		//方案二:三数取中放基准值位
		/*
		int mid = (l - s)/2 + s;
		GetMidNum(arr, s, mid, l);
		*/

		//方案三:随机取基准值
		//Swap(arr, s, rand() % (l - s + 1) + s);
		int boundindex = Partition(arr, s, l);
		Quick(arr, s, boundindex-1);
		Quick(arr, boundindex+1, l);
	}
}

//非递归实现
void Quick2(int arr[], int s, int l)
{
	stack<int> st; 
	if(s < l)
	{
		st.push(s);
		st.push(l);

		while(!st.empty())
		{
			int high = st.top();
			st.pop();
			int low = st.top();
			st.pop();
			int boundindex = Partition(arr, low, high);
			if(low < boundindex - 1)
			{
				st.push(low);//有至少两个数
				st.push(boundindex-1);
			}
			if(high > boundindex+1)
			{
				st.push(boundindex+1);
				st.push(high);
			}
		}
	}
}

void QuickSort(int arr[], int len)
{
	Quick(arr, 0, len-1);//递归
	//Quick2(arr, 0, len-1);//非递归
}

优化方案:主要是在Quick上做手脚,以此来体现快

1、当分裂到一定数量时,用直接插排来提高效率

2、三数取中,生成基准值

3、随机生成基准值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值