算法思想:
在待排序表L[1...n]中任取一个元素pivot作为枢轴(或基准,通常取首元素),通过一趟排序将待排序表划分为独立的两部分L[1...k-1]和Lk+1..n],使得L[...k-1]中的所有元素小于pivot,LIk+.1...n]中的所有元素大于等于pivot,则pivot放在了其最终位置L(k)上。
这个过程称为一次“划分”。然后分别递归地对两个子表重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终位置上。
代码实现:
//快速排序
void QuickSort(int A[],int low,int high){
if(low < high){
int pivotpos = Partition(A,low,high);
QuickSort(A,low,pivotpos - 1); //划分左子表
QuickSort(A,pivotpos + 1,high); //划分右子表
}
}
//用第一个元素将待排序的序列划分成左右两个部分
void Partition(int A[],int low,int high){
int pivot = A[low]; //选第一个元素作为枢纽
while(low < high){ //用low、high搜索枢纽的最终位置
while(low<high && A[high] >= pivot) --high;
A[low] = A[high]; //每一次赋值就换指针搜寻
while(low<high && A[low] <= pivot) --low;
A[high] = A[low]; //每一次赋值就换指针搜寻
}
A[low] = pivot; //枢纽元素存放到最终位置
return low; //返回存放枢纽的最终位置
}
自我总结:
1.在处理表的过程中,将A[low]的值给pivot后(一般是这样),视此时A[low]的值为空,然后开始搜索——首先从high开始向左移动寻找比pivot小的值填空,当“空”每被填补一次就会出现一个新的“空”,此时换low向左移动寻找比pivot大的值填空。
2.算法效率:(与递归层数相关)
——又与二叉树相关,因为屡次递归下来后的排序序列可以形成一个二叉树,则n个结点的二叉树的最低高度为 log2n,最高高度为 n;
时间复杂度 = n*(递归层数);
最好时间复杂度 = O(log2n * n); 最坏时间复杂度:O(n^2)
空间复杂度 = O(递归层数);
最好空间复杂度 = O(log2n); 最坏时间复杂度:O(n)
最坏情况:序列本就是一个有序序列;
3.快速排序不具有稳定性;
4.注意几个Partition()函数中可能忽略的不需要再判断的跳出while循环判断的条件:
(1)只有一个元素时不满足low < high跳出循环;
(2)左子表不包含元素时low > high 跳出循环;
(3)有两个元素时只要满足low < high 仍然要执行;