考题2:快速排序(递归与非递归)
基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序是一种不稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
(一)定轴法(递归):
1.备份对轴(首记录)
2.取两个指针left和right,初始值分别是序列的第二个元素和最后一个元素,并且left<=right
3.移动两个指针
*从right所指的位置向左搜索,找到第一个小于轴的元素,从left所指的位置向右搜索,找到第一个大于轴的元素,找到后如果left
void quickSort(int a[],int first,int last){
if(last <= first)
return ; //到了长度小于1这种情况已经是有序列了
int pivot = a[first];
int left = first + 1;//left等于第二个元素
int right = last;
int temp;
while(left <= right){
while(a[right] > pivot && right >= left)//找到一个比first小的,但必须保证left值小于等于right值
right--;
while(a[left] < pivot && left <= right)//找到一个比first大的,但得保证left值小于等于right值
left++;
if(left >= right) //说明已经是有序序列,无须交换
break;
temp = a[left];
a[left] = a[right];
a[right] = temp;
left++,right--; //相应的进一位
}
a[first] = a[right];//因为right一定是停在从右到左第一个小于first的数上,交换之后
a[right] = pivot;
quickSort(a,first,right-1);
quickSort(a,left,last);
}
(二)挖坑法(非递归):
1.备份轴记录
2.取两个指针low和high,初始值就是序列的两端下标,保证low<=high
3.移动两个指针
*从high向左找到第一个小于轴的元素, 放在low的位置
*从low向右找到第一个大于轴的元素,放在high的位置
4.重复,直到low=high,
5.把轴放在low所指的位置
6.分别对low所指的位置的左边和右边进行上述的递归
#include <iostream>
using namespace std;
void quickSort(int a[],int l,int r){
if(l < r){
int low = l;
int high = r;
int pivot = a[l];
while(low < high){
while(low < high && a[high] >= pivot)
high--;
if(low < high)
a[low++] = a[high];
while(low < high && a[low] < pivot)
low++;
if(low <high)
a[high--] = a[low];
}
a[low] = pivot;
quickSort(a,l,low-1);
quickSort(a,low+1,r);
}
}
int main()
{
int a[8] = {34,12,56,47,68,89,59,96};
quickSort(a,0,7);
cout<<"非递归"<<endl;
int i;
for(i = 0;i <=7;i++)
cout<<a[i]<<endl;
return 0;
}