1、插入排序(升序)
void InsertSort(int* a,int n)
{
for(int i=0;i<n-1;i++)
{
int end = i;
int tmp = a[end+1];
while(end > 0)
{
if(a[end]>tmp)
{
a[end+1] = a[end];
--end;
}
else
break;
}
a[end+1] = tmp;
}
}
2、希尔排序
void ShellSort(int* a, int n)
{
int gap = n;//gap>1时为预排序,gap=1时为直接插入排序
while(gap>1)
{
gap = gap/3+1;//+1是保证最后一次排序gap是1
for(int i=0;i<n-gap;++i)
{
int end = 1;
int tmp = a[end+gap];
while(end>0)
{
if(a[end]>tmp)
{
a[end+gap] = a[end];
end-=gap;
}
else
break;
}
a[end+gap] = tmp;
}
}
}
3、选择排序
void Swap(int* p1,int*p2)
{
int tmp=*p1;
*p1=*p2;
*p2=tmp;
}
void SelectSort(int* a, int n)
{
int begin=0,end=n-1;
while(begin<end)
{
//[begin,end]选出一个最小的,选出一个最大的(下标)
int mini=begin,maxi=end;
for(int i=begin;i<=end;++i)
{
if(a[i]>a[maxi])
maxi=i;
if(a[i]<a[mini])
mini=i;
}
Swap(&a[begin],&a[mini]);
if(begin==maxi)
maxi=mini;
Swap(&a[end],&a[maxi]);
++begin;
--end;
}
}
4、堆排序(排升序,建大堆)
void AdjustDwon(int* a, int n, int root)
{
int parent=root;
int child=parent*2+1;
while(child<n)
{
if((child+1<n)&&(a[child+1]>a[child]));
++child;
if(a[parent]<a[child])
{
int tmp=a[parent];
a[parent]=a[child];
a[child]=tmp;
parent=child;
child=parent*2+1;
}
else
break;
}
}
void HeapSort(int* a, int n)
{
for(int i=(n-1-1)/2;i>=0;--i)
AdjustDown(a,n,i);
int end=n-1;
while(end>0)
{
//把堆顶当前最大数依次换到最后
Swap(&a[0],&a[end]);
AdjustDown(a,end,0);//调堆选出剩下的数中最大的
--end;
}
}
5、冒泡排序
void BubbleSort(int* a, int n)
{
for(int end=n-1;end>0;--end)
{
int flag=0;
for(int i=0;i<end;++i)
{
if(a[i]>a[i+1])
{
Swap(&a[i],&a[i+1]);
flag=1;
}
}
if(flag==0)
break;
}
}
6、快速排序
// 快速排序hoare版本
int PartSort1(int* a, int left, int right)
{
int key=a[right];//right做key,左边先走;left做key,右边先走
int keyindex=right;
while(left<right)
{
while(left<right&&a[left]<=key)//left找大
++left;
while(left<right&&a[right]>=key)//right找小
--right;
Swap(&a[left],&a[right]);
}
Swap(&a[left],&a[keyindex]);
return left;
}
//快速排序挖坑法
int PartSort2(int* a,int left,int right)
{
int key=a[right];
while(left<right)
{
while(left<right&&a[left]<key)//找大
++left;
a[right]=a[left];//找到大,扔到右边坑里,同时right形成新的坑
while(left<right&&a[right]>=key)
--right;
a[left]=a[right];//找到小,扔到左边的坑里,同时left形成新的坑
}
a[left]=key;
return left;
}
//快速排序前后指针法
int PartSort3(int* a, int left, int right)
{
int prev=left-1;
int cur=left;
int key=a[right];
while(cur<right)//遇到key位置就结束
{
if(a[cur]<key&&++prev!=cur)
Swap(&a[prev],&a[cur]);
++cur;
}
++prev;
Swap(&a[prev],&a[right];
return prev;
}
//快速排序(递归)
void QuickSort(int* a, int left, int right)
{
if(left>=right)
return;
int keyindex=PartSort(a,left,right);
QuickSort(a,left,keyindex-1);
QuickSort(a,keyindex+1,right);
}
//快速排序非递归实现(用栈来模拟)
void QuickSortNonR(int* a, int left, int right)
{
Stack st;
StackInit(&st);
StackPush(&st, left);
StackPush(&st, right);
while (StackEmpty(&st) != 0)
{
int end = StackTop(&st);
StackPop(&st);
int begin = StackTop(&st);
StackPop(&st);
int div = PartSort1(a, begin, end);
if (begin < div - 1)
{
StackPush(&st, begin);
StackPush(&st, div - 1);
}
if (div + 1 < end)
{
StackPush(&st, div + 1);
StackPush(&st, end);
}
}
}
7、归并排序
//归并排序的递归实现
void _MergeSort(int* a, int left, int right, int* tmp)
{
if (left >= right)
return;
int mid = left + ((right - left) >> 1);
_MergeSort(a, left, mid, tmp);
_MergeSort(a, mid+1, right, tmp);
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int index = left;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] <= a[begin2])
tmp[index++] = a[begin1++];
else
tmp[index++] = a[begin2++];
}
while (begin1 <= end1)
tmp[index++] = a[begin1++];
while (begin2 <= end2)
tmp[index++] = a[begin2++];
memcpy(a+left, tmp+left, sizeof(int)*(right - left+1));
}
void MergeSort(int* a, int n)
{
assert(a);
int* tmp = (int*)malloc(sizeof(int)*n);
_MergeSort(a, 0, n - 1, tmp);
free(tmp);
}
//归并排序的非递归实现
void merge(int* a, int left, int mid, int right, int* tmp)
{
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int index = left;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] <= a[begin2])
tmp[index++] = a[begin1++];
else
tmp[index++] = a[begin2++];
}
while (begin1 <= end1)
tmp[index++] = a[begin1++];
while (begin2 <= end2)
tmp[index++] = a[begin2++];
memcpy(a+left, tmp+left, sizeof(int)*(right - left+1));
}
//k用来表示每次k个元素归并
void mergePass(int *arr, int k, int n, int *temp)
{
int i = 0;
//从前往后,将2个长度为k的子序列合并为1个
while(i < n - 2*k + 1)
{
merge(arr, i, i + k - 1, i + 2*k - 1, temp);
i += 2*k;
}
//合并区间[i, n - 1]有序的左半部分[i, i + k - 1]以及不及一个步长的右半部分[i + k, n - 1]
if(i < n - k )
{
merge(arr, i, i + k - 1,n-1, temp);
}
}
void MergeSortNonR(int *arr,int length)
{
int k = 1;
int *temp = (int *)malloc(sizeof(int) * length);
while(k < length)
{
mergePass(arr, k, length, temp);
k *= 2;
}
free(temp);
}
8、计数排序
void CountSort(int* a, int n)
{
int max=a[0],min=a[0];
for(int i=0;i<n;i++)
{
if(a[i]>max)
max=a[i];
if(a[i]<min)
min=a[i];
}
int range=max-min+1;
int* countArr=(int*)malloc(range*sizeof(int));
memset(countArr,0,sizeof(int)*range);
//1.统计次数
for(int i=0;i<n;++i)
countArr[a[i]-min]++;
//2.根据次数进行排序
int j=0;
for(int i=0;i<range;++i)
{
while(countArr[i]--)
a[j++]=i+min;
}
}