为了和其他的博客差不多,还是放一张对比图把,因为上个礼拜复习排序的时候找的代码良莠不齐,所以总结了一下,C++自己写了一份,我是认为 堆排序、快速排序 、归并排序是比较难懂的,感觉面试问的比较多
冒泡排序 时间复杂度 O(N2)
稳定的
/*
* @brief 冒泡排序
*/
void bubbleSort(int a[], int n){
int i, j;
for(int i = 0 ; i < n-1; i ++){
for(int j = 0 ; j < n - i - 1 ; j++){
if(a[j] > a[j+1]){
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
快速排序 事件复杂度 O(nlogn)
/*
/*@brief 快速排序
冒泡 + 分治 + 递归
*
*/
void quickSort(int a[], int low, int high){
if(low >= high)
return;
int i = low; // i 作为指针从左向右扫描
int j = high;
int key = a[low];
while(i<j){
while(a[j] >= key && i < j) //右边小于基准的数字
j--;
a[i] = a[j];
while(a[i] <= key && i < j) //左边大于基准的数字
i++;
a[j] = a[i];
}
a[i] = key; // 当i与j相遇,将基准元素赋值到指针 i 处
quickSort(a, low, i);
quickSort(a, i+1, high);
}
堆排序 ,事件复杂度 nlogn
这里建堆的时候是大顶堆,之后排序的时候每次大顶堆都跟数组末尾最后一个交换,所以最后得到的顺序是升序排列
/*
*@ 堆排序
*/
void adjust_heap(int *a, int root, int len){
int left = 2*root + 1;
int right = 2*root + 2;
int max = root;
if(left < len && a[left] > a[max]) // left < len 防止越界
max = left;
if(right < len && a[right] > a[max])
max = right;
if(max != root){
swap(a[max], a[root]); //堆顶需要最大
adjust_heap(a, max, len);
}
}
void heap_sort(int *a, int len){
//初始化建堆
for(int i = len/2-1 ; i >= 0; --i){ //从最后一个非叶子节点开始向前进行调整
adjust_heap(a, i, len);
}
//排序重建堆
cout << a[0] << endl;
for(int i = len-1 ; i >= 0; --i){ //堆排序 此时 [0, len-1]为一个堆
swap(a[0], a[i]);
adjust_heap(a, 0, i);
}
}
归并排序
事件复杂度 O(nlogn)
稳定
/*
*@brief 归并排序
*@ 分治 递归会占用大量的时间和空间 合并
*/
//合并数组中的下标为 left 到 middle , middle到right
void Merge(int arr[], int left, int middle, int right){ // 这里范围是 [left, right]
int temp[right - left + 1];
for(int i = left; i<= right; i++)
temp[i-left] = arr[i]; //给临时数组赋值 temp成为一个和arr一样的数组
int i = left, j = middle+1; //i 指向左边第0个, j指向右边第0个
for(int k = left ; k <= right ; k++){ //k指向 原数组的 第0个
if(i > middle && j <= right){ // k 超过了 middle 所以直接放右边数组数字
arr[k] = temp[j-left];
j++;
}
else if(j > right && i <= middle){ // j 已经超过了 right 所以直接放 左边数组数字
arr[k] = temp[i-left];
i++;
}
else if(temp[i-left] > temp[j-left]){
arr[k] = temp[j-left];
j++;
}
else if(temp[i-left] <= temp[j-left]){
arr[k] = temp[i-left];
i++;
}
}
}
void MergeSort(int arr[], int left, int right){
if(left >= right)
return;
int middle = (right+left)/2;
MergeSort(arr, left, middle);
MergeSort(arr, middle+1, right);
Merge(arr, left, middle, right);
}
选择排序
时间复杂度 O(n2)
直接选择排序
//选择排序 时间复杂度 O2 不稳定
void selectSort(int a[], int n){
int i,j,index;
for(int i = 0 ; i < n-1 ; i++){
index = i;
for(int j = i+1 ; j < n ; j++){
if(a[index] > a[j])
index = j;
swap(a[index], a[i]);
}
}
}
插入排序 稳定的
时间复杂度 O(n2)
直接插入排序
/*@brief 插入排序
*
*/
void insertSort(int a[], int n){
int i,j,key;
for(int i = 1; i < n ; i++){
key = a[i];
j = i - 1;
for(j ; j >= 0 ;j--){
if(a[j] > key)
a[j+1] = a[j];
else
break;
}
a[j+1] = key;
}
}
希尔排序
基数排序