每日一个算法-----快速排序算法
2018-03-20 22:33
211 查看
十大排序算法的时间复杂度和空间复制度表:
快速排序
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。该方法的基本思想是:1.先从数列中取出一个数作为基准数。2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。3.再对左右区间重复第二步,直到各区间
只有一个数。
快速排序算法的基本思想可以概括为:分治法+挖坑,分治法的思想我想大家都懂,只要是挖坑的思想。下面我们通过例子说明:
假设待排序序列a为:34 23 13 45 6 7 89 99 24 55
其中low=0,high=9, 挖的坑记为point= a[low],
算法的第一步先从high指针开始,从后向前寻找出第一个比point值小或者等于的数,那么比较过程是:55不符合、24符合,此时的high指向8,那么low=0, high=8, a[high]=24 while (low < high && a[high] >= point)
{
high--;
}
a[low] = a[high];
接着执行算法的第二步从low指针开始,从前向后寻找第一个比point=34值大或者等于的数,那么比较过程是:24(拉过来的坑)不符合、23不符合、13不符合、45符合,此时的low指向3,那么low=3,high=8,a[low]=45while (low < high && a[low] <= point)
{
low++;
}
a[high] = a[low];
此时算法执行完前两步后,我们需要回填坑位,在此之前我们先理清一下逻辑:
第一步中:point=a[low]=a[0]=34,a[high] = a[8]=24,a[low] = a[high];
第二步中:point=a[0]=34, a[low]=a[3]=45, a[high] = a[low];
上面的图说明,执行完这两步后,首先24覆盖了34(有两处24了,原先一处,覆盖点一处),然后45覆盖了24(24被覆盖掉了一份,还剩一份,但是45有两处了,原先一处,覆盖24的那一处,我们会发现34被完全覆盖掉了,不要急,茅坑法思想来了,恢复一下34)a[low] = point;//恢复数据,挖坑后续操作只需要一次递归前面的操作就可以了,具体就不说了,整个快速排序的代码如下:int CSort::partition(int *a, int low, int high)
{
int point = a[low];
while (low < high)
{
while (low < high && a[high] >= point)//从后先前
{
high--;
}
a[low] = a[high];
while (low < high && a[low] <= point)//从前向后
{
low++;
}
a[high] = a[low];
}
a[low] = point;//恢复坑位
return low;
}算法的递归过程void common_sort(int *a, int low, int high)
{
int point;
if (low < high)
{
point = partition(a, low, high);
common_sort(a, low, point - 1);
common_sort(a, point + 1, high);
}
}测试代码就不给了,下面是我的测试结果,因为我把普通快速排序和随机快速排序封装成了类,测试用例给了你也跑不了,如果需要测试的话,把上面代码搞懂,自己敲一遍更好。
特别感谢一位博主:大家如果不懂可以去他那边看看,讲的比我好MoreWindows。
快速排序
快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。该方法的基本思想是:1.先从数列中取出一个数作为基准数。2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。3.再对左右区间重复第二步,直到各区间
只有一个数。
快速排序算法的基本思想可以概括为:分治法+挖坑,分治法的思想我想大家都懂,只要是挖坑的思想。下面我们通过例子说明:
假设待排序序列a为:34 23 13 45 6 7 89 99 24 55
其中low=0,high=9, 挖的坑记为point= a[low],
算法的第一步先从high指针开始,从后向前寻找出第一个比point值小或者等于的数,那么比较过程是:55不符合、24符合,此时的high指向8,那么low=0, high=8, a[high]=24 while (low < high && a[high] >= point)
{
high--;
}
a[low] = a[high];
接着执行算法的第二步从low指针开始,从前向后寻找第一个比point=34值大或者等于的数,那么比较过程是:24(拉过来的坑)不符合、23不符合、13不符合、45符合,此时的low指向3,那么low=3,high=8,a[low]=45while (low < high && a[low] <= point)
{
low++;
}
a[high] = a[low];
此时算法执行完前两步后,我们需要回填坑位,在此之前我们先理清一下逻辑:
第一步中:point=a[low]=a[0]=34,a[high] = a[8]=24,a[low] = a[high];
第二步中:point=a[0]=34, a[low]=a[3]=45, a[high] = a[low];
上面的图说明,执行完这两步后,首先24覆盖了34(有两处24了,原先一处,覆盖点一处),然后45覆盖了24(24被覆盖掉了一份,还剩一份,但是45有两处了,原先一处,覆盖24的那一处,我们会发现34被完全覆盖掉了,不要急,茅坑法思想来了,恢复一下34)a[low] = point;//恢复数据,挖坑后续操作只需要一次递归前面的操作就可以了,具体就不说了,整个快速排序的代码如下:int CSort::partition(int *a, int low, int high)
{
int point = a[low];
while (low < high)
{
while (low < high && a[high] >= point)//从后先前
{
high--;
}
a[low] = a[high];
while (low < high && a[low] <= point)//从前向后
{
low++;
}
a[high] = a[low];
}
a[low] = point;//恢复坑位
return low;
}算法的递归过程void common_sort(int *a, int low, int high)
{
int point;
if (low < high)
{
point = partition(a, low, high);
common_sort(a, low, point - 1);
common_sort(a, point + 1, high);
}
}测试代码就不给了,下面是我的测试结果,因为我把普通快速排序和随机快速排序封装成了类,测试用例给了你也跑不了,如果需要测试的话,把上面代码搞懂,自己敲一遍更好。
特别感谢一位博主:大家如果不懂可以去他那边看看,讲的比我好MoreWindows。
相关文章推荐
- 每日一题(33)——用两个栈实现一个队列的功能?要求给出算法和思路
- 每日一道算法题2——定义一个栈,提供一个返回栈里最小元素方法
- 每日一个小算法-冒泡排序
- 每日一个小算法。快速排序
- 每日算法三道之判定一个给定序列能否为二叉搜索树的后序遍历结果
- 用一个栈实现另一个栈的排序(每日一道算法题)
- 每日一个小算法-简化版桶排序
- 每日一个小算法(一) 数组中连续个数组成的和最大
- 每日一道算法题:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。
- 判断一个链表是否回文(每日一道算法题)
- 每日一道算法题:一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 每日一算法2--将两个ASCII字符合成一个字节
- 每日一算法6--判断一个数字是奇数还是偶数
- [算法学习笔记]又一个采用分治法的排序算法----快速排序算法
- 每日一道算法题:输入一个表示整数的字符串,把该字符串转换成整数并输出
- 每日一道算法题:Google面试题:判断一个自然数是否是某个数的平方
- 每日一个算法------二叉树实现、递归和非递归算法(c++版)
- 每日算法题三道之给定一个字符串求k个不同字符的最长子串
- 每日一道算法题:求一个矩阵中最大的二维矩阵(元素和最大)
- 用递归函数和栈操作逆序一个栈(每日一道算法题)