交换排序
冒泡排序:
最简单直接的排序方式,时间复杂度为 O ( N 2 ) O(N^2) O(N2)
#include<iostream>
using namespace std;
#define N 10+1
int a[N] = {0,10,9,8,7,6,5,4,3,2,1};
//遍历
int print(int a[]){
for(int i = 1; i < N; i++){
cout << a[i] << " ";
}
cout << endl;
return 0;
}
int main(){
print(a);
for(int i = 1;i<N - 1;i++){ // 迭代的次数
for(int j = 1;j < N - i;j++){ // 每一次都会找出至少一个最大值或最小值;
if(a[j] > a[j + 1]){
a[0] = a[j];
a[j] = a[j + 1];
a[j + 1] = a[0];
}
}
}
print(a);
}
优化冒泡排序:
使用一个bool
类型的变量,来记录一轮迭代的过程中数据是否存在交换,如果存在交换,那么说明还有数据没有排好,否则说明所有数据都已经排好顺序了,那么就提前结束循环迭代。时间复杂度为
O
(
N
2
)
O(N^2)
O(N2)
// 优化冒泡排序
# include<iostream>
using namespace std;
# define IOS ios::sync_stdio(0); cin.tie(0); cout.tie(0);
const int N = 10 + 1;
int nums[N] = {0, 1, 9, 7, 8, 6, 5, 4, 3, 2, 10};
void solve(){
// 优化冒泡排序
int number = 0;
int temp = 0;
for(int i = 0; i < N; i++){
number += 1;
bool flag = false;
for(int j = 1;j < N - i; j++){
if(nums[j] < nums[j - 1]){
temp = nums[j - 1];
nums[j - 1] = nums[j];
nums[j] = temp;
flag = true;
}
}
if(!flag) break;
}
for(int i = 0;i < N; i++){
cout<<nums[i]<<" ";
}
cout<<endl<<number<<endl;
}
int main(){
int t = 1;
while(t --){
solve();
}
return 0;
}
双向冒泡排序:
双向冒泡排序,就是使用一个指针变量来记录左右边界,如果是正序排序(从小到大),那么从左至右的时候会将一个最大值推送到最后,那么这个位置就不必再进行排序了,缩减右边界指针,同理,在从右至左的时候,会将一个最小值推送到前面,缩减左边界指针,如果两个指针相遇就说明所有数据都已经排好顺序了。
双向冒泡排序可以结合优化冒泡排序,如果某一次迭代的过程中没有任何交换,那么就可以提前结束循环。
// 双向冒泡排序
# include<iostream>
using namespace std;
# define IOS ios::sync_stdio(0); cin.tie(0); cout.tie(0);
const int N = 10 + 1;
int nums[N] = {0, 1, 9, 7, 8, 6, 5, 4, 3, 2, 10};
void my_swap(int &a, int &b){
int temp = a;
a = b;
b = temp;
return ;
}
void solve(){
// 双向冒泡排序
int number = 0;
int left = 0, right = N - 1;
while(left < right){
// 从左到右
for(int i = left;i <= right;i ++){
if(nums[i] < nums[i - 1]) my_swap(nums[i], nums[i - 1]);
}
// 会得到一个最大值,因此right --
right --;
// 从右到左
for(int i = right;i >= left;i --){
if(nums[i] < nums[i - 1]) my_swap(nums[i], nums[i - 1]);
}
// 会得到一个最小值,因此left ++
left ++;
}
for(int i = 0;i < N; i++){
cout<<nums[i]<<" ";
}
cout<<endl<<number<<endl;
}
int main(){
int t = 1;
while(t --){
solve();
}
return 0;
}
快速排序:
时间复杂度 O ( N ⋅ log N ) O(N \cdot \log N) O(N⋅logN)
# include<iostream>
using namespace std;
# define IOS ios::sync_stdio(0); cin.tie(0); cout.tie(0);
const int N = 10 + 1;
int nums[N] = {0, 1, 9, 7, 8, 6, 5, 4, 3, 2, 10};
int quickSort(int l, int r){
int pivot = nums[r]; // 设置中间值为r
int low = l, higher = r;
while(low < higher){
// 进行左半部分
while(low < higher && nums[low] <= pivot) low ++;
nums[higher] = nums[low];
// 进行右半部分
while(low < higher && nums[higher] >= pivot) higher --;
nums[low] = nums[higher];
}
// 结束循环时,将pivot填充到最后的位置
// if(low == higher) cout<<true<<endl;
nums[low] = pivot;
return low; // 返回中间值
}
// 分区
void segmentation(int l, int r){
if(l < r){
int mid = quickSort(l, r);
segmentation(l, mid - 1); // 注意这里,mid相当于一个分界线,不用再进入排序中了
segmentation(mid + 1, r);
}
return ;
}
int main(){
// 快速排序算法
segmentation(0, N - 1);
for(int i = 0;i < N; i++){
cout<<nums[i]<<" ";
}
return 0;
}