排序汇总

来源:互联网 发布:尚学堂大数据2017 编辑:程序博客网 时间:2024/06/05 07:00
#include <iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int a[11]= {5,6,2,1,10,9,4,8,3,7};
int b[11];
int n=10;
//插入排序:1.简单插入排序 2.折半插入排序 3.希尔排序
//直接插入排序
//基本有序的时候最好,比较次数与初始序列分布无关
//复杂度n^2,最好n
void Insertsort()
{
    int t;
    for(int i=1; i<n; i++)
    {
        int t=a[i];//哨兵
        //找要插入的位置
        for(int j=i-1; j>=0; --j)
        {
            if(a[j]>t)
                a[j+1]=a[j];
            else
            {
                a[j+1]=t;
                break;
            }
        }
    }
}
//折半插入,稳定,但基本有序时不如直接插入排序
//复杂度n^2
void BInsertsort()
{
    int t;
    for(int i=1; i<n; i++)
    {
        t=a[i];
        //找要插入的位置
        int left=0,right=i-1;
        int mid=(left+right)/2;
        while(left<=right)
        {
            if(t>a[mid])
                left=mid+1;
            else
                right=mid-1;
            mid=(right+left)/2;


        }
        for(int j=i-1; j>=right+1; j--)
            a[j+1]=a[j];
        a[right+1]=t;


    }
}
//希尔排序(缩小增量排序)
//复杂度n^2
//不保证每趟至少有一个元素在最终位置
void Shellsort()
{
    int gap=n;
    while(gap) //希尔增量
    {
        for(int i=0; i<gap; i++) //枚举0-gap
        {
            for(int j=gap+i; j<n; j+=gap) //间隔为gap
            {
                if(a[j] < a[j-gap]) //直接插入排序
                {
                    int temp = a[j];
                    int k;
                    for(k=j-gap; k>=0; k-=gap)
                    {
                        if(a[k] > temp) a[k+gap] = a[k];
                        else break;
                    }
                    a[k+gap] = temp;
                }
            }
        }
        gap/=2;
    }
}
//交换类1.快速排序2.冒泡排序
//冒泡排序
//比较次数与初始序列分布有关
void  Maopaosort()
{
    for(int i=0; i<n-1; i++)
    {
        for(int j=0; j<n-i-1; j++)
        {
            if(a[j]>a[j+1])
            {
                int t=a[j];
                a[j]=a[j+1];
                a[j+1]=t;
            }
        }
    }
}
//快速排序
void Quicksort(int l,int r)
{
    if(l>r) return ;
    int t=a[l];//基数从左边开始,所以从右边开始找
    int i=l,j=r;
    while(i!=j)
    {
        while(i<j&&a[j]>=t) j--;//从右边开始找
        while(i<j&&a[i]<=t) i++;
        if(i<j) swap(a[i],a[j]);
    }
    a[l]=a[i];//交换基数位置
    a[i]=t;
    Quicksort(l,i-1);
    Quicksort(i+1,r);
}
//选择类 1.简单选择排序2.堆排序
//简单选择排序
void Selectsort()
{




    for(int i=0; i<n-1; i++)
    {
        int pos=i;
        int min =a[i];
        for(int j=i+1; j<n; j++)
        {
            if(min>a[j])
            {
                min=a[j];
                pos=j;
            }
        }
        int t;//交换
        t=a[pos];
        a[pos]=a[i];
        a[i]=t;
    }
}
//堆排序


void Heap_Adjust(int*num,int i,int n)
{
    if(i<=n/2)//非叶子结点
    {
        int lch=2*i;
        int rch=2*i+1;
        int t=i;
        if(lch<=n&&num[lch]>num[t])//如果左孩子大于该节点,且不出界
            t=lch;
        if(rch<=n&&num[rch]>num[t])//如果有孩子大于该节点,且不出界
            t=rch;
        if(t!=i)//找出最大的元素置于上层,若堆发生调整,则需继续向下调整下层的元素(递归实现)
        {
            swap(num[i],num[t]);
            Heap_Adjust(num,t,n);
        }
    }
}
void Heap_build(int* num,int n)
{
    for(int i=n/2; i>=0; i--) //调整每个非叶子节点实现建立大顶堆
        Heap_Adjust(num,i,n);
}
void Heap_sort(int* num,int n)
{
    Heap_build(num,n);//建立大顶堆
    for(int i=n; i>=0; i--) //不断调整大顶堆取出堆顶元素
    {
        swap(num[0],num[i]);//交换根元素和尾元素
        Heap_Adjust(num,0,i-1);
    }
}
//归并类 1.归并排序
void mergearray(int l, int mid, int r)
{
    int temp[n+1];//辅助数组
    int i = l;
    int j = mid+1;
    int m = mid;
    int n = r;
    int cnt = 0;
    while(i <= m && j <= n)
    {
        if(a[i] <= a[j])
            temp[cnt++] = a[i++];
        else
            temp[cnt++] = a[j++];
    }
    while(i <= m)//两个数组比完多出来的部分
        temp[cnt++] = a[i++];
    while(j <= n)
        temp[cnt++] = a[j++];
    for(int i=0; i<cnt; i++)
        a[l + i] = temp[i];
}
void Unitesort(int l, int r)
{
    if(l < r)
    {
        int m = (l + r) / 2;
        Unitesort(l,m);//递归合并
        Unitesort(m+1,r);
        mergearray(l, m, r);
    }
}


//基数排序
int max_bit(int n)
{
    int ma=a[0],mi=a[0];
    for(int i=2;i<n;i++)
    {
        ma=max(ma,a[i]);
        mi=min(mi,a[i]);
    }
    int ma_len=0,mi_len=0;
    while(ma)
    {
        ma=ma/10;
        ++ma_len;
    }
    while(mi)
    {
        mi=mi/10;
        ++mi_len;
    }
    return max(ma_len,mi_len);
}
void Collect(queue<int>*q)
{
    int index=0;
    for(int i=0;i<20;i++)
    {
        while(!q[i].empty())
        {
            a[index]=q[i].front();
            index++;
            q[i].pop();
        }
    }
}
void bin_sort(int n)
{
    int len=max_bit(n);//找出被排序的数中最大数的位数
    queue<int> q[20];//队列数组(使用队列使排序算法稳定)
    int flag=1,in;
    while(len)
    {  flag=flag*10;
       for(int i=0;i<=n;i++)//取待排序项的各个位数并进入队列(考虑有负数的情况,即-1到-9压入q[1]到q[9],零到九压入q[10]到q[19]
     {
        in=a[i]%flag/(flag/10)+10;
        q[in].push(a[i]);
     }
     Collect(q);//从队列中将待排序项收集回num数组
     --len;
    }
}
int main()
{
    //插入类
    //Insertsort();
    //BInsertsort();
    //Shellsort();
    //交换类
    //Maopaosort();
    // Quicksort(0,n-1);
    //选择类
    //Selectsort();
    //Heap_sort(a,n-1);
    //归并类
    Unitesort(0,n-1);
    //基数排序
    //bin_sort(n-1);
    for(int i=0; i<n; i++)
    {
        if(i==0)
            printf("%d",a[i]);
        else
            printf(" %d",a[i]);
    }
    return 0;
}
原创粉丝点击