快速排序
题目描述
将读入的 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];
}