#include <iostream>
#include <queue>
using namespace std;
//冒泡排序,时间复杂度O(n^2),空间复杂度O(1),稳定
void BubbleSort(int a[], int n){
for(int i=0; i<n-1; ++i){
bool isCmp = false;
for(int j=0; j<n-1-i; ++j){
if(a[j] > a[j+1]){
swap(a[j], a[j+1]);
isCmp = true;//发生了比较
}
}
if(isCmp == false)
break;//扫描一遍没有发生过一次比较,则说明已经有序,可以提前结束
}
}
//选择排序,时间复杂度O(n^2),空间复杂度O(1),不稳定
void SelectSort(int a[], int n){
for(int i=0; i<n-1; ++i){
int min_index = i;
for(int j=i+1; j<n; ++j){
if(a[j] < a[min_index])
min_index = j;
}
swap(a[i], a[min_index]);
}
}
//插入排序,时间复杂度O(n^2),空间复杂度O(1),稳定
void InsertSort(int a[], int n){
for(int i=1; i<n; ++i){
for(int j=i-1; j>=0; --j){
if(a[j] > a[j+1])
swap(a[j+1], a[j]);//一边比较一边交换
}
}
}
//希尔排序,插入排序的改进,(最坏)时间复杂度O(n^2),空间复杂度O(1),不稳定,
//平均时间复杂度比插入排序低,大概为O(n^1.5),所以比插入排序好
void ShellSort(int a[], int n){
int gap = n / 2;
while(gap >= 1){
for(int i = gap; i<n; i+=gap){
for(int j = i-gap; j>=0; j-=gap){
if(a[j] > a[j+gap])
swap(a[j+gap], a[j]);//一边比较一边交换
}
}
gap /= 2;
}
}
//归并排序,时间复杂度O(nlogn),空间复杂度O(n),稳定
Merge(int a[], int low, int mid, int high){
int* help = new int[high-low+1];
int i = low, j = mid + 1;
int k = 0;//help数组的下标
while(i<=mid && j<=high){
help[k++] = a[i] <= a[j] ? a[i++] : a[j++];//谁小放谁,相等则放a[i],保证稳定性
}
while(i<=mid){
help[k++] = a[i++];
}
while(j<=high){
help[k++] = a[j++];
}
k = 0;
for(int i=low; i<=high; ++i){
a[i] = help[k++];
}
delete[] help;
}
void MergeSort(int a[], int low, int high){
if(low == high)
return;
int mid = low + (high-low)/2;
MergeSort(a, low, mid);//处理左边
MergeSort(a, mid+1, high);//处理右边
Merge(a, low, mid, high);//左右归并
}
//快速排序,(平均)时间复杂度O(nlogn),空间复杂度O(nlogn),不稳定
void QuickSort(int a[], int low, int high){
int i = low, j = high;
if(i>=j)
return;
swap(a[i], a[i+rand()%(j-i+1)]);//随机快排
int num = a[i];
while(i<j){
while(i<j && a[j] >= num){
--j;
}
swap(a[i], a[j]);
while(i<j && a[i] <= num){
++i;
}
swap(a[i], a[j]);
}
QuickSort(a, low, i-1);
QuickSort(a, i+1, high);
}
//把数组中第index数插入堆中(前index-1个已经成堆)
void HeapInsert(int a[], int index){
while(a[index] > a[(index-1)/2]){
swap(a[index], a[(index-1)/2]);
index = (index-1)/2;
}
}
void Heapify(int a[], int index, int heapsize){
int left = index*2 + 1;
while(left < heapsize){
//有右孩子并且右孩子比左孩子大则等于右孩子,否则为左孩子
int largest = left+1<heapsize && a[left+1]>a[left] ? left+1:left;
largest = a[largest]>a[index]?largest:index;
if(largest==index)
break;
swap(a[largest], a[index]);
index = largest;
left = index*2 + 1;
}
}
//堆排序,时间复杂度O(nlogn),空间复杂度O(1),不稳定
void HeapSort(int a[], int n){
//先建堆,时间复杂度O(n)
for(int i=0; i<n; ++i){
HeapInsert(a, i);
}
//交换堆顶和最后一个结点
//重建堆,时间复杂度一次为O(logn),总共为O(nlogn)
while(n>1){
swap(a[0], a[--n]);
Heapify(a, 0, n);
}
}
//得到一个数字的倒数第i位数
int getReIndexNum(int num, int i){
int res = 0;
while(i--){
res = num%10;
num /= 10;
}
return res;
}
//基数排序,时间复杂度O(n*radix),空间复杂度O(n),稳定(我实现的这个代码只能是正数)
void RadixSort(int a[], int n){
//申请一个序号为0~9的桶
queue<int>* bucket = new queue<int>[10];
int max_num = a[0];
//找数组中的最大元素,它的位数最多;
for(int i=1; i<n; ++i){
if(a[i] > max_num)
max_num = a[i];
}
int radix = 0;//最大元素的位数
while(max_num){
max_num /= 10;
++radix;
}
for(int m=1; m<=radix; ++m){
//装桶
for(int i=0; i<n; ++i){
bucket[getReIndexNum(a[i], m)].push(a[i]);
}
//收集
for(int i=0, j=0; i<10&&j<n; ++i){//每个桶依次收集,i表示桶的序号,j表示原数组序号
while(!bucket[i].empty()){//直到该桶为空,则跳下一个
a[j++] = bucket[i].front();
bucket[i].pop();
}
}
}
}
int main(){
int a[] = {1, 3, 5, 76, 10, 8, 2, 9, 100, 24, 12, 89};
RadixSort(a, 12);
for(int i=0; i<12; ++i){
cout << a[i] << endl;
}
return 0;
}
八种排序算法C++注释版
最新推荐文章于 2024-08-14 11:18:54 发布