插入.希尔.选择.堆排.冒泡.快排.归并.计数_8排序
Posted 黑桃_K_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了插入.希尔.选择.堆排.冒泡.快排.归并.计数_8排序相关的知识,希望对你有一定的参考价值。
插入排序
//插入排序
void insertSort(int* arr, int n){
for (int i = 1; i < n; i++){
int end = i - 1;
int data = arr[i];
while (end>=0 && data<arr[end]){
arr[end + 1] = arr[end];
--end;
}
arr[end+1] = data;
}
}
希尔排序
//希尔排序
void shellSort(int* arr, int n){
int gap = n;
while (gap > 1){
gap = gap / 3 + 1;
//最后
//
for (int i = gap; i < n; ++i){
//同一组
int end = i - gap;
//待插入
int data = arr[i];
while (end >= 0 && arr[end]>data){
arr[end + gap] = arr[end];
end -= gap;
}
arr[end + gap] = data;
}
}
}
选择排序
//选择排序
void selectSort(int* arr, int n){
int start = 0;//记录起始位置
int end = n - 1;//记录结束位置
while ( start < end){
int minIndex = start;//最小值下标
for (int i = start+1; i <= end; ++i){//找最小值位置
if (arr[i] < arr[minIndex])
minIndex = i;
}
//把最小值放开始位置
swap(arr[minIndex], arr[start]);
++start;
}
}
//选择排序2
void selectSort2(int* arr, int n){
int start = 0;
int end = n - 1;
while (start < end){
int minIdx = start;
int maxIdx = end;
for (int i = start+1; i <= end; ++i){
if (arr[i] < arr[minIdx])
minIdx = i;
if (arr[i]>arr[maxIdx])
maxIdx = i;
}
swap(arr[start], arr[minIdx]);
if (maxIdx == start)
maxIdx = minIdx;
swap(arr[maxIdx],arr[end]);
++start;
--end;
}
}
堆排
//向下调整
void shiftDown(int* arr, int n, int cur){
int child = cur * 2 + 1;
while (child < n){
if (child + 1 < n && arr[child + 1] > arr[child])
++child;
if (arr[cur]<arr[child]){
swap(arr[child], arr[cur]);
cur = child;
child = cur * 2 + 1;
}
else
break;
}
}
//堆排序
void heapSort(int* arr, int n){
for (int i = (n - 2) / 2; i >= 0; --i){
shiftDown(arr, n, i);
}
int end = n - 1;
while (end > 0){
swap(arr[end], arr[0]);
shiftDown(arr, end, 0);
--end;
}
}
冒泡排序
//冒泡排序
void bubbleSort(int* arr, int n){
//相邻元素比较
int end = n; //[0,end]
while (end > 1){
int flag = 0;//标记排序中是否发生交换
for (int i = 1; i < end; ++i){
if (arr[i] < arr[i - 1]){
swap(arr[i], arr[i - 1]);
flag = 1;
}
}
if (flag == 0)//无交换,
break;
--end;
}
}
快排
//快速排序基准点 数据有序且过多时,会导致递归溢出
//用三数取中可以避免
int position(int* arr, int begin,int end){
//选基准点
int key = arr[begin];
int start = begin;//记录起点位置
while (begin < end){
//从后往前,找小于
while (begin < end && arr[end] >= key)
--end;
//从前往后,找大于基准值
while (begin < end && arr[begin] <= key)
++begin;
swap(arr[begin], arr[end]);
}
swap(arr[start], arr[begin]);
return begin;
}
//快排
void quickSort(int* arr, int begin, int end){
if (begin >= end)
return;
int divide = position(arr, begin, end);
//左,[begin,divide)
quickSort(arr, begin, divide - 1);
//右,[divede+1,end]
quickSort(arr, divide + 1, end);
}
//找基准值 挖坑法
int partion2(int* arr, int begin, int end){
int key = arr[begin];
while (begin < end){
while (begin<end && arr[end] < key)
--end;
arr[begin] = arr[end];
while (begin<end && arr[begin]>key)
++begin;
arr[end]=arr[begin];
}
arr[begin] = key;
return begin;
}
//找基准值 前后指针版本
int partion3(int* arr, int begin, int end){
//上一个小于基准值位置
int prev = begin;
//下一个小于基准值位置
int cur = begin + 1;
int key = arr[begin];
while (cur <= end){
//当cur走到下一个小于基准值位置
if (arr[cur] < key && ++prev != cur){
swap(arr[cur], arr[prev]);
}
++cur;
}
swap(arr[begin], arr[prev]);
return prev;
}
//非递归快排,不会有栈溢出风险
void quickSortNoR(int* arr,int n){
stack<int> st;
int begin = 0, end = n - 1;
st.push(begin);
st.push(end);
while (!st.empty()){
int end2 = st.top();
st.pop();
int begin2 = st.top();
st.pop();
int div = partion3(arr, begin, end);
//[begin,div-1]
if (div - 1 > begin2){
st.push(begin2);
st.push(div-1);
}
//[div+1,end]
if (end > div + 1){
st.push(div + 1);
st.push(end2);
}
}
}
归并排序
//归并排序
void merge(int* arr, int begin, int mid, int end, int* tmp){
//递增
int begin1 = begin;
int end1 = mid;
int begin2 = mid + 1;
int end2 = end;
int index = begin;
while (begin1 < end1 && begin2 < end2){
if (arr[begin1] < arr[begin2]){
tmp[index++] = arr[begin1];
begin1++;
}
else{
tmp[index++] = arr[begin2];
begin2++;
}
}
if (begin1 >= end1)
memcpy(tmp + index, arr + begin1, sizeof(int)*(end1 - begin1 + 1));
if (begin2 < end2)
memcpy(tmp + index, arr + begin2, sizeof(int)*(end2 - begin2 + 1));
//合并之后的零时空间拷贝过去
memcpy(arr + begin, tmp + begin, sizeof(int)*(end - begin + 1));
}
//
void _mergeSort(int* arr,int begin,int end,int* tmp){
if (begin >= end)
return;
int mid = begin + (end - begin) / 2;
_mergeSort(arr, begin, mid, tmp);
_mergeSort(arr, mid + 1,end, tmp);
merge(arr, begin, mid,end,tmp);
}
//
void mergeSort(int* arr, int n){
//申请辅助空间
int* tmp = (int*)malloc(sizeof(int)*n);
_mergeSort(arr, 0, n - 1, tmp);
free(tmp);
}
//归并排序不递归
void mergeSortNoR(int* arr, int n){
int* tmp = (int*)malloc(sizeof(int)*n);
//子序列长度
int step = 1;
while (step < n){
for (int idx = 0; idx < n; idx += 2 * step){
//找两个待合并子序列区间
//[begin,mid] [min+1,end]
int begin = idx;
int mid = idx + step - 1;
if (mid >= n - 1)
//不存在第二个子序列
continue;
int end = idx + 2 * step - 1;
//判断第二个子序列是否越界
if (end>n)
end = n - 1;
merge(arr, begin, mid, end, tmp);
}
step *= 2;
}
}
计数排序
//计数排序
void countSort(int* arr, int n){
int max=arr[0], min=arr[0];
for (int i = 1; i < n; ++i){
if (arr[i]>max)
max = arr[i];
if (arr[i] < min)
min = arr[i];
}
//申请范围
int range = max - min + 1;
int* countArr = (int*)calloc(range, sizeof(int));
for (int i = 0; i < n; ++i){
countArr[arr[i] - min]++;
}
//遍历数组。排序
int idx = 0;
for (int i = 0; i < range; ++i){
idx = countArr[i];
while (idx--){
arr[idx++] = i+min;
}
}
}
总:
#include<iostream>
#include<time.h>
#include <algorithm>
#include<stack>
using namespace std;
//插入排序
void insertSort(int* arr, int n){
for (int i = 1; i < n; i++){
int end = i - 1;
int data = arr[i];
while (end>=0 && data<arr[end]){
arr[end + 1] = arr[end];
--end;
}
arr[end+1] = data;
}
}
//希尔排序
void shellSort(int* arr, int n){
int gap = n;
while (gap > 1){
gap = gap / 3 + 1;
//最后
//
for (int i = gap; i < n; ++i){
//同一组
int end = i - gap;
//待插入
int data = arr[i];
while (end >= 0 && arr[end]>data){
arr[end + gap] = arr[end];
end -= gap;
}
arr[end + gap] = data;
}
<以上是关于插入.希尔.选择.堆排.冒泡.快排.归并.计数_8排序的主要内容,如果未能解决你的问题,请参考以下文章
十大排序算法-快排-希尔-堆排-归并-冒泡-桶排-选择-插入-计数-基数-1
8种面试经典排序详解--选择,插入,希尔,冒泡,堆排,3种快排及非递归,归并及非递归,计数(图+C语言代码+时间复杂度)
8种面试经典排序详解--选择,插入,希尔,冒泡,堆排,3种快排及非递归,归并及非递归,计数(图+C语言代码+时间复杂度)
八大排序算法C语言过程图解+代码实现(插入,希尔,选择,堆排,冒泡,快排,归并,计数)