排序查找算法

排序算法:

1. 冒泡排序

冒泡排序通过比较相邻两个值的大小进行两两比较,顺序相反,则交换两者位置。这样,每一趟会将最小或最大的元素浮到末尾位置。

//冒泡排序
        function bubbleSort(array){
            var temp;
            for (var i = 0; i < array.length - 1; i++){
                for (var j = 0; j < array.length-1-i; j++){
                    if (array[j]>array[j+1]){
                        temp = array[j];
                        array[j] = array[j+1];
                        array[j+1] = temp;
                    }
                }
            }
            return array;
        }

外圈表示执行的趟数,每执行一趟就可以确定一个最大值或最小值。内圈表示两两进行比较的次数。

冒泡排序的时间复杂度计算过程:循环次数为(n-1)+(n-2)+(n-3)+…+1=(n-1)n/2。所以时间复杂度为O(n^2)。
其实这个程序还可以更简单,我们考虑,当循环完一趟之后,发现排序完的数组跟之前的数组没有变化,就说明这时已经排序好了。
因此,程序更改为:

function bubbleSort(array){
            var temp;
            for (var i = 0; i < array.length - 1; i++){
                var flag = false;           //加一个标记,若执行完一趟之后结果没有改变,就说明已排序完成,则跳出循环。
                for (var j = 0; j < array.length-1-i; j++){
                    if (array[j]>array[j+1]){
                        temp = array[j];
                        array[j] = array[j+1];
                        array[j+1] = temp;
                        flag = true;
                    }
                }
                if(!flag){
                    break;
                }
            }
            return array;
        }

2.简单选择排序

简单选择排序就是每趟通过比较所有元素的值,选出最小的元素放到首位。看程序

用min来记录当前趟中最小值的位置,找到最小值的位置之后,再进行交换。

        //简单选择排序
        function selectSort(array){
            for (var i = 0; i < array.length-1; i ++){
                var min = i,
                    temp;
                for (var j = i + 1; j < array.length; j ++){
                    if (array[j] < array[min]){
                        min = j;
                    }
                }
                temp = array[i];
                array[i] = array[min];
                array[min] = temp;
            }
            return array;
        }

计算复杂度:(n-1)+(n-2)+(n-3)+…+1=n(n-1)/2,时间复杂度为O(n^2)

3. 直接插入排序

function insertSort(array){
    for (var i = 1; i < array.length; i++){
             if(array[i] < array[i-1]){
                 //array[i]值和array[i]之前的值比较并移位
                 var temp = array[i];    //保存第i位的值
                 var k = i-1;
                 for (var j = k; j >= 0 && temp < array[j]; j --){
                     array[j+1] = array[j];
                     k--;
                 }
                 array[k+1] = temp;   //插入正确的位置
             }
     }
     return array;
 }

4. 希尔排序

希尔排序就是将待排序序列分成几个子序列,分别再进行直接插入排序。

//希尔排序
        function shellSort(array){
            var gap = 1,
                len = array.length,
                temp;
            while(gap<len/3){
                gap = gap * 3 + 1;    //动态定义间隔序列
            }
            for(gap; gap > 0; gap = Math.floor(gap / 3)){          //根据gap值确定循环趟数,直到gap=0时循环停止
                for (var i = gap; i < len ; i++){
                    temp = array[i];
                    for (var j = i - gap; j>=0&&temp<array[j]; j-=gap){
                        array[j+gap] = array[j] ;
                    }
                    array[j+gap] = temp;
                }
            }
            return array;
        }

查找算法

1.顺序查找

function sequentialSearch(array,n){
            for (var i = 0; i < array.length; i++){
                if (array[i] === n){
                    return i;
                }
            }
            return -1;    //没有找到
        }

执行次数为n次,所以时间复杂度为O(n)

2.二分查找

二分查找(又称为折半查找)是在有序序列中查找比较多的查找算法,基本思路:设有一个从小到大的序列,取中间的元素m进行比较,如果等于需要查找的元素x则返回元素m的下标,若x大于m则再从右边的区间查找,若x小于m则再从左边的区间查找,这样每次减少一半的查找范围。时间复杂度为O(log2(n)),查找速度相对顺序查找要快很多,但是查找的数据序列必须是有序序列(即数据是从小到大或从大到小排序的)。

function binarySearch(array,n){
            var left = 0,
                right = array.length - 1,
                mid = Math.floor((left+right)/2);
            while(left<=right){
                if(array[mid] === n){
                    return mid;
                }else if(array[mid] > n){
                    right = mid - 1;
                }else{
                    left = mid + 1;
                }
            }
            return -1;
        }

