交换排序类:冒泡排序,快速排序
他们的共同点就在于,通过记录的交换,最终得到想要的结果。
下面实现快速排序。
思想:通过一趟排序将待排记录划分为两部分。(作为划分标记的记录,已经保证是在它正确的位置)再对那两部分,再进行划分。知道划分为一个一个单独的数据,此时,所有记录已经是排好序了。
复杂度分析:
快速排序的时间性能取决于快速排序递归的深度。我们假设在最优情况下,partition总是在每次划分的中间位置。用递归树描述,此递归树是平衡的。深度为(logn(下取整)+1),即取递归次数为logn次。那么也就是说,总共执行了logn次找到了枢轴。而每次的找枢轴过程都是对n个数中查找的,即使是一分为二,2*(n/2)=n,则最优时间复杂度为O(nlogn)。最坏情况下,就是待排序列为正序或者倒序状态。此时,递归树就是一颗斜树。执行n-1次递归调用,第i次划分需要n-i次关键字比较。总比较次数为n(n-1)/2;复杂度为O(n^2)
辅助空间:O(logn)~~O(n),最优情况和最坏情况。最优情况可划分递归图,方便理解,同层次的1个空间共享。
#include <iostream>
using namespace std;
#define MAXSIZE 20
int search(int a[], int low, int high)
{
int tmp;
tmp= a[low];
while(low < high)
{
while(low < high && a[high] > tmp) //此处low<high不可省略,是循环退出条件。如果省了,退出条件应为|low-high|=1。
{
high--;
}
a[low] = a[high];
while(low < high && a[low] < tmp )
{
low++;
}
a[high] = a[low];
}
a[low]=tmp; // 在枢轴的位置上,方式tmp应该在的位置。也就是它的最终位置。
return low;
}
int * QuickSort(int a[],int low, int high)
{
int pivot;
if (low < high) // 递归退出条件。决不能忽略。当low == high时,证明只有一个记录,不需要再找位置。
{
pivot = search(a,low, high);
QuickSort(a,low, pivot-1);
QuickSort(a, pivot+1, high);
}
return a; //返回地址。注意函数定义返回值类型为指针。
}
int main()
{
int arr[MAXSIZE]={0};
int n;
int i;
int *pointer;
cout<<"输入数据的个数"<<endl;
cin>>n;
cout<<"输入数据:"<<endl;
for(i=1; i<=n; i++)
{
cin>> arr[i];
}
pointer = QuickSort(arr, 1, n);
for(i=1; i<=n; i++)
{
cout<<*(pointer+1)<<endl; // pointer从1开始,不是0
pointer++;
}
return 0;
}