排序查找算法

排序算法:

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;
        }

猜你喜欢

转载自blog.csdn.net/superyuan567/article/details/85041522