zoukankan      html  css  js  c++  java
  • 自己写的JS排序算法

    这学期刚刚学完数据结构,之前就自己写了一点东西,现在整理一下。

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>JS实现排序</title>
        <meta name="description" content="用JS自己写的排序算法">
        <meta name="keywords" content="JS,排序">
    </head>
    
    <body>
        <script type="text/javascript">
        //从小到大排序
        var a = [9, 2, 4, 1, 8, 7, 5, 3, 6];
        //第一种:简单冒泡排序
        function bubbleSort0(ar) {
            for (var i = 0; i < ar.length - 1; i++) { //a.length长的数组只要进行a.length-1次排序,0-a.length-2刚好为a.length-1的长度
                for (var j = i + 1; j < ar.length; j++) {
                    if (a[i] > a[j]) {
                        a[i] ^= a[j]; //交换两个数
                        a[j] ^= a[i];
                        a[i] ^= a[j];
                    }
                }
            }
        }
        bubbleSort0(a);
        console.log("简单冒泡排序:" + a);
    
        //第二种:正宗冒泡排序
        var a = [9, 2, 4, 1, 8, 7, 5, 3, 6];
        function bubbleSort(ar) {
            var flag = true;
            for (var i = 0; i < ar.length - 1 && flag; i++) { //a.length长的数组只要进行a.length-1次排序,0-a.length-2刚好为a.length-1的长度
                for (var j = ar.length - 1; j > i; j--) { //判断条件与下面的判断条件的边界值需要注意
                    flag = false; //默认标志为false,则当不进入下面括号的时候代表i之后的数已经排好了序,这里用的是上一轮排序的结果
                    if (a[j] < a[j - 1]) {
                        a[j] ^= a[j - 1];
                        a[j - 1] ^= a[j];
                        a[j] ^= a[j - 1];
                        flag = true; //当i后面有数据交换的时候则认为排序没有完成
                    }
                }
            }
        }
        bubbleSort(a);
        console.log("正宗冒泡排序:" + a);
    
        //第三种:简单选择排序
        var a = [9, 2, 4, 1, 8, 7, 5, 3, 6];
    
        function selectSort(ar) {
            for (var i = 0; i < ar.length - 1; i++) {
                var temp = i;
                for (var j = i + 1; j < ar.length; j++) {
                    if (a[j] < a[temp])
                        temp = j;
                }
                if (temp != i) {
                    a[i] ^= a[temp];
                    a[temp] ^= a[i];
                    a[i] ^= a[temp];
                }
            }
        }
        selectSort(a);
        console.log("简单选择排序:" + a);
    
        //第四种:插入排序
        var a = [0, 9, 2, 4, 1, 8, 7, 5, 3, 6]; //第一个0是放暂存数的,为了能让后面的数有空间挪动
        function insertSort(ar) {
            for (var i = 2; i < ar.length; i++) { //假设a[1]为已经排好序的数列,虽然只有一个数
                if (a[i] < a[i - 1]) { //当后面的数比前面的数小的时候
                    a[0] = a[i];
                    for (var j = i - 1; a[j] > a[0]; j--) //暂存位还可以起到比较的作用
                        a[j + 1] = a[j];
                    a[j + 1] = a[0];
                }
            }
            a[0] = 0; //小洁癖,还原暂存数位为0,美观
        }
        insertSort(a);
        console.log("插入排序:" + a);
    
        //第五种:希尔排序
        var a = [0, 9, 2, 4, 1, 8, 7, 5, 3, 6]; //第一个0是放暂存数的,为了能让后面的数有空间挪动
        function shellSort(ar) {
            var incre = ar.length - 1; //初始化递增量为数组内排序的数字的长度,不包括暂存位
            do {
                incre = parseInt(incre / 3) + 1; //经研究递增量为n/3+1,n/9+1,n/27+1……时的排序效率最高,这里取n/3+1方法
                for (var i = incre + 1; i <= ar.length - 1; i++) {
                    if (a[i] < a[i - incre]) {
                        a[0] = a[i];
                        for (var j = i - incre; j > 0 && a[j] > a[0]; j -= incre)
                            a[j + incre] = a[j];
                        a[j + incre] = a[0];
                    }
                }
            } while (incre > 1);
            a[0] = 0;
        }
        shellSort(a);
        console.log("希尔排序:" + a);
    
        //第六种:基数排序
        var b = [337, 332, 132, 267, 262, 164, 260, 167, 2000]; //测试基数排序的数组,定义大一点
        function radixSort(arr) {
            var i, j, k, lsd;
            var n = 1; //变量n,每次递增10倍
            var t = 1; //数字的最大位数递增量,从个位开始
            var temp = new Array(10); //创建一维数组
            var count = new Array(10);
            for (i = 0; i < 10; i++) {
                temp[i] = new Array(arr.length); //创建二维数组
            }
            for (i = 0; i < 10; i++) { //初始化二维数组和计数数组
                count[i] = 0;
                for (j = 0; j < arr.length; j++)
                    temp[i][j] = 0;
            }
            var numLength = getNumberLength(arr); //得到数的宽度,比如[337,1,22]得到为3,函数放在基数排序函数radixSort的最后
            while (t++ <= numLength) { //这里循环数组数字的位数进行统计和收集
    
                for (j = 0; j < arr.length; j++) { //统计
                    lsd = parseInt((arr[j] / n) % 10); //取得当前位数的数字
                    temp[lsd][count[lsd]++] = arr[j]; //将其存入二维数组temp
                }
                for (i = 0, k = 0; i < 10; i++) { //收集二维数组的计数存入原来的数组
                    if (count[i] != 0) //当前的数字统计有数
                        for (j = 0; j < count[i]; j++) //***计数数组的作用体现了,不用每次都把二维数组temp置0
                            arr[k++] = temp[i][j];
                    count[i] = 0;
                }
                n *= 10; //统计后一位数组
            }
    
            function getNumberLength(a) { //计算数组的数字的最大长度,比如[337,1,22]得到为3,放在最后没关系,JS有隐式提升
                var numberLength, max = 0;
                for (var i = 0; i < a.length; i++) {
                    var temp = a[i];
                    numberLength = 0;
                    while (temp >= 10) {
                        temp /= 10;
                        numberLength++;
                        if (temp < 10) {
                            numberLength++;
                            break;
                        }
                    }
                    if (numberLength > max)
                        max = numberLength;
                }
                return max;
            }
        }
        radixSort(b);
        console.log("基数排序:" + b);
    
        //第七种:快速排序
        var a = [10, 90, 20, 40, 50, 80, 70, 30, 60]; //第一个0是放暂存数的,为了能让后面的数有空间挪动
        function quickSort(ar, low, high) {
                var povit;
                if (low < high) {
                    povit = partition(ar, low, high);
                    quickSort(ar, low, povit - 1);
                    quickSort(ar, povit + 1, high);
                }
            }
            //求枢轴
        function partition(ar, low, high) {
            var povitkey;
            povitkey = ar[low]; //取最低的数作为枢轴
            var temp;
            while (low < high) {
                while (low < high && ar[high] >= povitkey)
                    high--;
                if (ar[high] != ar[low]) {
                    ar[high] ^= ar[low];
                    ar[low] ^= ar[high];
                    ar[high] ^= ar[low];
                }
                while (low < high && ar[low] <= povitkey)
                    low++;
                if (ar[high] != ar[low]) {
                    ar[high] ^= ar[low];
                    ar[low] ^= ar[high];
                    ar[high] ^= ar[low];
                }
            }
            return low;
        }
        quickSort(a, 0, a.length - 1);
        console.log("快速排序:" + a);
    
        //第八种:堆排序
        var a = [0, 50, 10, 90, 30, 70, 40, 80, 60, 20]; //第一个0是放暂存数的,为了能让后面的数有空间挪动
        function heapSort(ar) {
            var i;
            for (i = parseInt((ar.length - 1) / 2); i > 0; i--) { //构建大顶堆
                heapAdjust(ar, i, ar.length - 1);
            }
            for (i = ar.length - 1; i > 1; i--) {
                //交换两个数,ar[1]和ar[i]
                ar[1] ^= ar[i];
                ar[i] ^= ar[1];
                ar[1] ^= ar[i];
                heapAdjust(ar, 1, i - 1);
            }
        }
    
        function heapAdjust(ar, s, m) { //s为上标,m为下标
            var temp, j;
            temp = ar[s];
            for (j = 2 * s; j <= m; j *= 2) {
                if (j < m && ar[j + 1] > ar[j]) //当右孩子比左孩子大的时候
                    j++;
                if (temp > ar[j])
                    break;
                ar[s] = ar[j];
                s = j;
            }
            ar[s] = temp;
        }
        heapSort(a);
        console.log("堆排序:" + a);
        
        //第八种:堆排序改进
        var a = [50, 10, 90, 30, 70, 40, 80, 60, 20]; //第一个0是放暂存数的,为了能让后面的数有空间挪动
        function heapSort(ar) {
            var i;
            for (i = parseInt((ar.length - 1) / 2) - 1; i >= 0; i--) { //构建大顶堆
                heapAdjust(ar, i, ar.length - 1);
            }
            for (i = ar.length - 1; i >= 1; i--) {
                //交换两个数,ar[1]和ar[i]
                ar[0] ^= ar[i];
                ar[i] ^= ar[0];
                ar[0] ^= ar[i];
                if (i !== 1)
                    heapAdjust(ar, 0, i - 1);
            }
        }
    
        function heapAdjust(ar, s, m) { //s为上标,m为下标
            var temp, j;
            temp = ar[s];
            for (j = 2 * s; j <= m; j *= 2) {
                if (j < m && ar[j + 1] > ar[j]) //当右孩子比左孩子大的时候
                    j++;
                if (temp > ar[j])
                    break;
                ar[s] = ar[j];
                s = j;
            }
            ar[s] = temp;
        }
        heapSort(a);
        console.log("堆排序改进:" + a);
        </script>
    </body>
    
    </html>
    

    也不知道是不是最好的排序算法,学的时候是用的C语言写的,C语言的版本后面再整理吧,这里的都是JS的。

    感觉高级语言封装好了太多东西,像排序只要一个sort方法就搞定了,但是自己写完才知道,后面封装了太多东西,一个排序方法可能Brenden Eich(JS发明者)已经写了几百行代码。

    像Java,C#等等都封装了太多的基本代码在里面,感觉我们开发项目就是在组装电脑,拿起内存和硬盘看下型号插插插。最后剩下的就只有动手能力了。

    keep fighting!:)

     
  • 相关阅读:
    nginx通过多级代理获得真实用户IP的方法
    装饰器
    base64文件隐写脚本
    椭圆曲线加密
    mysql创建账号及管理权限
    Linux 中指定启动 tomcat 的 jdk 版本
    Linux 下创建 sftp 用户并限定目录
    linux 服务器脚本采集数据中文无法执行错误
    poi 读取使用 Strict Open XML 保存的 excel 文档
    win7 配置Windows Update 失败,还原更改,无法进入系统
  • 原文地址:https://www.cnblogs.com/manfredHu/p/4599416.html
Copyright © 2011-2022 走看看