【数据结构】【内部排序总结(C++)之选择排序】

 

选择排序的基本思想是:每一趟在n-i+1(i=1,2,3,……n-1)个记录中选取关键字最小的记录作为有序序列中的第i个记录。

 

  1. 简单选择排序:
  • 以n=5(【a1,a2,a3,a4,a5】)为例,将序列分为两部分,初始序列为【】+【a1,a2,a3,a4,a5】,选择排序每一趟排序的结果是:选择右边序列的最小元素加入左边序列的末尾。
  • 代码:
    #include<iostream>
    using namespace std;
    const int N=10;
    void SelectSort(int a[])
    {
        cout<<"Before sort:";
        for(int i=0;i<N;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    
        for(int i=0;i<N;i++)
        {
            int pos=i;
            for(int j=i+1;j<N;j++)
            {
                if(a[j]<a[pos])
                    pos=j;
            }
            int temp=a[pos];
            a[pos]=a[i];
            a[i]=temp;
        }
    
        cout<<"after sort:";
        for(int i=0;i<N;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
        return ;
    }
    int main()
    {
        int a[N]={6,5,2,1,8,1,12,34,23,10};
        SelectSort(a);
        return 0;
    }
    

      

  • 时间复杂度:O(N2)。无论记录的初始排列如何,所需进行的关键字之间的比较次数相同,故时间复杂度与初始排列无关,总是O(N2)。
  • 效果图:

2.树形选择排序(Tree Selection Sort)(又称锦标赛排序Tournament Sort)

  • 出发点:简单选择排序的主要操作是关键字之间的比较,从减少“比较”出发:显然,在n个关键字中选出最小值,至少需要n-1次比较,然而从剩余的n-1个关键字中选择次小值,却并非一定要n-2次比较(可利用前次比较所得信息减少以后各趟排序所需比较次数)。
  • 基本思想:对n个记录的关键字进行两个一组的比较,然后再较小者之间继续两个一组比较……直至选出最小关键字。(构建出了一个完全二叉树,根节点最小)。选出次小关键字:将叶子节点中的最小关键字改为“最大值”,从该叶子节点开始,和其兄弟关键字比较,更新从叶子节点到根节点路径上个节点的关键值,则根节点为次小关键字。以此类推,,,直至排序完成。
  • 时间复杂度:O(nlogn) 除最小关键字外,每个次小关键字需约log2n次比较
  • 缺点:辅助空间大,和“最大值”进行多余比较

3. 堆排序(Heap Sort)

  • 只需一个记录大小的辅助空间,每个待排序记录仅占一个存储空间
  • 堆:是一个完全二叉树,可由一个数组实现。每个节点的值都大于等于(或小于等于)其左右孩子的值。
  • 定义:输出堆顶最小值后,使得剩余元素的序列重建成一个堆,则得到n个元素中的次小值。如此反复执行,便得到一个有序序列,这个过程称为堆排序。
  • 关键步骤:“筛选”(对于这样一个堆(:除堆顶元素外,均满足堆得定义,)将其自堆顶到叶子进行调整,从而变成一个新的堆)。
  • 代码:
    #include<iostream>
    using namespace std;
    const int N=11;
    void HeapAdjust(int a[],int s,int m)
    {
        int temp=a[s];
        for(int i=2*s; i<=m; i=i*2)
        {
            if(i<m && a[i]<a[i+1])
                i++;
            if(temp>a[i])
                break;
            a[s]=a[i];
            s=i;
        }
        a[s]=temp;
    
    }
    void HeapSort(int a[])
    {
        cout<<"before:";
        for(int i=1;i<N;i++)
            cout<<a[i]<<" ";
        cout<<endl;
        for(int i=N/2;i>0;i--)
        {
            HeapAdjust(a,i,N-1);
        }
    
        cout<<"heap:";
        for(int i=1;i<N;i++)
            cout<<a[i]<<" ";
        cout<<endl;
        for(int i=N-1; i>1;i--)
        {
            int temp=a[1];
            a[1]=a[i];
            a[i]=temp;
            HeapAdjust(a,1,i-1);
        }
        cout<<"after heap sort:";
        for(int i=1;i<N;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }
    int main()
    {
        int a[N]={0,6,5,2,1,8,1,12,34,23,10};
        HeapSort(a);
        return 0;
    }
    

      

  • 效果图:
  • 时间复杂度:O(NlogN)
  • 适用于n较大的文件,且最坏时间复杂度也为O(NlogN)
posted @ 2018-08-25 22:45  dreamer123  阅读(811)  评论(0编辑  收藏  举报