排序算法简单实现


cc.Class({
    extends: cc.Component,

    properties: {

    },

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {},

    start() {
        this.arr = [10, 9, 8, 7, 6, 5, 4, 8, 12, 11, 25, 3];
        // this.bubbleSort(this.arr);
        // this.bubbleSort2(this.arr);
        // this.selectionSort(this.arr);
        // this.insertionSort(this.arr);
        // this.shellSort(this.arr);
        // this.mergeSortS(this.arr);
        //this.quickSortS(this.arr);
        // this.heapSort(this.arr);
        // this.countingSortS(this.arr);
        //this.bucketSortS(this.arr);
        // this.radixSortS(this.arr);





    },
    /**
     * 冒泡排序算法
     * 从小到大排序
     * 相邻两个元素两两比较,交换位置
     */
    bubbleSort(arr) {
        let len = arr.length;
        let count = 0;
        for (let i = 0; i < len - 1; i++) {
            for (let j = 0; j < len - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    let min = arr[j + 1];
                    arr[j + 1] = arr[j];
                    arr[j] = min;
                    count++;
                }
            }

        }
        console.log(count);//执行了35次
        console.log(arr);
        return arr;
    },
    bubbleSort2(arr) {
        let len = arr.length;
        let count = 0;
        for (let i = 0; i < len - 1; i++) {
            for (let j = i + 1; j < len; j++) {
                if (arr[i] > arr[j]) {
                    let min = arr[j];
                    arr[j] = arr[i];
                    arr[i] = min;
                    count++;
                }
            }

        }
        console.log(count);//执行了34次
        console.log(arr);
        return arr;
    },
    /**
     * 选择排序
     * 从小到大排序
     * 从第一个元素开始向后查找,找到最小的,两两交换位置
     * @param {*} arr 
     */
    selectionSort(arr) {
        let len = arr.length;
        let minIndex, min;
        let count = 0;
        for (let i = 0; i < len; i++) {
            minIndex = i;
            for (let j = i + 1; j < len; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                    count++;
                }
            }
            min = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = min;
        }
        console.log(count);//执行了20次
        console.log(arr);
        return arr;
    },
    /**
     * 插入排序
     * 从第二个开始查找,找到比前一个小的,就交换位置
     * @param {*} arr 
     */
    insertionSort(arr) {
        let count = 0;
        let len = arr.length;
        let preIndex, current;
        for (let i = 1; i < len; i++) {
            preIndex = i - 1;
            current = arr[i];
            while (preIndex >= 0 && arr[preIndex] > current) {
                arr[preIndex + 1] = arr[preIndex];
                preIndex--;
                count++;
            }
            arr[preIndex + 1] = current;
        }
        console.log(count);//执行了35次;
        console.log(arr);
        return arr;
    },
    /**
     * 希尔排序
     * 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
     * @param {*} arr 
     */
    shellSort(arr) {
        let len = arr.length,
            temp,
            count = 0,
            gap = 1;
        while (gap < len / 3) {//动态定义间隔序列
            gap = gap * 3 + 1;
            count++;
        }
        for (gap; gap > 0; gap = Math.floor(gap / 3)) {
            for (let i = gap; i < len; i++) {
                temp = arr[i];
                for (var j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {
                    arr[j + gap] = arr[j];
                    count++;
                }
                arr[j + gap] = temp;
            }
        }
        console.log(count);//执行了24次
        console.log(arr);
        return arr;
    },
    /**
     * 由两个方法体组成的归并排序
     * 先自上而下的递归,然后自下而上的迭代
     * @param {*} arr 
     */
    mergeSortS(arr) {
        function mergeSort(arr) {
            let len = arr.length;
            if (len < 2) {
                return arr;
            }
            let middle = Math.floor(len / 2),
                left = arr.slice(0, middle),
                right = arr.slice(middle);
            return merge(mergeSort(left), mergeSort(right));
        }
        function merge(left, right) {
            let result = [];
            while (left.length && right.length) {
                if (left[0] <= right[0]) {
                    result.push(left.shift());

                } else {
                    result.push(right.shift());
                }
            }
            while (left.length) {
                result.push(left.shift());
            }
            while (right.length) {
                result.push(right.shift());
            }

            return result;
        }

        let dataArr = mergeSort(arr);
        console.log(dataArr);
        return dataArr;
    },
    /**
     * 快速排序
     * 从数列中挑出一个元素,称为 "基准"(pivot);
       重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
       递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
     * @param {*} arr 
     */
    quickSortS(arr) {
        function quickSort(arr, left, right) {
            let len = arr.length,
                partitionIndex,
                lefts = typeof left != 'number' ? 0 : left,
                rights = typeof right != 'number' ? len - 1 : right;

            if (lefts < rights) {
                partitionIndex = partition(arr, lefts, rights);
                quickSort(arr, lefts, partitionIndex - 1);
                quickSort(arr, partitionIndex + 1, rights);
            }
            return arr;
        }
        function partition(arr, left, right) {
            let pivot = left,
                index = pivot + 1;
            for (let i = index; i <= right; i++) {
                if (arr[i] < arr[pivot]) {
                    swap(arr, i, index);
                    index++;
                }
            }
            swap(arr, pivot, index - 1);
            return index - 1;
        }
        function swap(arr, i, j) {
            let temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        function partition2(arr, low, high) {
            let pivot = arr[low];
            while (low < high) {
                while (low < high && arr[high] > pivot) {
                    --high;
                }
                arr[low] = arr[high];
                while (low < high && arr[low] <= pivot) {
                    ++low;
                }
                arr[high] = arr[low];
            }
            arr[low] = pivot;
            return low;
        }
        function quickSort2(arr, low, high) {
            if (low < high) {
                let pivot = partition2(arr, low, high);
                quickSort2(arr, low, pivot - 1);
                quickSort2(arr, pivot + 1, high);

            }

            return arr;
        }

        let dataArr = quickSort(arr);
        console.log(dataArr);
        let dataArr2 = quickSort2(arr);
        console.log(dataArr2);
        return dataArr || dataArr2
    },
    /**
     *  堆排序
     *  类似于二叉树的结构
     *  创建一个堆 H[0……n-1];
        把堆首(最大值)和堆尾互换;
        把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
        重复步骤 2,直到堆的尺寸为 1。
     * @param {*} arr 
     */
    heapSort(arr) {
        let len;
        function buildMaxHeap(arr) {  //建立大顶堆(类似于树形图)
            len = arr.length;
            for (let i = Math.floor(len / 2); i >= 0; i--) {
                heapify(arr, i);
            }
        }
        function heapify(arr, i) {
            let left = 2 * i + 1,
                right = 2 * i + 2,
                largest = i;
            if (left < len && arr[left] > arr[largest]) {
                largest = left;
            }
            if (right < len && arr[right] > arr[largest]) {
                largest = right;
            }
            if (largest != i) {
                swap(arr, i, largest);
                heapify(arr, largest);
            }
        }
        function swap(arr, i, j) {
            let temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;

        }
        function heapSort(arr) {
            buildMaxHeap(arr);
            for (let i = arr.length - 1; i > 0; i--) {
                swap(arr, 0, i);
                len--;
                heapify(arr, 0);
            }
            return arr;
        }
        let dataArr = heapSort(arr);
        console.log(dataArr);
        return dataArr;
    },
    /**
     * 计数排序
     * 操作原理,类似于映射原理。确定数组的最大长度,然后建立一个0-n的已排序列。一一映射数组元素到改序列中。然后从该序列中从小到大,拿出数组的元素,顺序加入数组中
     * (1)找出待排序的数组中最大和最小的元素
       (2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项
       (3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
       (4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1
     * @param {*} arr 
     */
    countingSortS(arr) {
        function countingSort(arr, maxValue) {
            let bucket = new Array(maxValue + 1),
                sortedIndex = 0,
                arrLen = arr.length,
                bucketLen = maxValue + 1;
            for (let i = 0; i < arrLen; i++) {
                if (!bucket[arr[i]]) {
                    bucket[arr[i]] = 0;

                }
                bucket[arr[i]]++;
            }
            for (let j = 0; j < bucketLen; j++) {
                while (bucket[j] > 0) {
                    arr[sortedIndex++] = j;
                    bucket[j]--;
                }
            }
            return arr;
        }
        function maxValueNumber(arr) {
            let max = arr[0];
            for (let h = 1; h < arr.length; h++) {
                if (arr[h] >= max) {
                    max = arr[h];
                }
            }
            return max;
        }

        arr = countingSort(arr, maxValueNumber(arr));
        console.log(arr);
        return arr;
    },
    /**
     * 桶排序
     * 操作原理:利用映射原理,将数组中元素平均映射到每个桶中,每个桶有数值范围。然后在桶中进行排序
     * @param {*} arr 
     */
    bucketSortS(arr) {
        return;//此方法测试有问题
        function bucketSort(arr, bucketSize) {
            if (arr.length === 0) {
                return arr;
            }

            let i;
            let minValue = arr[0];
            let maxValue = arr[0];
            for (i = 1; i < arr.length; i++) {
                if (arr[i] < minValue) {
                    minValue = arr[i];                // 输入数据的最小值
                } else if (arr[i] > maxValue) {
                    maxValue = arr[i];                // 输入数据的最大值
                }
            }

            //桶的初始化
            let DEFAULT_BUCKET_SIZE = 5;            // 设置桶的默认数量为5
            //bucketSize = bucketSize || DEFAULT_BUCKET_SIZE;
            bucketSize = bucketSize ? bucketSize : DEFAULT_BUCKET_SIZE;
            let bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;
            let buckets = new Array(bucketCount);
            for (i = 0; i < buckets.length; i++) {
                buckets[i] = [];
            }

            //利用映射函数将数据分配到各个桶中
            for (i = 0; i < arr.length; i++) {
                buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i]);
            }

            arr.length = 0;
            for (i = 0; i < buckets.length; i++) {
                this.insertionSort(buckets[i]);                      // 对每个桶进行排序,这里使用了插入排序
                for (let j = 0; j < buckets[i].length; j++) {
                    arr.push(buckets[i][j]);
                }
            }

            return arr;
        }
        arr = bucketSort(arr);
        console.log(arr);
        return arr;
    },
    /**
     * 基数排序
     * 
     * 基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
     * 基数排序:根据键值的每位数字来分配桶;
       计数排序:每个桶只存储单一键值;
       桶排序:每个桶存储一定范围的数值;
     * @param {*} arr 
     */
    radixSortS(arr) {
        let counter = [];
        function radixSort(arr, maxDigit) {
            var mod = 10;
            var dev = 1;
            for (var i = 0; i < maxDigit; i++ , dev *= 10, mod *= 10) {
                for (var j = 0; j < arr.length; j++) {
                    var bucket = parseInt((arr[j] % mod) / dev);
                    if (counter[bucket] == null) {
                        counter[bucket] = [];
                    }
                    counter[bucket].push(arr[j]);
                }
                var pos = 0;
                for (var j = 0; j < counter.length; j++) {
                    var value = null;
                    if (counter[j] != null) {
                        while ((value = counter[j].shift()) != null) {
                            arr[pos++] = value;
                        }
                    }
                }
            }
            return arr;
        }
        arr = radixSort(arr, 25);
        console.log(arr);
        return arr;
    }

   //利用js 特性排序
   sort (arr) {
    let a0=[];
    arr.forEach(item => {
        a0[item]=item;
    });
    let a1=[];
    let len=0;
    console.log(a0);
    for (let i = 0; i < a0.length; i++) {
        const element = a0[i];
        if(element){
            a1[len]=element;
            len++;
        }   
    }
    console.log(a1);
}
    // update (dt) {},
});

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值