• 选择类排序


    1. 交换两个数————位运算

    static void swap(int *pa, int *pb)
    {				
        *pa ^= *pb;
        *pb ^= *pa;
        *pa ^= *pb;
              
             return;
    }
    

    2. 简单选择排序

    1. What:

    • 每一趟在无序区选择一个最小的元素。
    • 把所选中的无序区中的元素放到有序区中的最终位置上。
    • 算法效率与初始数据的顺序性无关,因为当序列为正序时不会减少比较的次数。

    2.How:

    static void selectSort(int a[], int n)
        {
    
            int i   = 0;
            int j   = 0;
            int Min = 0;
    
            for (i = 0; i < n-1; i++)       /* n 个数需要 n-1 的选择 */
            {
                Min = i;
                for (j = i+1; j < n; j++)   /* 从无序区中选择出最小的元素 */
                {
                    if (a[Min] > a[j])
                    {
                        Min = j;            /* 保存在无序区中的最小元素的下标 */
                    }
                }
    
                if (Min != i)
                {
                    swap(&a[Min], &a[i]);
                }
            }
    
            return;
        }
    

    3.Why:

    • 每一趟排序使得一个元素归位,有序区的元素一定小于(顺序)[大于(逆序)]无序区的元素,因此是全局有序的。
    • Min 用来保存无序区最小元素 的下标。
    • 算法的效率与初始数据的状态无关(无论逆序还是正序,比较次数都不会减少)。

    3. 堆排序

    1. What:

    • 是简单选择排序的改进
    • 初始建堆 ,a[0] 为哨兵,待排序元素存储在 a[1,n] 中
    • 将 a[1, n] 调整为堆,交换 a[1] 和 a[k] (k = n n-1 ... 2)

    2.How:

      /* 1. 完全二叉树调整为大根堆的算法 */
    static void shiftHeap (int a[], int low, int high)
    {
    
        int     i = low;
        int     j = 2*i;    /* a[j] 是 a[i] 的左孩子 */
    
        a[0] = a[i];        /* a[0] 临时备份数据*/
    
        while (j <= high)
        {
            /* j 指向较大的孩子 */
            if (j<high && a[j+1]>a[j]) /* 保证 j+1 有意义 */
            {
                j++;
            }
    
            if (a[j] > a[0])    /* 孩子结点大于父节点,需要调整 */
            {
                a[i] = a[j];
                i = j;
                j = 2*i;
            }
            else
            {
                break;
            }
        }
    
        a[i] = a[0];            /* 被筛选的节点放入最终的位置 */
    }
    
    
    static void heapSort (int a[], int n)
    {
        int     i = 0;
    
        for (i=n>>1; i>=1; i--)     /* 初始建立大根堆 */
        {
            shiftHeap(a,i,n);
        }
    
        for (i=n; i>=2; i--)        /* 每一趟将无序区中一个最大的元素归位,需要 n-1 趟 */
        {
            swap(&a[1],&a[i]);
    
            shiftHeap(a,1,i-1);
        }
    }
    

    3.Why:

    • 每一趟排序使得一个元素归位,是全局有序
    • 是一个在顺序表中的完全二叉树
    • 大根堆(不小于孩子节点) 小根堆(不大于孩子节点)
  • 相关阅读:
    面向对象设计技巧[Object Oriented Design Tips] 2
    面向对象设计的技巧[Object Oriented Design Tips]1
    36家示范性软件学院验收的得分排名顺序
    解决windows系统乱码(其实是法语)
    [maven] maven/appfuse 常用命令介绍
    [plsql] win7/64位 PL/SQL登录时报 ora12154无法解析指定的连接标识
    [maven] pom.xml常用配置介绍
    web.xml中classpath:和classpath*:的区别
    [http] 深入理解HTTP消息头
    [Hibernate] Hibernate连接mysql示范
  • 原文地址:https://www.cnblogs.com/hwfre/p/16047544.html
Copyright © 2020-2023  润新知