直接插入排序
void insert_sort(int arr[],size_t n){
int i,j;
//第一个元素前面没有元素,所以不需要插入,一个元素肯定是有序
for(i=1;i<n;++i){//把元素arr[i]往前插入 [0,i-1]区间有序 使得 [0,i]区间有序
int key = arr[i]; //记录需要插入的元素arr[i];
for(j=i-1;j>=0&&key<arr[j];--j){//key比arr[j]要小 说明key要放到arr[j]的前面 arr[j]要往后移
arr[j+1] = arr[j];
}
if(j+1 != i){//如果 j+1 == i arr[j+1]本来存储的就是key
arr[j+1] = key;
}
}
}
折半插入排序
void bin_insert_sort(int arr[],size_t n){
int i,j;
for(i=1;i<n;++i){
int left=0,right=i-1;
int key = arr[i];
while(left<=right){
int mid = (left+right)/2;
if(arr[mid]<=key){
left = mid+1;
}else{
right = mid-1;
}
}
for(j=i-1;j>right;--j){
arr[j+1] = arr[j];
}
arr[right+1] = key;
}
}
二路插入排序
void two_road_insert_sort(int arr[],size_t n){
//需要把arr中的元素使用二分插入到brr数组中
int brr[n];
int max=0,min = 0;//记录brr数组中最大值和最小值的下标
brr[0] = arr[0]; //brr中只有一个值 brr[0]
int i,j;
for(i=1;i<n;++i){//把arr中所有元素逐一插入到brr数组中
//arr[i]
if(arr[i]>=brr[max]){//插入的元素大于等于brr中最大值元素 max后面
brr[++max] = arr[i];
}else if(arr[i]<=brr[min]){//插入的元素小于等于brr中最小值 min前面
//min = (min-1+(int)n)%n;
if(min==0){
min = n-1;
}else{
--min;
}
brr[min] = arr[i];
}else if(arr[i]>brr[0]){
for(j=max;j>=0&&brr[j]>arr[i];--j){//把大于arr[i]往后移
brr[j+1] = brr[j];
}
++max;
brr[j+1] = arr[i];
}else{
for(j=min;j<n&&brr[j]<arr[i];++j){//把小于arr[i]往前移
brr[j-1] = brr[j];
}
--min;
brr[j-1] = arr[i];
}
}
for(i=0;i<n;i++){
arr[i] = brr[(i+min)%n]; //利用求余 可以找到min前面的数
}
}
希尔排序
void shell_insert_sort(int arr[],size_t n){
int step,i,j;
for(step=n/2;step>0;step=step/2){
for(i=step;i<n;++i){//从组内第二个元素开始进行组内插入
int key = arr[i];
//组内插入 i i-step前一个元素
for(j=i-step;j>=0&&key<arr[j];j=j-step){
arr[j+step] = arr[j];
}
if(j+step!=i){
arr[j+step] = key;
}
}
}
}
简单选择排序
void select_sort(int arr[],size_t n){
int i,j;
for(i=1;i<n;++i){
//循环[0,n-i]区间 记录最大值的下标
int index = 0;
for(j=1;j<=n-i;++j){//循环指定的区间 记录最大值的下标
if(arr[index] < arr[j]){
index = j;
}
}
if(index != n-i){
int tmp = arr[index];
arr[index] = arr[n-i];
arr[n-i] = tmp;
}
}
}
堆排序
void reheap(int arr[],int pos,size_t n){
int key = arr[pos];
int child = 2*pos + 1; //pos左孩子下标
while(child<n){//左孩子存在
if(child+1<n && arr[child]<arr[child+1]){//右孩子存在且右孩子大
++child;
}
if(key < arr[child]){
arr[pos] = arr[child];
pos = child;
child = 2*pos + 1;
}else{
break;
}
}
arr[pos] = key;
}
void heap_sort(int arr[],size_t n){
int i;
//把arr调整为大根堆
for(i=n/2-1;i>=0;--i){
reheap(arr,i,n);
}
for(i=n-1;i>0;--i){
//把arr[0]和最后一个元素交换位置
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
//0下标元素发生改变 只需要重新调整0位置的元素即可
reheap(arr,0,i);
}
}
冒泡排序
//如果数组有序 时间复杂度为O(n) 平均时间复杂度O(n^2)
void bubble_sort(int arr[],size_t n){
int i,j;
for(i=0;i<n;++i){
bool swap = false;
for(j=1;j<n-i;++j){
//arr[j-1] arr[j]
if(arr[j] < arr[j-1]){
int tmp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = tmp;
swap = true;
}
}
if(!swap){//在完整的一次冒泡过程中,没有任何两个元素的值发生交换 说明有序
break;
}
}
}