#include<iostream>
#include<iomanip>
#include<cmath>
#include<string.h>
#include<cstdlib>
using namespace std;
//插入排序
// 1.直接插入
// a.记录被插入的值 temp
// b.插入次数 i
// c.插入位置 pos
// d.大于插入数移动从i-1到pos都往后移动
// 时间复杂度o(n*n),空间复杂度o(1)
void insert_sort(int arr[],int n)
{
int i,pos,temp;
for(i=1;i<n;i++)
{
//找坐标
temp = arr[i];
pos = i;
while(arr[--pos]>temp&&pos>=0);
//后移
for(int j = i-1;j>pos;j--)
{
arr[j+1] = arr[j];
}
arr[pos+1] = temp;
}
}
void insert_sort_1(int arr[],int n)
{
int i,j,temp;
for(i=1;i<n;i++)
{
//找坐标
if(arr[i]<arr[i-1])
{
temp = arr[i];
//后移
for(int j = i-1;j>=0&&arr[j]>temp;j--)
{
arr[j+1] = arr[j];
}
arr[j+1] = temp;
}
}
}
// 2.折半插入
void insert_sort_2(int arr[],int n)
{
int i,pos,temp;
for(i = 1;i<n;i++)
{
temp = arr[i];
//折半查找
int left = 0,right = i-1;
while(left<=right)
{
int mid = (left+right)/2;
if(arr[mid]<temp)left = mid+1;
else right = mid-1;
}
pos = right;
//后移
for(int j = i-1;j>pos;j--)
{
arr[j+1] = arr[j];
}
arr[pos+1] = temp;
}
}
// 3.希尔排序
// 1.循环步长,/2直到步长为1
// 2.对于每个步长进行插入排序
// 空间复杂度o(1),时间复杂度约为(n的1.3次方)
// 不稳定
void shell_sort(int arr[],int n)
{
int d,i,j,temp;
for(d = n/2;d>=1;d/=2)
{
//单步插入
for(i =d;i<n;i++)
{
if(arr[i-d]>arr[i])
{
temp = arr[i];
for(j =i-d;j>=0&&arr[j]>temp;j-=d)
{
arr[j+d] = arr[j];
}
arr[j+d] =temp;
}
}
}
}
// 交换排序
// 1.冒泡排序
// a.循环次数n-1,每次会找到一个最大值放到最后;
// b.交换n-1-i次
// 空间复杂度o(1),时间复杂度最好o(n),最坏为o(n*n)
// 稳定,适用于链表
void bubble_sort(int arr[],int n)
{
int i,j,temp;
for(i =0;i<n;i++)
{
int flag = 1;
for(j =0;j<n-1-i;j++)
{
if(arr[j]>arr[j+1])
{
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
flag = 0;
}
}
if(flag)break;
}
}
//快速排序
// 1.单次划分函数part(int arr[],int left,int right)
// 2.递归左右划分,出口是left==right
// 时间复杂度最好o(n*log2 n),最差o(n*n);空间复杂度最好o(n*log2 n),最差o(n*n)
int part(int arr[],int left,int right)
{
int mul = arr[left];
while(left<right)
{
while(left<right&&arr[right]>=mul)right--;//找到小值
arr[left] = arr[right];
while(left<right&&arr[left]<mul)left++;
arr[right] = arr[left];
}
arr[left] = mul;
return left;
}
void quick_sort(int arr[],int left,int right)
{
if(left<right)
{
int mul = part(arr,left,right);
quick_sort(arr,left,mul-1);
quick_sort(arr,mul+1,right);
}
}
//选择排序
//1.简单选择排序
// a.循环n-1次
// b.每次找到最小值放在前面
//时间复杂度o(n*n)无法优化,不稳定
void select_sort(int arr[],int n)
{
int i,j,min,item;
for(i =0;i<n-1;i++)
{
min =i;
for(j=i;j<n;j++)
{
if(arr[j]<arr[min])min =j;
}
//交换
item = arr[min];
arr[min] = arr[i];
arr[i] = item;
}
}
//2.堆排序(感觉特别厉害)
// a.将每个大根堆的首元素放在最后
// b.将剩下元素进行首元素大根堆排序
// c.需要节点子数大根堆函数,数组大根堆函数,最后组装在大根堆排序中
// 时间复杂度为o(n*log2 n),空间复杂度o(1)
void max_one(int arr[],int k,int len)
{
int i,temp;
temp = arr[k];
for(i =2*k;i<=len;i*=2)
{
//找到两个孩子最大
if(i<len&&arr[i]<arr[i+1])i++;
if(temp>arr[i])break;//当时写成了arr[k]>arr[i]弄了好久
else//交换
{
arr[k] = arr[i];
k = i;
}
}
arr[k] = temp;
}
void max_arr(int arr[],int len)
{
for(int i=len/2;i>0;i--)
{
max_one(arr,i,len);
}
}
void max_sort(int arr[],int len)
{
max_arr(arr,len);
for(int i =len;i>0;i--)
{
int temp = arr[i];
arr[i] = arr[1];
arr[1] = temp;
max_one(arr,1,i-1);
}
}
//试一试小根堆
// a.将最小根第一项保留,继续剩下形成小跟堆
// b.节点子树小根堆上升
// 代码有点问题(之后改)
void print_arr(int arr[],int len)
{
for(int i =1;i<=len;i++)
{
cout<<arr[i]<<' ';
}
cout<<endl;
}
void min_one(int arr[],int k,int len)
{
int i,temp;//记录最小位置和初始值
temp = arr[k];
for(i = 2*k;i<=len;i*=2)
{
//最小
if(i<len&&arr[i]>arr[i+1])i++;
if(temp<arr[i])break;
else
{
arr[k] = arr[i];
k = i;
}
}
arr[k] = temp;
}
void min_arr(int arr[],int len)
{
for(int i = len/2;i>0;i--)
{
min_one(arr,i,len);
}
}
void min_sort(int arr[],int len)
{
for(int i =len;i>0;i--)
{
int temp = arr[i];
arr[i] = arr[1];
arr[1] = temp;
min_one(arr,1,i-1);
print_arr(arr,len);
}
}
//归并排序
//时间复杂度o(n*log2 n)空间复杂度o(n)
//1.两个有序数组合并
int brr[100];
void merge(int arr[],int left,int mid,int right)
{
int i,j,k;
for(i =left;i<=right;i++)
{
brr[i] = arr[i];
}
for(i = left,j =mid+1,k =left;i<=mid&&j<=right;k++)
{
if(brr[i]<=brr[j])arr[k] = brr[i++];
else arr[k] = brr[j++];
}
while(j<=right)arr[k++] = brr[j++];
while(i<=mid)arr[k++] = brr[i++];
}
void merge_sort(int arr[],int left,int right)
{
if(left<right)
{
int mid = (left+right)/2;
merge_sort(arr,left,mid);
merge_sort(arr,mid+1,right);
merge(arr,left,mid,right);
}
}
// //计数排序
// 1.记录数组最大最小值,开辟一个大小为max-min的数组
// 2.记录坐标次数
// 3.打印序号+min
void count_sort(int arr[],int len)
{
int min = 100,max = 0;
for(int i=0;i<len;i++)
{
if(arr[i]<min)min = arr[i];
if(arr[i]>max)max = arr[i];
}
int d = max-min+1;
int *b = new int[d];
memset(b,0,d*sizeof(int));
for(int i =0;i<len;i++)
{
b[arr[i]-min]++;
}
for(int i =0;i<d;i++)
{
while(b[i]--)
{
cout<<i+min<<" ";
}
}
delete []b;
}
int main()
{
int arr[] = {134,349,24,576,854,23,5,78,-7};
int n = sizeof(arr)/sizeof(arr[0]);
// insert_sort_2(arr,n);
// shell_sort(arr,n);
// bubble_sort(arr,n);
// quick_sort(arr,0,n-1);
// select_sort(arr,n);
// max_sort(arr,n-1);//精彩,太精彩了!
// min_arr(arr,n-1);
// min_sort(arr,n-1);
// merge_sort(arr,0,n-1);
count_sort(arr,n);
}