3.插值查找

基于二分查找算法,将查找点的选择改进为自适应选择,可以提高查找效率。当然,差值查找也属于有序查找。

注:对于表长较大,而关键字分布又比较均匀的查找表来说,插值查找算法的平均性能比折半查找要好的多。反之,数组中如果分布非常不均匀,那么插值查找未必是很合适的选择。

function interpolationSearch(array,n){
            var left = 0,
                right = array.length - 1,
                mid;
            while(left<=right){
                mid = Math.floor(left+((n-array[left])/(array[right]-array[left]))*(right-left));
                if(array[mid] === n){
                    return mid;
                }else if(array[mid] > n){
                    right = mid - 1;
                }else{
                    left = mid + 1;
                }
            }
            return -1;
        }
package com.chehejia.esdqa.cclientautotest.testcase.aisp_aggregation_api.car_state;

import lombok.extern.slf4j.Slf4j;

/**
 * @author wangliyuan
 * @date 2021/9/1 11:10
 */
@Slf4j
public class MyTest {
    public static int[] arr = new int[]{6, 5, 4, 10, 8, 3};
    public static int[] arr1 = new int[]{3, 4};
    public static int[] bubbleSort(int[] arr){
        int len = arr.length;
        for(int i = 0; i < len; i ++){
            int temp;
            int lastSwap = 0;
            for(int j = 0; j < len - i -1; j++){
                if(arr[j + 1] < arr[j]){
                    temp = arr[j + 1];
                    arr[j + 1] = arr[j];
                    arr[j]  = temp;
                    lastSwap ++;

                }
            }
            if(lastSwap == 0){
                break;
            }
        }

        return arr;

    }

    //直接选择排序

    public static int[] straightSelectSort(int[] arr){
        int len = arr.length;
        for(int i = 0; i < len-1; i ++){
            int min = i;
            int temp;
            for (int j = i + 1; j < len; j++){
                if(arr[j] < arr[min]){
                    min = j;
                }

            }
            if(min != i){
                temp = arr[i];
                arr[i] = arr[min];
                arr[min] = temp;
            }

        }
        return arr;
    }

    //直接插入排序
    public static int[] straintInsertSort(int[] arr){
        int len = arr.length;
        for (int i = 1; i < len; i++){
            int j = i - 1;
            int temp = arr[i];
            while (j >=0 && arr[j] > temp){
                arr[j + 1] = arr[j];
                j = j -1;
            }
            arr[j + 1] = temp;
        }
        return arr;


    }

    //快速排序
    public static int partition(int[] arr, int left, int right){
        int temp = arr[left];     //基准值
        while(left < right){
            while(arr[right] >= temp && right > left){
                right --;
            }
            if(right > left){
                arr[left] = arr[right];
            }
            while(left < right && arr[left] <= temp){
                left ++;
            }
            if(left < right){
                arr[right] = arr[left];
            }
        }
        arr[left] = temp;
        return left;

    }

    public static int[] quickSort(int[] arr, int left, int right){

        if(left < right){
            int partitionIndex = partition(arr, left, right);
            quickSort(arr, left, partitionIndex - 1);
            quickSort(arr, partitionIndex + 1, right);

        }
        return arr;

    }

    //堆排序
    public static int[] heapSort(int[] arr){
        int len = arr.length;
        for(int i = len-1; i > 0; i --){
            sort(arr,0, i);
        }
        return arr;
    }

    public static void sort(int[] arr, int startIndex, int endIndex){

        int index = startIndex + 1;
        while(index <= endIndex){
            //父节点 (i-1)/2
            //左节点  i * 2 + 1
            //右节点  i * 2 + 2
            int fatherNodeIndex = (index - 1)/2;
            if(arr[index] > arr[fatherNodeIndex]){
                int temp = arr[index];
                arr[index] = arr[fatherNodeIndex];
                arr[fatherNodeIndex] = temp;

            }
            index ++;

        }
        //大顶堆获取第一个值和最后一个值交换位置
        int temp = arr[endIndex];
        arr[endIndex] = arr[0];
        arr[0] = temp;

    }

    //希尔排序
    public static int[] xierSort(int[] arr){
        int len = arr.length;
        int gap = len/2;
        while(gap > 0){
            for(int i = gap; i < len; i++){
                int j = i - gap;
                int temp = arr[i];
                while(j >= 0 && arr[j] >temp){
                    arr[j + gap] = arr[j];
                    j-=gap;
                }
                arr[j + gap] = temp;
            }
            gap = gap / 2;
        }
        return arr;
    }
    
    public static void main(String[] args) {
        xierSort(arr);
    }

}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值