您的位置:首页 > 编程语言 > C语言/C++

快速排序(c++代码)

2014-12-22 17:22 399 查看
//快速排序
/*
快速排序的思路是:
1.先从数列中取出一个数作为基准数.
2.分区.将比这个数大的数全部放到它的右边,小于或等于它的数全放到左边.
3.再对左右区间重复第二步,直到各区间只有一个数或没有数.
*/
//如有错误,欢迎指正.

#include <stdio.h>
#include <vector>
#include <stack>
using namespace std;

//《算法导论》上的分区方法,具体图例请参考本书.
//选取最右边的数为基准数,从左向右单边扫描.将数组分为4部分:
//区域一(left至i) : 值<= 基准数的区域
//区域二(i+1至j-1): 值> 基准数的区域
//区域三(j至right-1) :未划分区域
//区域四(right) :基准数
//我们假设left = 0 , right = 10
int _partition(vector<int> &vec , int left , int right){
int pivotkey = vec[right];
int temp;
//一开始区域一为空: left(0) -> i(-1)
//区域二也为空 : i+1(0) -> j-1(-1)
//区域三为: j(0) -> right-1(9)
int i = left - 1;
for ( int j = left ; j < right ; j++ ) {
//找到 <= 基准数的数的位置,我们将其和区域二最前面一个元素交换.
//从而扩大区域一.
if ( vec[j] <= pivotkey ){
i++;
//exchange( vec[i] , vec[j])
temp = vec[i];
vec[i] = vec[j];
vec[j] = temp;
}
//j++扩大区域二的位置,减少区域三的位置.
}
//exchange( vec[i+1] , vec[right])
temp = vec[i+1];
vec[i+1] = vec[right];
vec[right] = temp;
//
return i+1;
}

//另一种分区方法.俗称挖坑法.
//选取最左边的数为基准数,从两边向中间扫描.
int _partition_1(vector<int> &vec , int left , int right){
int pivotkey = vec[left];
while( left < right ){
//从右向左扫描
while ( left < right && vec[right] > pivotkey ) right--;
if ( left < right ) {
vec[left] = vec[right];
left++;
}
//从左向右扫描
while ( left < right && vec[left] <= pivotkey ) left++;
if ( left < right ) {
vec[right] = vec[left];
right--;
}
}
//两个坑坑到一起了.把基准数塞入这个坑.
vec[left] = pivotkey;
return left;
}

//快速排序(递归方式)
void _quickSort(vector<int> &vec , int left , int right){
if ( left < right ){
int pivot_pos = _partition( vec , left , right);
//int pivot_pos = _partition_1( vec , left , right );
_quickSort( vec , left , pivot_pos - 1);
_quickSort( vec , pivot_pos + 1 , right);
}
}

//快速排序包装函数(递归方式)
void quickSort(vector<int> &vec){
_quickSort( vec , 0 , vec.size() - 1);
}

//快速排序(使用栈的非递归方式)
//使用栈来模拟递归,栈中保存需要排序元素的边界
void quickSort_Using_Stack(vector<int> &vec){
stack<int> s;
//存储第一对边界.
s.push(0);
s.push(vec.size()-1);
//
while( !s.empty() ){
//
int right = s.top(); s.pop();
int left = s.top(); s.pop();
int pivot_pos = _partition( vec , left , right );
//
if ( pivot_pos - 1 > left){
s.push( left );
s.push( pivot_pos - 1 );
}
if ( pivot_pos + 1 < right){
s.push( pivot_pos + 1 );
s.push( right );
}
}
}

void test_push(vector<int> &vec){
vec.push_back(100);
vec.push_back(129);
vec.push_back(88);
vec.push_back(90);
vec.push_back(111);
vec.push_back(1);
}

void test_print_and_clear(vector<int> &vec){
for(int i = 0 ; i < vec.size() ; i++){
printf("%d " , vec[i]);
}
printf("\n");
vec.clear();
}

int main(){
vector<int> vec;
//quickSort
test_push(vec);
quickSort(vec);
test_print_and_clear(vec);
//quickSort_Using_Stack
test_push(vec);
quickSort_Using_Stack(vec);
test_print_and_clear(vec);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: