• 选择排序


    概念

    选择排序:从排序的记录中选择出关键字最小的记录,顺序放在已排好的子文件的后面

    常用的方法

    直接选择法 、 堆排序

    直接排序的思想:n 个记录的文件的直接选择排序需要经过n-1次直接排序所得出结果

    void SelectSort(int *arr, int len)
    
    {
    
        int i,j;        // 为循环做准
    
        int iMin;        // 存储每次最小值
    
        int temp;        // 作为临时存储值
    
        for (i=0; i<len-1; i++)        // 进行len-1趟比较即可
    
        {
    
            iMin = i;                // 存储每次最小值
    
            for (j=i+1; j<len; j++)    // 第i次需要与之比较的数据
    
            {
    
                if (arr[iMin]>arr[j])
    
                {
    
                    iMin = j;        // 记录最小值的位置
    
                }
    
            }
    
            temp = arr[i];            // 交换
    
            arr[i] = arr[iMin];
    
            arr[iMin] = temp;
    
        }
    
    }

    直接排序的核心:确定待排序的的数据  、确定比较的数据、找出最小值、进行交换

    直接排序的算法性能分析

    直接选择排序和直接插入排序类似,都分为无序区、有序区、 区别:直接插入排序是将无序区的第一个元素直接插入到有序区;直接选择排序 把最小的元素放到最后

    例子

    void Selectsort(int a[], int n)
    {
        int i, j, nMinIndex;
        for (i = 0; i < n; i++)
        {
            nMinIndex = i; //找最小元素的位置
            for (j = i + 1; j < n; j++)
                if (a[j] < a[nMinIndex])
                    nMinIndex = j;
     
            Swap(a[i], a[nMinIndex]); //将这个元素放到无序区的开头
        }
    }

     堆排序

    堆排序类似于一个二叉树除了最底层之外其它层都是满的

    二叉堆 分为 最小堆和最大堆

    最大堆:每个父节点的元素大于等于 孩子的节点

    实现

    void AdjustMaxHeap(int a[], int i, int n)  
    {  
        int j, temp;  
        temp = a[i];        // 保存第i个结点值
        j = 2 * i + 1;        // 第i个结点的左孩子
        while (j < n)  
        {  
            if (j + 1 < n && a[j + 1] > a[j])    // 在左右孩子中找最大的  
                j++;                // 如果右孩子大,j就变成右孩子序号
            if (a[j] <= temp)            // 如果左右孩子的值都不大于父结点,就终止
                break;  
            a[i] = a[j];            // 把较大的子结点往上移动,替换它的父结点  
            i = j;                // 为下次循环做准备
            j = 2 * i + 1;  
        }  
        a[i] = temp;                          // 保存父结点的值,此时i是j的值,表示孩子的值
    
    }
    
    
    功能:建立初始堆(最大堆)
    思路:
    1、要想将初始文件R[1..n]调整为一个大根堆,就必须将它
    所对应的完全二叉树中以每一结点为根的子树都调整为堆。
    2、显然只有一个结点的树是堆,而在完全二叉树中,所有序号i>[n/2]([]向下取整)的
    结点都是叶子,因此以这些结点为根的子树均已是堆。
    3、我们只需依次将以序号为[n/2],[n/2]-1,...1的结点作为根的子树都调整为堆即可。
    4、由于c语言中数组下标从0开始,因此,第3点的序号改为[n/2]-1,[n/2]-2,...0
    
    
    void MakeMaxHeap(int a[], int n)  
    
    {  
    
        for (int i = n / 2 - 1; i >= 0; i--)    // 根结点序号
    
            AdjustMaxHeap(a, i, n);        // 为每个根结点调整,保存最大堆性质
    
    }
        1、建立初始堆
    
        2、每一趟最后一个数都与a[0]交换,并重新调整堆,
    
            使其保持堆的特性。
    
    */
    void MaxHeapSort(int a[], int n)  
    {  
    
        MakeMaxHeap(a,n);        // 建立初始堆
    
        for (int i = n - 1; i >= 1; i--)    // 对当前无序区a[1..i]进行堆排序,共做n-1趟
    
        {  
    
            int temp = a[i];    // 将堆顶和堆中最后一个记录交换
    
            a[i] = a[0];
    
            a[0] = temp;        
    
            AdjustMaxHeap(a, 0, i);    // 将a[0..i]重新调整为最大堆,仅有a[0]可能违反堆性质
    
        }  
    
    }  
    堆排序的算法性能分析
    堆排序是不稳定,但是它的平均时间复杂度和最差情况时间复杂度都是O(nlogn)
     
  • 相关阅读:
    201521123051 《Java程序设计》 第二周学习总结
    201521123001《Java程序设计》第11周学习总结
    201521123001《Java程序设计》第12周学习总结
    201521123001《Java程序设计》第11周学习总结
    201521123001《Java程序设计》第10周学习总结
    201521123001《Java程序设计》第9周学习总结
    201521123001《Java程序设计》第8周学习总结
    201521123001《Java程序设计》第7周学习总结
    201521123001《Java程序设计》第6周学习总结
    201521123001《Java程序设计》第5周学习总结
  • 原文地址:https://www.cnblogs.com/w6w6/p/11089690.html
Copyright © 2020-2023  润新知