zoukankan      html  css  js  c++  java
  • 排序

    排序

    快速排序

    快速排序算法说下,基点怎么选?如果一个数组是已经排序好的怎么选基点?**

    • 数组元素随机,取固定基准;
    • 数组元素已排序或逆序,取随机基准;
    • 更好的方法:三数取中,选取数组开头,中间和结尾的元素,通过比较,选择中间的值作为快排的基准。

    优化

    • 数组较小时选择插入排序
    • 相同元素聚合

    这里效率最好的快排组合 是:三数取中+插排+聚集相等元素,它和STL中的Sort函数效率差不多

    聚集相同元素的话就是把相同的元素都聚集到中间,然后将左边和右边分开的时候可以减少一些元素。

    //快速排序
    function quickSort(arr){
        //debugger;
        let right = arr.length - 1
        quick(arr,0,right)
        console.log(arr)
    }
    
    
    function partition(arr,left,right){
        if (left < right) {  
                midu(arr, left, right);
                let pivot = right - 1;
                //左指针
                let i = left ;
                //右指针
               let j = right -1 ;
                while (j > i) {
                    while (j > i && arr[i] < arr[pivot]) {i++}
                    while (j > i && arr[j] >= arr[pivot]) {j--}
                    if (i < j) {
                        swap(arr, i, j);
                    }else{
                        break;
                    }
                  
                }
                if( i == j ) {swap(arr,i,pivot)}
                return i;
                
            }
    }
    function quick(arr,left,right){
        if(left < right){
            let i = partition(arr,left,right)
            quick(arr, left, i - 1);
            quick(arr, i + 1, right);
        }
        
            
    }
    
    function midu(arr,left,right){ 
        let mid = left+((right-left)>>1);// >> 优先级低于 + -
        //  也可以写成let mid =  Math.floor(left+right/2)
            if (arr[left] > arr[mid]) {
                swap(arr, left, mid);
            }
            if (arr[left] > arr[right]) {
                swap(arr, left, right);
            }
            if (arr[right] < arr[mid]) {
                swap(arr, right, mid);
            }
            swap(arr, right - 1, mid);
    }
    
    
    function  swap(arr,a,b){
        let temp = arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
    }
    

    归并排序

    //归并排序
    
    function  mergeSort(array){
        debugger;
        return  mergeSortRec(array);
    }
         
    function  mergeSortRec(array){
        var length = array.length; 
        if(length === 1) {  
        return array; }   
        var mid = Math.floor(length / 2), 
        left = array.slice(0, mid), 
        right = array.slice(mid, length); 
        return merge(mergeSortRec(left), mergeSortRec(right));
    }
    
    function  merge(left, right){
        var result = [], 
        il = 0,
        ir = 0; 
        while(il < left.length && ir < right.length) {    
            if(left[il] < right[ir]) {       
                result.push(left[il++]);    
            } else{       
                result.push(right[ir++]); // {10}     
            }   
        } 
        while (il < left.length){     // {11}     
            result.push(left[il++]);   
        } 
        while (ir < right.length){    // {12}     
            result.push(right[ir++]);  
        } 
        return result; // {13} 
        
    }
    

    插入排序

    //插入排序
    function insertSort(arr) {
        debugger;
        for(let i = 1; i < arr.length; i++) {
            let j, temp = arr[i];
            for(j = i; j > 0 && arr[j - 1] > temp; j --) {
                arr[j] = arr[j - 1];
            }
            arr[j] = temp;
        }
    }
    

    优化

    插入排序前面的元素是有序的,可以采用二分查找的方式

    堆排序

    function heapSort(array) {
        //debugger;   
        var heapSize = array.length;   
        buildHeap(array); //{1} 
        while (heapSize > 1) {     
            heapSize--;     
            swap(array, 0, heapSize); //{2}     
            heapify(array, heapSize, 0); //{3}   
        } 
        console.log(array)
    };
    
    
    //建堆
    function buildHeap(array){   
      var heapSize = array.length;   
      for (var i = Math.floor(array.length / 2); i >= 0; i--) {    
        heapify(array, heapSize, i);   
      } 
    };
    
    //父节点和两个子节点的比较过程
    function heapify(array, heapSize, i){
        var left = i * 2 + 1,
        right = i * 2 + 2,
        largest = i;
        if (left < heapSize && array[left] > array[largest]) {
            largest = left;
        }
        if (right < heapSize && array[right] > array[largest]) {
            largest = right;
        }
        if (largest !== i) {
            swap(array, i, largest);
            heapify(array, heapSize, largest);
        }
        
    };
    
    

    选择排序

    function selectionSort(arr) {
         debugger;
        // 选多少次
        for(let i = 0; i < arr.length - 1; i ++) {
            let minIndex = i;
            // 在arr[i + 1, ] 中找最小值索引, i+1 代表有序的下一个数,我们默认第一个元素是最小的
            for(let j = i + 1; j < arr.length; j ++) {
                if(arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            if(minIndex != i) {
                // 交换
                let temp = arr[minIndex]
                arr[minIndex] = arr[i]
                arr[i] = temp;
            }
        }
    }
    
    
    

    优化

    原来的选择排序是每次选择一个最小的值放在最前面

    改进措施:每次循环找到最大值和最小值,然后最小值和第一个交换,最大值和最后一个交换

    冒泡排序

    优化

    算法的稳定性:冒泡,快排,归并,基数是稳定的

  • 相关阅读:
    一片非常有趣的文章 三分钟读懂TT猫分布式、微服务和集群之路
    mysql+mycat搭建稳定高可用集群,负载均衡,主备复制,读写分离
    mycat读写分离+垂直切分+水平切分+er分片+全局表 测试
    LVS Nginx HAProxy 优缺点
    nginx map配置根据请求头不同分配流量到不同后端服务
    Javamail发送邮件
    java发送html模板的高逼格邮件
    学习openresty时,nginx的一个坑
    mysql数据导出golang实现
    mysql支持原生json使用说明
  • 原文地址:https://www.cnblogs.com/zhoujingguoguo/p/12602346.html
Copyright © 2011-2022 走看看