五種基本的排序算法(JavaScript版)

排序算法一直都是筆試和麪試的一個必考點,這次我們就通過實例的講解,給出JavaScript版本的排序算法。
我們先初始化一個算法的構造函數,然後將各種排序算法都作爲方法寫在構造函數的內部,構造函數如下所示:

		function ArrayList() {
            var array = [];
            this.insert = function (item) {
                array.push(item);
            };

            this.toString = function () {
                return array.join();
            };
            // 交換變量的值
            function swap(index1, index2){
                var flag = array[index1];
                array[index1] = array[index2];
                array[index2] = flag;

            };
		}
		//構建數組實例
		function CreateSortArray(num) {
            var array = new ArrayList();
            for(var i = num; i > 0; i--){
                array.insert(i);
            }

            return array;
        }

冒泡排序 — 時間複雜度O(n^2)

冒泡雙循環,外層循環控制需要確立元素回到正確位置的次數,最後一個元素自動回到正確的位置上面;內層循環將相鄰的元素兩兩進行比較,如果第一個比第二個大,就交換他們,直至結束。因爲數組後面的元素已經是有序的,所以內層循環次數必須減去排序好元素的大小。
代碼如下:

this.bubbleSort = function () {
    for(var i = 0; i < array.length; i++)
        for(var j = 0; j < array.length - 1 - i; j++) 
                    {
                        if(array[j] > array[j + 1])
                        {
                            swap(j, j + 1);
                        }
                    }
            };

選擇排序 – 時間複雜度O(n^2)

算法思想: 首先我們假定第一個元素爲最小的元素,在後面的元素中找出最小的,與第一個進行位置交換,若第一個本身都是最小的,我們則不變位置,以此類推,得到數組的升序排列。
代碼如下:

			this.selectionSort = function () {
                var length = array.length;
                for(var i = 0; i < length - 1; i++){
                    indexMin = i;
                    for(var j = i + 1; j < length; j++)
                    {
                        if(array[i] > array[j])
                        {
                            indexMin = j;
                        }
                    }
                    if(i !== indexMin)
                    {
                        swap(i, indexMin);
                    }
                }
            };

插入排序 — 時間複雜度O(n^2)

算法思想:假定第一個元素是已經排過序的,後面的元素與前面的元素進行比較,比自身大的就交換位置,小的則位置不變。
代碼如下:

			this.insertionSort = function () {
                var temp;
                for(var i = 1; i < array.length; i++)
                {
                    j = i;
                    temp = array[i];
                    while(j > 0 && array[j] < array[j - 1])
                    {
                        array[j] = array[j - 1];
                        j--;
                    }
                    array[j] = temp;
                }

                return array;
            };

歸併排序 — 時間複雜度O(nlog * n)

算法思想:使用遞歸將一個大的數組分成n(n代表數組的長度)個只有一個元素的列表,然後再使用合併算法進行合併,相當於數組拆分,再給元素進行排序合併,效果圖如下:
完全二叉樹
在理解了思想後,我們來看看代碼:

		this.mergeSort = function () {
                array = mergeSortRec(array);
            };

            var mergeSortRec = function (array) {
                var length = array.length;
                if(length === 1)
                {
                    return array;
                }
                var mid = Math.floor(length / 2);
                var left = array.slice(0, mid);
                var right = array.slice(mid, length);

                return merge(mergeSortRec(left), mergeSortRec(right));
            };

            var merge = function (left, right) {
                var result = [];
                var 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++]);
                    }
                }

                while(il < left.length)
                {
                    result.push(left[il++]);
                }

                while(ir < right.length)
                {
                    result.push(right[ir++]);
                }

                return result;
            };

快速排序 — 時間複雜度O(nlog^n)

算法思想:我們先從數組的中間確定一個元素爲主元,將其劃分爲無限小的序列,然後從數組的頭部確立頭指針,尾部確立尾指針。依次與主元進行比較,左邊比主元大的,右邊比主元小的,將依次交互位置,重複 以上操作,實現快速升序排列,快速排序的性能比其它同複雜度的要好。
代碼如下:

		this.quickSort = function() {
                quick(array, 0, array.length - 1);
            };
            var quick = function (array, left, right){
                var index;
                if(array.length > 1){
                    index = partition(array, left, right);
                    if(left < index - 1){
                        quick(array, left, index - 1);
                    }
                    if(index < right){
                        quick(array, index, right);
                    }
                }
            };

            var partition = function (array, left, right) {
                var provt = array[Math.floor((left + right) / 2)];
                var i = left,
                    j = right;

                while(i <= j) {
                    while(array[i] < provt) {
                        i++;
                    }
                    while(array[j] > provt) {
                        j--;
                    }

                    if(i <= j) {
                        swapQuickSort(array, i, j);
                        i++;
                        j--;
                    }
                }

                return i;
            };

            var swapQuickSort = function (array, index1, index2) {
                var flag = array[index1];
                array[index1] = array[index2];
                array[index2] = flag;
            };

二分搜索法

算法思想: 在數組中尋找一個特定的值,我們可以從數組的中間將其分隔開,當然前提是數組是已經排序過的,同中間值進行比較,然後重複之前的操作,直至找出來要比較的值。
代碼如下:

			this.binarySearch = function (item) {
                this.quickSort();    //使用快排進行排序
                var low = 0,
                    high = array.length - 1,
                    mid,
                    element;

                while(low <= high){
                    mid = Math.floor((low + high) /2);
                    element = array[mid];

                    if(item < element) {
                        high = mid - 1;
                    }else if(item > element){
                        low = mid + 1;
                    }else{
                        return mid;
                    }
                }

                return -1;
            };

代碼測試

		var array = new CreateSortArray(5);
        console.log(array.toString());
        array.bubbleSort();
        console.log(array.toString());
        array.selectionSort();
        console.log(array.toString());
        array.insertionSort();
        console.log(array.toString());
        array.mergeSort();
        console.log(array.toString());
        array.quickSort();
        console.log(array.toString());
        console.log(array.binarySearch(1));

效果圖如下所示:
執行結果
源碼:git源碼地址
以上就是對算法的一些複習,如果有什麼不足,望大家指出來,一起進步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章