#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stdlib.h>
using namespace std;
#define MAXSIZE 20
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define ET(a,b) ((a)==(b))
#define left(x) (2*x+1)
#define right(x) 2*(x+1)
typedef int KeyType;
//int i=0,j=0;
typedef struct
{
KeyType key;
//InfoType otherinfo;
}RedType;
typedef struct
{
RedType r[MAXSIZE+1];
int length;
}SqList;
bool is_friend(string a,string b)
{
if(a==b)
return false;
sort(a.begin(),a.end());
sort(b.begin(),b.end());
return a==b;
}
//void InsertSort(SqList &L)
//{
// for (i=2;i<L.length;++i)
// if (LT(L.r[i].key,L.r[i-1].key))
// {
// L.r[0]=L.r[i];
// L.r[i]=L.r[i-1];
// for (j = i-2; LT(L.r[0].key,L.r[j].key);--j)
// L.r[j+1]=L.r[j];
// L.r[j+1]=L.r[0];
// }
//}
void swap(int array[],int i,int j)
{
int temp=array[i];
array[i]=array[j];
array[j]=temp;
}
//插入排序
//最差情况下,直接插入排序的最大时间代价为θ(n²),最小时间代价为θ(n),平均时间代价为θ(n²)。
void InserSort(int array[],int n)
{
for (int i=1;i<n;++i)
{
for (int j=i;j>0;--j)
{
if (array[j]<array[j-1])
swap(array,j,j-1);
else
break;
}
}
}
//冒泡排序
//冒泡排序的最大时间代价,最小时间代价和平均时间代价均为θ(n²)。
void BubbleSort(int array[],int n)
{
for (int i=0;i<n-1;i++)
{
for (int j=n-1;j>i;--j)
{
if(array[j]<array[j-1])
swap(array,j,j-1);
}
}
}
// 选择排序的最大时间代价,最小时间代价和平均时间代价均为θ(n²)。选择排序不依赖于原始数组的输入顺序。
//选择排序
void SelectionSort(int array[],int n)
{
for (int i=0;i<n-1;++i)
{
int smallest=i;
for(int j=i+1;j<n;++j)
{
if(array[smallest]>array[j])
smallest=j;
}
swap(array,i,smallest);
}
}
//希尔排序
//增量为2的shell排序的时间代价可以达到θ(n的3/2次方),有的增量可以达到θ(n的7/6次方),很接近θ(n)。
void ShellSort(int array[],int n)
{
for(int delta=n/2;delta>0;delta/=2)
for(int i=0;i<delta;++i)
for(int j=i+delta;j<n;j+=delta)
for(int k=j;k>0;k-=delta)
if(array[k]<array[k-1])
swap(array,k,k-1);
}
//快速排序的最大时间代价为θ(n²),最小时间代价为θ(n*logn),平均时间代价为θ(n*logn)。
//快速排序
//构造轴点
int partition(int array[],int low,int high)
{
//以尾元素array[high]作为候选轴
int i=low-1;
for (int j=low;j<high;++j)//遍历low到high-1的元素
{
if(array[j]<array[high])
{
++i;
swap(array,i,j);
}
}
swap(array,high,(i+1));
return i+1;
}
void QuickSort(int array[],int low,int high)
{
if(low>high) return;
int q=partition(array,low,high);
QuickSort(array,low,q-1);
QuickSort(array,q+1,high);
}
//归并排序
//归并排序的最大时间代价,最小时间代价和平均时间代价均为θ(n*logn)。归并排序不依赖于原始数组的有序程度。
//归并过程--将两个有序的数组合并成一个有序数组
void merge(int array[],int left,int middle,int right)
{
int *tempArray = new int[right-left+1];
int index1=left;
int index2=middle+1;
int i=0;
while(index1<=middle&&index2<=right)
{
if (array[index1]<=array[index2])
tempArray[i++]=array[index1++];
else
tempArray[i++]=array[index2++];
}
while (index1<=middle)
tempArray[i++]=array[index1++];
while (index2<=right)
tempArray[i++]=array[index2++];
for(int j=0;j<i;++j)
array[left+j]=tempArray[j];
delete[] tempArray;
}
//递归大法好
void MergeSort(int* array,int left,int right)
{
if(left>=right||array==NULL) return;
//if(right-left<2) return ;
int middle=(left+right)/2;
MergeSort(array,left,middle);
MergeSort(array,middle+1,right);
merge(array,left,middle,right);
}
//堆排序
//堆排序的最大时间代价,最小时间代价和平均时间代价均为θ(n*logn)。堆排序和归并排序一样,不依赖于原始数组的有序程度。
//输入为要被排序的数组和根节点,数组a党组被维护的那部分的下表是low,high
void MaxHeapify(int* a,int i,int low,int high)
{
int l=left(i);
int r=right(i);
int largest=0;
if (l<=high&&a[l]>a[i])
largest=l;
else
largest=i;
if(r<high && a[r]>a[largest])
largest=r;
if(largest!=i)
{
swap(a,largest,i);
MaxHeapify(a,largest,low,high);
}
}
void BuildMaxHeap(int* a,int length)
{
for(int i=length/2-1;i>=0;--i)
MaxHeapify(a,i,0,length-1);
}
void HeapSort(int a[],int length)
{
BuildMaxHeap(a,length);
for(int i=length-1;i>=1;--i)
{
swap(a,0,i);
MaxHeapify(a,0,0,i-1);
}
}
//基数排序
//基数排序的时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的比较性排序法。
//基数排序法是属于稳定性的排序。
/*计算关键字位数的最大值*/
int KeySize(int array[],int size)
{
int keyMax=0;
for (int i=0;i<size;++i)
{
int temp=1;
int n=10;
while(array[i]/n)
{
temp++;
n*=10;
}
keyMax=(temp>keyMax)?temp:keyMax;
}
return keyMax;
}
//void RadixSort(int array[],int size)
//{
// int bucket[10][10]={0};//定义基数桶
// int order[10]={0};//保存每个基数桶之中的元素个数
// int keyMax=KeySize(array,size);
// for(int n=1;keyMax>0;n*=10,keyMax--)
// {
// //将待排序的元素按关键值得大小依次放入基数桶中
// for (int i=0;i<size;i++)
// {
// int lsd=(array[i]/n)%10;
// bucket[lsd][order[lsd]]=array[i];
// order[lsd]++;
// }
// //将基数桶中的元素重新串接起来
// int k=0;
// for(int i=0;i<10;++i)
// {
// if (order[i]!=0)
// {
// for (int j=0;j<order[j];++j)
// {
// array[k]=bucket[i][j];
// k++;
// }
// order[i]=0;
// }
// }
//
// }
//
//}
void RadixSort(int array[],int size)
{
int r=1;
int tmp[10];
int count[10];
int keyMax=KeySize(array,size);
for(int i=0;i<keyMax;i++)
{
for(int i=0;i<10;i++)//装桶之前要先清桶
count[i]=0;
for(i=0;i<size;i++) //记录每个桶的记录数
{
int k=array[i]/r;
int q=k%10;
count[q]++;
}
for(i=1;i<10;i++)//计算位置
{
count[i]+=count[i-1];
//cout<<count[i]<<" ";
}
for(int j=size-1;j>=0;j--)
{
int p=array[j]/r;
int s=p%10;
tmp[count[s]-1]=array[j];
count[s]--;
}
for(i=0;i<size;i++)
array[i]=tmp[i];
r=r*10;
}
}
//归并,快速和基数排序最常考
int main()
{
int array[10]={9,1,2,7,15,5,8,3,6,4};
//InserSort(array,10);//插入排序
//BubbleSort(array,10);//冒泡排序
//SelectionSort(array,10);//选择排序
//ShellSort(array,10);//希尔排序(属于插入排序)
//QuickSort(array,0,9);//快速排序
//MergeSort(array,0,9);//归并排序
//HeapSort(array,10);//堆排序(属于选择排序)
RadixSort(array,10);//未测试成功,待改进
for (int i=0;i<10;++i )
cout<<array[i]<<" ";
cout<<endl;
system("pause");
return 0;
}