javascript排序算法

// A code block
var foo = 'bar';
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>简单排序</title>
</head>

<body>
    <script>
        // 封装ArrayList
        function ArrayList() {
            this.array = []
            //封装添加数组方法
            ArrayList.prototype.insert = function (item) {
                this.array.push(item)
            }
            //分隔符
            ArrayList.prototype.toString = function () {
                return this.array.join()
            }
            //冒泡排序                                                                                                                        
            ArrayList.prototype.bubbleSort = function () {
                // 1.获取数组的长度                                                                                                                                                                                                                                              
                var length = this.array.length

                // 2.反向循环, 因此次数越来越少
                //第一次进来比较到倒数第一-1,第二次-2
                //遍历第一次排序完成最大的数据,所以最后一个数据不需要比较了所以i--
                for (var i = length - 1; i >= 0; i--) {
                    // 3.根据i的次数, 比较循环到i位置
                    for (var j = 0; j < i; j++) {
                        // 4.如果j位置比j+1位置的数据大, 那么就交换
                        if (this.array[j] > this.array[j + 1]) {
                            // 交换
                            this.swap(j, j + 1)
                        }
                    }
                }
            }
            //选择排序
            ArrayList.prototype.selectionSort = function () {
                // 1.获取数组的长度
                var length = this.array.length

                // 2.外层循环: 从0位置开始取出数据, 直到length-2位置
                //length - 1最后一个不需要排序
                for (var i = 0; i < length - 1; i++) {
                    // 3.内层循环: 从i+1位置开始, 和后面的内容比较
                    var min = i
                    for (var j = min + 1; j < length; j++) {
                        // 4.如果i位置的数据大于j位置的数据, 记录最小的位置
                        if (this.array[min] > this.array[j]) {
                            min = j
                        }
                    }
                    this.swap(min, i)
                }
            }
            //插入排序
            ArrayList.prototype.insertionSort = function () {
                // 1.获取数组的长度
                var length = this.array.length

                // 2.外层循环: 外层循环是从1位置开始, 依次遍历到最后
                //从1开始,把目的把0位置的数标记为局部有序
                for (var i = 1; i < length; i++) {
                    // 3.记录选出的元素, 放在变量temp中
                    var j = i
                    var temp = this.array[i]  //取出当前局部排序后,需要插入的数据

                    // 4.内层循环: 内层循环不确定循环的次数, 最好使用while循环
                    // 比较到j最少大于0, 
                    // this.array[j - 1]  > temp  局部排序的数,是否大于需要插入的
                    while (j > 0 && this.array[j - 1] > temp) {
                        //大于就交换位置j-- 然比较向前
                        //  如第一次 4 5 6 7 3 如第2次 4 5 6 3 7 
                        this.array[j] = this.array[j - 1]
                        j--
                    }

                    // 5.将选出的j位置, 放入temp元素(最后元素不满足以上条记录,找到对应位置赋值)
                    this.array[j] = temp
                }
            }
            //希尔排序 
            ArrayList.prototype.shellSort = function () {
                // 1.获取数组的长度
                var length = this.array.length

                // 2.根据长度计算增量
                var gap = Math.floor(length / 2)

                // 3.增量不断变量小, 大于0就继续排序
                while (gap > 0) {
                    // 4.实现插入排序
                    for (var i = gap; i < length; i++) {
                        // 4.1.保存临时变量
                        var j = i
                        var temp = this.array[i]  //这里获取存储

                        // 4.2.插入排序的内存循环
                        //然后这里通过如插入排序中的对比进行小组排序
                        //his.array[j - gap] 成为了0对比插入、
                        //j > gap - 1 限定不能出分组 
                        while (j > gap - 1 && this.array[j - gap] > temp) {
                            this.array[j] = this.array[j - gap]
                            j -= gap
                        }

                        // 4.3.将选出的j位置设置为temp
                        this.array[j] = temp
                    }

                    // 5.重新计算新的间隔,出循环时分组完成,再次进行分组、直至为间隔为1
                    gap = Math.floor(gap / 2)
                }
            }

            ArrayList.prototype.swap = function (m, n) {
                var temp = this.array[m]
                this.array[m] = this.array[n]
                this.array[n] = temp
            }

            // 选择枢纽
            ArrayList.prototype.median = function (left, right) {
                // 1.求出中间的位置
                var center = Math.floor((left + right) / 2)

                // 2.判断并且进行交换
                if (this.array[left] > this.array[center]) {
                    this.swap(left, center)
                }
                if (this.array[center] > this.array[right]) {
                    this.swap(center, right)
                }
                if (this.array[left] > this.array[right]) {
                    this.swap(left, right)
                }

                // 3.巧妙的操作: 将center移动到right - 1的位置.
                this.swap(center, right - 1)

                // 4.返回pivot
                return this.array[right - 1]
            }

            // 快速排序实现
            ArrayList.prototype.quickSort = function () {
                this.quickSortRec(0, this.array.length - 1)
            }

            ArrayList.prototype.quickSortRec = function (left, right) {
                // 0.递归结束条件 
                //索引位置相同就结束(如到中间)
                if (left >= right) return

                // 1.获取枢纽
                var pivot = this.median(left, right)

                // 2.开始进行交换
                var i = left //0左边起始位置
                var j = right - 1  //右边枢纽
                while (true) {
                    //判断右边位置先加,是否大于枢纽就停止(找比枢纽大的数)
                    while (this.array[++i] < pivot) { }
                    //判断右边位置先减,是否小于枢纽就停止(找比枢纽小的数)
                    while (this.array[--j] > pivot) { }
                    if (i < j) {  //比较获取获取到的数,然后进行交换位置,小的在左边,大的字在左边
                        this.swap(i, j)
                    } else { //当i >=j 的时候(说明两个指针查到同一值了,停止循环然后执外赋值)
                        break
                    }
                }

                // 3.将枢纽放在正确的位置(这里获取到的i和j都是在中间了)
                this.swap(i, right - 1)

                // 4.递归调用左边
                //再向左右分组递归再次排序
                this.quickSortRec(left, i - 1)
                this.quickSortRec(i + 1, right)
            }
        }

        // 初始化数据项
        var list = new ArrayList()
        list.insert(3)
        list.insert(6)
        list.insert(4)
        list.insert(2)
        list.insert(11)
        list.insert(10)
        list.insert(5)
        alert(list) // 3,6,4,2,11,10,5

        // 测试冒泡排序
        //    list.bubbleSort()
        //    alert(list) // 2,3,4,5,6,10,11

        // 测试选择排序
        //    list.selectionSort()
        //    alert(list) // 2,3,4,5,6,10,11

        // 测试插入排序
        //    list.insertionSort()
        //    alert(list) // 2,3,4,5,6,10,11

        // 测试希尔排序
        //    list.shellSort()
        //    alert(list)

        // 测试中位数选取
        //    // 原来的数组: 3,6,4,2,11,10,5
        //    var pivot = list.median(1, 6) // left:6 right:5 center:2
        //    alert(pivot) // pivot:5
        //    alert(list) // 3,2,4,10,11,5,6

        // 测试快速排序
        list.quickSort()
        alert(list)
    </script>
</body>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值