排序算法

#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;
}

 

posted on 2017-05-21 21:18  zhaodun  阅读(264)  评论(0编辑  收藏  举报

导航