zoukankan      html  css  js  c++  java
  • 选择排序-简单选择排序、堆排序算法

    选择排序是一类借助选择进行排序的方法,主要思想:每趟排序在当前待排序序列中选出关键码最小的记录,添加到有序序列中。特点是记录移动的次数较少。

    一、简单选择排序

    选择排序是一种简单直观的排序算法,无论什么数据进去都是O(n2) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。通俗来说就是你们中间谁最小谁就出列,站到队列的最后边,然后继续对着剩余的无序数组说你们中间谁最小谁就出列,站到队列的最后边,一直到最后一个,继续站到最后边,这样数组就有了顺序,从小到大。

    基本思想:

      第i趟排序在待排序序列arr[i]-arr[n](1<=i<=n-1)中选取关键码最小的记录并和第i个记录交换作为有序序列的第i个记录。

    function selectSort(arr){
        var len=arr.length;
        var temp;
        for(var i=0;i<len-1;i++){
            index=i;
            for(var j=i+1;j<len;j++){
                if(arr[j]<arr[index]){ // 寻找最小的数 保存索引
                    index=j;                   
                }
            }
            if(index!=i){
                temp=arr[index];
                arr[index]=arr[i];
                arr[i]=temp;
            }
        }
        return arr;
    }
    console.log(selectSort([4,3,2,1,5,6,7]));

     效率:

    时间复杂度:最好:O(N2),最坏:O(N2),平均:O(N2)。

    空间复杂度:O(1)。

    稳定性:不稳定

    二、堆排序

    首先明确完全二叉树概念:

      深度为k,有n个结点的二叉树当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称为完全二叉树。

    其次明确堆的概念:

      堆是具有以下性质的完全二叉树,每个结点的值小于或等于其孩子结点的值(小根堆),每个结点的值大于或等于其孩子结点的值(大根堆)

    堆排序分为两个过程:

    1.建堆。

      堆实质上是完全二叉树,必须满足:树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。堆分为:大根堆和小根堆,升序排序采用大根堆,降序排序采用小根堆。如果是大根堆,则通过调整函数将值最大的节点调整至堆的根结点。

      伪代码:

      1.设置i和j,分别指向当前要筛选的结点和要筛选结点的左孩子;

      2.若结点i已是叶子,则筛选完毕,算法结束;否则执行下述操作;

        2.1 将j指向结点i 的左右孩子的较大者;

        2.2 如果arrr[i]>arr[j],则筛选完毕,算法结束;

               2.3 如果arr[i]<arr[j],则将arr[i]与arr[j]交换;另i=j,转步骤2继续筛选;

    筛选法调整堆的算法:

    //筛选法调整堆函数
    function headAdjust(arr, k, m) {
        //将当前节点值(即将被筛选的节点)进行保存
        var i = k;
        var filter = arr[k];
        var temp;
        //定位到当前节点的左孩子节点
        var j = i * 2 + 1;
        //递归,直至没有子节点为止(筛选还没有进行到叶子)
        while (j < m) {
            //比较i的左右孩子,j指向较大者,如果当前节点有右边的子节点,并且右子节点较大,采用右子节点
            if (j + 1 < m && arr[j] < arr[j + 1]) {
                j++;
            }
    
            if (arr[i] > arr[j]) { //根节点已经大于孩子节点中的较大者
                break;
            } else {
                temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
                i = j;
                j = i * 2 + 1;
            }
        }
    }

    初始建堆:

    //初始建堆
    function buildHeap(arr) {
        //从最后一个分支节点到根节点
        for (var i = arr.length / 2; i >= 0; i--) {
            headAdjust(arr, i, arr.length);
        }
    }

    2.将堆的根结点保存于尾部,并对剩余序列调用调整函数,调整完成后,再将最大跟保存于尾部,再对剩余序列进行调整,反复进行该过程,直至排序完成。

    //堆排序函数
    function sort(arr) {
        //初始建堆
        buildHeap(arr);
        var len = arr.length;
        var temp;
        //从堆尾部开始调整
        /*for(var i=arr.length-1; i>0; i--){
          temp = arr[i];
          arr[i] = arr[0];
          arr[0] = temp;
          //进行调整,将最大元素调整至堆顶
          headAdjust(arr, 0, i);
        }*/
        //从堆首开始调整
        for (var i = 0; i < len; i++) {
            //堆顶永远是最大元素,故将堆顶和尾部元素交换,将最大元素保存于尾部,并且不参与后面的调整
            temp = arr[0];
            arr[0] = arr[len - (i + 1)];
            arr[len - (i + 1)] = temp;
    
            //进行调整,将最大元素调整至堆顶
            headAdjust(arr, 0, len - (i + 1));
        }
    }

    调用:

    var arr = [36, 30, 18, 40, 32, 45, 22, 50];
    console.log('before: ' + arr);
    sort(arr);
    console.log(' after: ' + arr);

     效率:

    时间复杂度:最好:O(nlog2n),最坏:O(nlog2n),平均:O(nlog2n)。

    空间复杂度:O(1)。

    稳定性:不稳定

  • 相关阅读:
    Saltstack安装及入门
    网络-flannel及calico
    vxlan 协议
    5G系统架构
    5G及移动边缘计算(MEC)学习笔记(3)
    linux 环境变量
    Python 包管理工具
    linux 后台运行程序
    训练测试样本划分
    kmeans 聚类 k 值优化
  • 原文地址:https://www.cnblogs.com/Iona/p/4724878.html
Copyright © 2011-2022 走看看