排序算法--快排(递归|非递归实现)

平均时间复杂度:O(nlogn)
最坏情况下的是:O(n^2) – 数列顺逆序

递归 – 单边循环法


#include <iostream>
using namespace std;

// partition()实现元素交换
int partition(int arr[], int startIndex,int endIndex) {
    int temp = 0;
    // pivot作为基准值(数列区域分割线)
    // 临时存储arr[startIndex]的值
    int pivot = arr[startIndex];
    // mark:小于基准值的边界线
    int mark = startIndex;

    for(int i = startIndex;i <= endIndex;i++){
        // 小于基准值则
        // 1.小于基准值的边界区域(mark)扩增1
        // 2.将当前元素(小于基准值的元素)与mark指代元素交换位置
        if(arr[i] < pivot){
            mark++;
            temp = arr[i];
            arr[i] = arr[mark];
            arr[mark] = temp;
        }
    }
    // 基准值归位
    // 每轮交换完毕后,将mark元素与初始位pivot元素交换
    // 使分割线 pivot在对应位置(小于|pivot|大于的)
    arr[startIndex] = arr[mark];
    arr[mark] = pivot;
    // 最后返回分割线位置下标
    return mark;
}

void quickSort(int arr[], int startIndex,int endIndex,int len) {
    // 递归结束条件:startIndex >= endIndex
    // 直到不可拆分为止
    if(startIndex > endIndex)
        return;
    // 非法输入判断,防止数组越界
    if(startIndex < 0 || endIndex >=len){
        cout << "argc error,array bound"<<endl;
        return;
    }
    // 得到基准元素位置
    int pivotIndex = partition(arr,startIndex,endIndex);
    // 根据基准元素,分成两部分进行递归排序
    quickSort(arr,startIndex,pivotIndex-1,len);
    quickSort(arr,pivotIndex+1,endIndex,len);

}

void printArr(int a[], int len) {
    for(int i = 0;i< len; i++){
        cout << a[i] << " ";
    }
    cout <<endl;
}

int main() {
    int arr[] ={4,7,3,5,6,2,8,1};
    int len = sizeof(arr)/sizeof(int);
    int endIndex = len -1;
    cout << "排序前:";printArr(arr,len);
    quickSort(arr, 0, endIndex,len);
    cout << "排序后:";printArr(arr,len);
}


非递归实现

  1. 原本的递归实现转化成一个栈的实现
  2. 用栈保存每一个待排序子串的【首|尾】的【元素下标】,下一次while循环时取出这个范围,对这段子序列进行partition操作
#include <iostream>
#include <vector>
#include <stack>
using namespace std;

void print(const vector<int>& array)
{
    for(auto val:array)
        cout<<val<<" ";
    cout<<endl;
}


int partition(vector<int>&arr,int start,int end)
{
    int temp = 0;
    int left = start;
    int right = end;
    int pivot = arr[start];

    while(left!=right){
        // 控制right 指针比较并左移
        while(left < right && arr[right] > pivot)
            right--;
        // 控制left指针比较并右移,注意左分区取值范围“ <= ”
        while(left < right && arr[left] <= pivot)
            left++;

        // 交换left和right 指针所指向的元素
        if(left < right){
            temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
        }
    }

    //pivot 和指针重合点交换
    arr[start] = arr[left];
    arr[left] = pivot;

    return left;
}

//辅助函数
void qsortHelp(vector<int>& array,int start, int end)
{
    stack<int>temp;
    //先把区间入栈,保证栈内不为空
    temp.push(end);   // push 压栈存入end
    temp.push(start); // push 压栈存入start

    while(!temp.empty()){
        start = temp.top(); // 获取栈顶元素(不弹栈) start = 0;
        temp.pop();         // 弹出 start
        end = temp.top();   // 获取栈顶元素(不弹栈) end = len-1;
        temp.pop();         // 弹出 end

        if(start < end){
            //根据此时的左右区间,选出中间的基准值key
            int div = partition(array,start,end);

            // 左分区存在:[start,div-1]
            if(div -1 > start){
                temp.push(div-1);
                temp.push(start);
            }
            // 右分区存在:[div+1,end]
            if(div + 1 < end){
                temp.push(end);
                temp.push(div+1);
            }
        }
    }
}


//非递归排序入口函数
void quickSort(vector<int>& arr)
{
    if(arr.empty())
        return;
    int len = arr.size();
    // printf("len = %d\n",len);
    qsortHelp(arr,0,len-1);

}

int main()
{
    vector<int>array{1,5,2,4,0,3,8,9,7,6};
    cout<<"排序前: ";print(array);
    quickSort(array);
    cout<<"排序后: ";print(array);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值