uacs2024

导航

快速排序

题目描述

将读入的 N 个数从小到大排序后输出。

输入格式

第一行为一个正整数 N。

第二行包含 N 个空格隔开的正整数 ,为你需要进行排序的数。

输出格式

将给定的 N 个数从小到大输出,数之间空格隔开,行末换行且无空格。

输入 #1

5
4 2 4 5 1

输出 #1

1 2 4 4 5

说明/提示

 

一、 左右指针法

#include<iostream>
using namespace std;

void swap(int &a,int &b){
    int t;t = a;a = b;b = t;
}

int sort(int i,int j,int num[]){
    int key = i;
    while(i < j){
        while(i < j && num[j] >= num[key]) j--;  //这里右指针先动
        while(i < j && num[i] <= num[key]) i++;  
        //右指针碰到比基准小的之后左指针动,直到左指针遇到比基准大的
        
        swap(num[i],num[j]);
        //j--;  交换完之后直接下一轮while,不需要让右指针再往左一次
    }
    swap(num[j],num[key]);
    return j;  //返回此次sort基准的位置,以便分割快排
}

void quickSort(int i,int j,int num[]){
    if(i >= j) return;
    int key = sort(i,j,num);
    quickSort(i,key-1,num);
    quickSort(key+1,j,num);
}

int main(){
    int n;cin >> n;
    int num[n];
    for (int i = 0; i < n; i++)  cin >> num[i];
    quickSort(0,n-1,num);
    for (int i = 0; i < n - 1; i++)  cout << num[i] << " ";
    cout << num[n-1];
}

 

二、挖坑法(王道演示的就是这种)

#include<iostream>
using namespace std;

void swap(int &a,int &b){
    int t;t = a;a = b;b = t;
}

//变化在sort函数
int sort(int i,int j,int num[]){
    int hole = i;    //先把最左边的位置当作坑
    int key = num[i];  //把基准值记录为key
    while(i < j){
        //while(i < j && num[j] >= num[hole])  错误范例,正常情况下num[hole]是一直在变的,不是一开始的基准值
        while(i < j && num[j] >= key)  j--;
        num[hole] = num[j];hole = j;   //这里相当于先移动右指针,遇到比基准小的就把当前右指针的值放到坑里,然后把右指针的位置当作新坑

        //while(i < j && num[i] <= num[hole])  错误原因同上
        while(i < j && num[i] <= key)  i++;
        num[hole] = num[i];hole = i;  
    }
    num[hole] = key;
    return hole;
}

void quickSort(int i,int j,int num[]){
    if(i >= j) return;
    int key = sort(i,j,num);
    quickSort(i,key-1,num);
    quickSort(key+1,j,num);
}

int main(){
    int n;cin >> n;
    int num[n];
    for (int i = 0; i < n; i++)  cin >> num[i];
    quickSort(0,n-1,num);
    for (int i = 0; i < n - 1; i++)  cout << num[i] << " ";
    cout << num[n-1];
}

 

三、前后指针法

#include<iostream>
using namespace std;

void swap(int &a,int &b){
    int t;t = a;a = b;b = t;
}
//cur若指向的数比基准值小,那么prev右移,prev和cur指向的值互换,最后cur右移
//cur若指向的数比基准值大,那么cur右移
//直到cur越过有边界,结束循环。prev指向的位置就是基准值应该在的位置
int sort(int i,int j,int num[]){
    int prev = i;
    int cur = i+1;  //永远都是prev在第一,cur在第二
    int key = num[i];  //将基准值保存
    while(cur <= j){
        if(num[cur] > key){
            cur++;
        }
        else{  //num[cur] <= key
            prev++;
            swap(num[prev],num[cur]);
            cur++;
        }
        /*
        //一种更简洁的写法
        if(num[cur] <= key){
            prev++;
            swap(num[prev],num[cur]);
        }
        cur++;*/
    }
    swap(num[i],num[prev]);
    //num[prev] = key;  整个过程num[i]是一直没变的,不能直接把key放到prev的位置
    return prev;
}

void quickSort(int i,int j,int num[]){
    if(i >= j) return;
    int key = sort(i,j,num);
    quickSort(i,key-1,num);
    quickSort(key+1,j,num);

}

int main(){
    int n;cin >> n;
    int num[n];
    for (int i = 0; i < n; i++)  cin >> num[i];

    quickSort(0,n-1,num);

    for (int i = 0; i < n - 1; i++)  cout << num[i] << " ";
    cout << num[n-1];
}

 

 

 

 

posted on 2024-11-07 17:49  ᶜʸᵃⁿ  阅读(0)  评论(0编辑  收藏  举报