插入排序(基本插入,折半插入,二路插入)
(基本插入):需要一个哨兵位存放需要插入的值(这里把a[0]作为哨兵位)从第二个数开始插入,把第二个数放在a[0]里面,与前面的数一次进行比较
void InsertSort(int ar[],int n)
{
for(int i = 2;i<=n;++i)
{
ar[0] = ar[i];
for(int j = i-1;ar[0]<ar[j];--j)
ar[j+1] = ar[j];
ar[j+1] = ar[0];
}
}
(折半插入未做):
(二路插入):创建一个临时数组,用start和finish作为起始末尾下标
void TWayInsert(int ar[],int n)
{
int *tmp = (int*)malloc(sizeof(int)*n);
assert(tmp != NULL);
int start,finish;
start = finish = 0;
tmp[0] = ar[0];
for(int i=1;i<n;++i)
{
if(ar[i]<tmp[start])
{
start = (start-1+n)%n;
tmp[start] = ar[i];
}
else if(ar[i] > tmp[finish])
tmp[++finish] = ar[i];
else //start< <finish
{
tmp[++finish] = tmp[finish-1];
for(int j= finish-1;ar[i]<tmp[(j-1+n)%n];j = (j-1+n)%n)
tmp[j] = tmp[(j-1+n)%n];
tmp[j] = ar[i];
}
}
for(i=0;i<n;++i)
{
ar[i] = tmp[start];
start = (start+1)%n;
}
free(tmp);
}
希尔排序:引入增量dlta,把原始数据分割成很多小数组的插入排序
void ShellInsert(int ar[],int n,int dk)
{
int tmp;
for(int i=dk;i<n;++i)
{
if(ar[i]<ar[i-dk])
{
tmp = ar[i];
ar[i] = ar[i-dk];
for(int j=i-dk;j-dk>0;j-=dk)
{
if(tmp<ar[j-dk])
ar[j] = ar[j-dk];
else
break;
}
ar[j] = tmp;
}
}
}
void ShellSort(int ar[],int n)
{
int dlta[] = {5,3,2,1};
int k = sizeof(dlta)/sizeof(int);
for(int i=0;i<k;++i)
{
ShellInsert(ar,n,dlta[i]);
}
}
冒泡排序:比较相邻两个值的大小,如果前面的>后面的就交换位置。两个for循环,第一个for是趟数,1-5趟;第二个for是每趟循环
void InsertSort(int ar[],int n)
{
for(int i = 1;i<n;++i)
{
for(int j=0;j<n-i;++j)
{
if(ar[j]>ar[j+1])
{
int tmp = ar[j];
ar[j] = ar[j+1];
ar[j+1] = tmp;
}
}
}
}
快排:找一个数,左边 < 这个数 < 右边,再对左右进行递归
int Partition(int ar[],int low,int high)
{
int key = ar[low];
while(low<high)
{
while(low<high && ar[high]>=key)
high--;
Swap(ar[low],ar[high]);
while(low<high && ar[low]<=key)
low++;
Swap(ar[low],ar[high]);
}
return low;
}
void QuikSort(int ar[],int low,int high)
{
if(low<high)
{
int key_pos = Partition(ar,low,high);
QuikSort(ar,low,key_pos-1);
QuikSort(ar,key_pos+1,high);
}
}
选择排序:找最小值第一趟和a[0]换,第二趟和a[1]换
int FindMin(int ar[],int start,int finish)
{
int min_pos = start;
for(int i=start+1;i<=finish;++i)
{
if(ar[min_pos]>ar[i])
min_pos = i;
}
return min_pos;
}
void SelectSort(int ar[],int n)
{
for(int i=0;i<n;++i)
{
int min_pos = FindMin(ar,i,n-1);
Swap(ar[i],ar[min_pos]);
}
}
堆排序(未做)
归并排序(未做)
基数排序:不停的分发,回收数据,直到有序,Distribute,Collect(利用list库)
list<int> ls[10];
void Contribute(int ar[],int n,int k)
{
int tmp;
int x;
for(int i=0;i<n;++i)
{
tmp = ar[i];
x = k;
while(tmp && x > 0)
{
tmp /= 10;
x--;
}
ls[tmp%10].push_back(ar[i]);
}
}
void Collect(int ar[],int n)
{
int k = 0;
for(int i=0;i<n;++i)
{
while(!ls[i].empty())
{
ar[k++] = ls[i].front();
ls[i].pop_front();
}
}
}
void RadixSort(int ar[],int n)
{
for(int i=0;i<3;++i)
{
Contribute(ar,n,i);
Collect(ar,n);
}
}
Swap()方法
template<class Type>
void Swap(Type &a,Type &b)
{
Type tmp;
tmp = a;
a = b;
b = tmp;
}
测试代码:main()
#include<iostream>
#include<assert.h>
#include<list>
using namespace std;
void main()
{
int ar[] = {278, 109, 63, 930, 589, 184, 505, 269, 8, 83};
int n = sizeof(ar)/sizeof(int);
RadixSort(ar,n);//自己换Sort
for(int i=0;i<n;++i)
cout<<ar[i]<<" ";
cout<<endl;
}