ok,今天继续来学没学完的排序算法
一、排序
快速排序
在考试中只用快排就可以,其他排序不做阐述。
快排就相当于二分排序。在算法笔记中把划分区间的元素称为主元。
其思路是
1.调整序列中的元素,使当前序列最左端的元素在调整后满足左侧所有元素均不超过该元素,右侧所有元素均大于该元素。
2.对该元素的左侧和右侧分别递归进行1的调整,直到当前调整的区间长度不超过1。
#include <bits/stdc++.h>
using namespace std;
class Solution{//考研《天勤高分笔记》的写法
public:
void quickSort(vector<int>& nums, int left, int right){
if(left >= right) return;
int cur = left + 1;
int pivot = left; //每次交换,pivot需要右移一个分界位置
while(cur <= right){
if(nums[left] >= nums[cur]){//交换位置,保证新分界点pivot左侧都是小于nums[pivot]
swap(nums[pivot+1],nums[cur]);
pivot++;
}
cur++;
}
swap(nums[pivot],nums[left]);//把分界点pivot移到新的分界位置
quickSort(nums,left,pivot-1);
quickSort(nums,pivot+1,right);
}
vector<int> sortArray(vector<int>& nums){
int n = nums.size();
quickSort(nums,0,n-1);
return nums;
}
};
class Solution2 {//严蔚敏《数据结构》定义枢轴函数写法
public:
// 将 nums 从 low 到 high 分区,左边区域比基数小,右边区域比基数大,然后返回中间值的下标
int partition(vector<int>& nums,int low,int high){
int pivot = nums[low]; // 取第一个数为基数
while(low < high){
while(low < high and nums[high] >= pivot)
--high;// 找到第一个小于基数的位置
nums[low] = nums[high];
while(low < high and nums[low] <= pivot)
++low;// 找到第一个大于基数的位置
nums[high] = nums[low];// 交换这两个数,使得左边分区都小于或等于基数,右边分区大于或等于基数
}
nums[low] = pivot;
return low;
}
void QuickSort(vector<int>& nums,int low,int high){
if(low < high){
int pivotpos = partition(nums, low, high);// 将数组分区,并获得中间值的下标
QuickSort(nums, low, pivotpos - 1);// 对左边区域快速排序
QuickSort(nums, pivotpos + 1, high);// 对右边区域快速排序
}
}
vector<int> sortArray(vector<int>& nums) { // 主函数
int n = nums.size();
QuickSort(nums, 0, n - 1);
return nums;
}
};
int main()
{
Solution2 s;
vector<int> nums = {8,9,1,7,2,3,5,4,6,0};
vector<int> result = s.sortArray(nums);
return 0;
}
代码来自于网络,但是涉及vector所以我并不这么使用
// 该代码参考 https://www.geeksforgeeks.org/quick-sort/
#include <bits/stdc++.h>
#define N 100010
using namespace std;
int n;
int a[N];
void quick_sort(int l, int r) {
// 设置最右边的数为分界线
int pivot = a[r];
// 元素移动
int k = l - 1;
for (int j = l; j < r; ++j)
if (a[j] < pivot) swap(a[j], a[++k]);
swap(a[r], a[++k]);
if (l < k - 1) quick_sort(l, k - 1); // 如果序列的分界线左边的子段长度>1,排序
if (k + 1 < r) quick_sort(k + 1, r); // 如果序列的分界线右边的子段长度>1,排序
// 上面的过程结束后,到这里左子段和右子段已经分别排好序。又因为确定分界线以后的移动操作
// 保证了左子段中的元素都小于等于分界线,右子段中的元素都大于分界线。所以整个序列也是有序的。
}
int main() {
// 输入
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
// 快速排序
quick_sort(1, n);
// 输出
for (int i = 1; i <= n; ++i) printf("%d ", a[i]);
return 0;
}
以上就是快排的内容