学习js数据结构与算法8—排序与搜索算法

排序和搜索算法

排序算法

    // 排序
    function ArrayList() {
        var arr = [];

        this.insert = function(item) {
            arr.push(item);
        };

        this.toString = function() {
            return arr.join();
        };

        // 冒泡排序
        // 从运行时间的角度来看,冒泡排序是最差的一个,复杂度O(n^2)
        this.bubbleSort = function() {
            var len = arr.length;
            // 如果从内循环减去外循环已跑过的轮数,就可以避免内循环中所有不必要的比较
            for (var i = 0; i < len; i++) {
                for (var j = 0; j < len - 1 - i; j++) {
                    if (arr[j] > arr[j + 1]) {
                        swap(j, j + 1);
                    }
                }
            }
        };
        function swap(m, n) {
            var tmp = arr[m];
            arr[m] = arr[n];
            arr[n] = tmp;
        }
        
        // 选择排序
        // 思路:找到数据中的最小值并将其放在第一位,接着找到第二小的放在第二位,以此类推
        // 时间复杂度也是O(n^2)
        this.selectionSort = function() {
            var len = arr.length,
                indexMin;

            for (var i = 0; i < len - 1; i++) {
                indexMin = i;
                for (var j = i; j < len; j++) {
                    if (arr[indexMin] > arr[j]) {
                        indexMin = j;
                    }
                }
                if (i !== indexMin) {
                    swap(i, indexMin);
                }
            }
        }

        // 插入排序
        // 排序小型数组时,比冒泡和选择排序性能要好
        this.insertionSort = function() {
            var len = arr.length,
                j, tmp;

            for (var i = 1; i < len; i++) {
                j = i;
                tmp = arr[i];
                while (j > 0 && arr[j - 1] > tmp) {
                    arr[j] = arr[j - 1];
                    j--;
                }
                arr[j] = tmp;
            }
        }

        // 归并排序
        // 是第一个可以被实际使用的排序算法,性能比前三个算法好,复杂度为O(nlog^n)
        // 归并排序是一种分治算法。其思想是将原始数组切分成较小的数组,直到每个小数组只有一个位置,
        // 接着将小数组归并成较大的数组,直到最后只有一个排序完毕的大数组
        this.mergeSort = function() {
            arr = mergeSortRec(arr);
        };
        var mergeSortRec = function(arr) {
            var len = arr.length;
            if (len === 1) {
                return arr;
            }

            var mid = Math.floor(len / 2),
                left = arr.slice(0, mid),
                right = arr.slice(mid, len);

            return merge(mergeSortRec(left), mergeSortRec(right));
        };
        var merge = function(left, right) {
            var res = [],
                l = 0,
                r = 0;

            while (l < left.length && r < right.length) {
                if (left[l] < right[r]) {
                    res.push(left[l++]);
                } else {
                    res.push(right[r++]);
                }
            }

            while (l < left.length) {
                res.push(left[l++]);
            }

            while (r < right.length) {
                res.push(right[r++]);
            }
            return res;
        };
        
        // 快速排序
        // 快排是最常用的排序算法,复杂度为O(nlog^n),且它的性能通常比其他的复杂度为O(nlog^n)的要好
        // 也使用分治的方法,将原始数组分成较小的数组
        this.quickSort = function() {
            quick(arr, 0, arr.length - 1);
        };
        var quick = function(arr, left, right) {
            var index;

            if (arr.length > 1) {
                index = partition(arr, left, right);

                if (left < index - 1) {
                    quick(arr, left, index - 1);
                }

                if (index < right) {
                    quick(arr, index, right);
                }
            }
        };
        var partition = function(arr, left, right) {
            var pivot = arr[Math.floor((left + right) / 2)],
                i = left,
                j = right;

            while (i <= j) {
                while (arr[i] < pivot) {
                    i++;
                }
                while (arr[j] > pivot) {
                    j--;
                }
                if (i <= j) {
                    swapQuick(arr, i, j);
                    i++;
                    j--;
                }
            }
            return i;
        };

        function swapQuick(arr, m, n) {
            var tmp = arr[m];
            arr[m] = arr[n];
            arr[n] = tmp;
        }
        
        
        // 搜索算法
        // 1.顺序搜索
        // 将每一个数据结构中的元素和我们要找的元素作比较。顺序搜索是最低效的一种搜索算法
        this.lowSearch = function(item) {
            for (var i = 0; i < arr.length; i++) {
                if (item === arr[i]) {
                    return i;
                }
            }
            return -1;
        };


        //2.二分搜索
        /* 
            这个算法要求被搜索的数据结构已排序
            步骤:
                1.选择数组的中间值
                2.如果选中的值是待搜索值,那么算法是执行完毕
                3.如果待搜索值比选中值要小,则返回步骤1并在选中值左边的子数组中寻找
                4.如果待搜索值比选中值要大,则返回步骤1并在选中值右边的子数组中寻找
        */
        this.binarySearch = function(item) {
            this.quickSort();
            
            var low = 0,
                high = arr.length - 1,
                mid, ele;
                
            while (low <= high) {
                mid = Math.floor((low + high) / 2);
                ele = arr[mid];
                
                if (ele < item) {
                    low = mid + 1;
                } else if (ele > item) {
                    high = mid - 1;
                } else {
                    return mid;
                }
            }
            
            return -1;
        };
    }

    // 创建未排序的数组
    function createNonSortedArray(size) {
        var arr = new ArrayList();
        for (var i = size; i > 0; i--) {
            arr.insert(i);
        }
        return arr;
    }

    var arr = createNonSortedArray(5);
    console.log(arr.toString());
    // arr.bubbleSort();
    // arr.selectionSort();
    // arr.insertionSort();
    // arr.mergeSort();
    arr.quickSort();
    console.log(arr.toString());
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335