排序算法

一、稳定性

官方定义: 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
白话: 指的是排序之后,相同元素的相对位置有没有发生变化,如果变化了,就不稳定,如果没有变化,则相对稳定

举个例子就是:
比如:[12,3,15,12,35,34,6],使用冒泡排序的话,从大到小排序后为
[35,34,15,12,12,6,3],两个12的相对位置没有改变,所以相对稳定,如果使用快速排序,如果小于等于12,就放在12后边,那么两个12的相对位置就发生了改变,就不是很稳定!

二、各种排序算法复杂度
在这里插入图片描述
三、各种算法实现

之前的文章,有算法的动图演示

稳定排序

1、冒泡排序

数组原型上追加冒泡排序方法

        // 冒泡排序  从大到小排序  倒序/顺序
        Array.prototype.Maopao = function (sort = false) {
            var arr=this;
            if(arr.length<=1){
                 return arr;
             }
            for (var i = 0; i < arr.length - 1; i++) {//第几轮
                for (var k = 0; k < arr.length - 1 - i; k++) {//相邻的两个元素
                    //从小到大
                    if (sort == false) {
                        if (arr[k] > arr[k + 1]) {
                            temp = arr[k];
                            arr[k] = arr[k + 1];
                            arr[k + 1] = temp;
                        }
                    }
                    //从大到小
                    else {
                        if (arr[k] < arr[k + 1]) {
                            var temp = arr[k];
                            arr[k] = arr[k + 1];
                            arr[k + 1] = temp;
                        }
                    }

                }
            }
            return arr;
        }
        var arr2 = [18, 3, 1, 26, 7, 33, 6, 11];
        arr2.Maopao();

通过构造函数写

 function ArrayList(){
            this.array=[];
            //数据插入
            ArrayList.prototype.insert=function(item){
                this.array.push(item);
            }
            //冒泡排序
            ArrayList.prototype.maopao=function(){
                var length = this.array.length;
                for(var i=0;i<length-1;i++){
                    for(j=0;j<length-1-i;j++){
                        if(this.array[j]<this.array[j+1]){
                            var temp=this.array[j];
                            this.array[j]=this.array[j+1];
                            this.array[j+1]=temp;
                        }
                    }
                }
                console.log(this.array)
                return this.array;
            }
        }
        var arrs=new ArrayList();
        arrs.insert(34);
        arrs.insert(3);
        arrs.insert(6);
        arrs.insert(4);
        arrs.maopao();

2、插入排序

思想
插入排序与选择排序的区别
1、选择排序
首先在未排列的数组中找到最大/小值,存放到数组的起始序列,紧接着在剩下的数组中找到次大/小的值,递归进行
2、插入排序
类似于扑克牌,默认先插第一个元素,然后下一个元素如果比他大,就放在后面,如果比他小,就放在前面 冒泡
对于未排序数据,在已排序序列中从后向前扫描,找到相应位置

 //插入排序
        Array.prototype.InsertSort = function () {
            var arr = this;
            for (var i = 0; i < arr.length; i++) {
                var temp = arr[i];//标记值
                var j = i - 1;//默认已排序的元素
                //如果前面的值比后面的大,两个元素就交换一下位置
                while (j >= 0 && arr[j] > temp) {
                    arr[j + 1] = arr[j];
                    j--;//这里一定得记得!!!
                }
                arr[j + 1] = temp;
            }
            return arr;
        }
        var arrs = [1, 6, 3, 2, 45, 66, 34, 21];
        arrs.InsertSort();
        console.log(arrs);
 //二分法 折半查找  标记值 左、右
        //排好序 》左边找 《右边找   前提!!!!数组是有序的
        Array.prototype.binaryInsertSort=function(start,end,key){
            var arr=this;
            if(start>end){
                return false;
            }
            var mid=Math.floor((end+start)/2);
            if(arr[mid]==key){
                return mid;
            }
            else if(arr[mid]>key){
                return arr.binaryInsertSort(start,mid-1,key);
            }
            else {
                return arr.binaryInsertSort(mid+1,end,key);
            }
            return false;
        };
        var arrs = [1, 2, 6, 45, 66, 74, 91];
        console.log(arrs.binaryInsertSort(0,arrs.length,91));

3、归并排序

含义:什么是归并排序?
归并排序是将两个有序的数列合并成一个大的有序的数列,通过递归进行,层层合并,进行归并
先分再合并

function MergeSort(array) {
            //分
            let len = array.length;
            if (len <= 1) {
                return array;
            }
            let num = Math.floor(len / 2);
            let left = MergeSort(array.slice(0, num));
            let right = MergeSort(array.slice(num, array.length));
            return merge(left, right);
            //归并
            function merge(left, right) {
                //记录result的索引 l和r是一样的意思 为了保持索引能够连着
                let [l, r] = [0, 0];
                let result = [];
                while (l < left.length && r < right.length) {
                    if (left[l] < right[r]) {
                        result.push(left[l]);
                        l++;
                    } else {
                        result.push(right[r]);
                        r++;
                    }
                }
                //归并
                result = result.concat(left.slice(l, left.length));
                result = result.concat(right.slice(r, right.length));
                return result;
            }
        }
        var arr = [80, 34, 56, 25, 27, 85, 32];
        console.log(MergeSort(arr));
function MergeSort(array){
            if(array.length<=1){
                return array;
            }
            var mid=Math.floor(array.length/2);
            var left=MergeSort(array.slice(0,mid));
            var right=MergeSort(array.slice(mid));
            
            return Merge(left,right);
            // 合并
            function Merge(left,right){
                var result=[];
                while(left.length&&right.length){
                    if(left[0]>right[0]){
                        //删除并返回
                        result.push(right.shift());
                    }
                    else {
                        result.push(left.shift());
                    }
                }
                
                //左右合并
                return result.concat(left, right);;
            }
        }
        var arr = [80, 34, 56, 25, 27, 85, 32];
        console.log(MergeSort(arr));
        

不稳定排序

4、快速排序

思想
以数组中的某一个值为标记量,遍历数组,如果数组的长度小于等于1的话,直接返回该数组,
否则遍历的值比该标志量小,那么就把他压入a数组中,否则,压入b数组中,递归的进行这样的操作,就把排序结果搞出来了
左、右、中间 递归排序
需要对数组的数量进行判断,如果长度小于等于1,就返回该数组,判断条件写在最前面

 Array.prototype.QuickSort = function () {
            var arr = this;
            if (arr.length <= 1) {
                return arr;
            }
            var middle = arr.splice(parseInt(arr.length / 2), 1);
            var left = [];//小
            var right = [];//大
            for (var i = 0; i < arr.length; i++) {
                if (arr[i] < middle) {
                    left.push(arr[i]);
                }
                else {
                    right.push(arr[i]);
                }
            }
            return left.QuickSort().concat(middle).concat(right.QuickSort())
        }
        var arr = [1, 2, 22, 32, 23, 12, 34];
        arr.QuickSort();
        console.log(arr,arr.QuickSort());

5、选择排序

思想
插入排序与选择排序的区别
1、选择排序
首先在未排列的数组中找到最大/小值,存放到数组的起始序列,紧接着在剩下的数组中找到次大/小的值,递归进行
2、插入排序
类似于扑克牌,默认先插第一个元素,然后下一个元素如果比他大,就放在后面,如果比他小,就放在前面 冒泡
对于未排序数据,在已排序序列中从后向前扫描,找到相应位置

 Array.prototype.SelectSort=function(){
             var arr=this;
             if(arr.length<=1){
                 return arr;
             }
             for(var i=0;i<arr.length;i++){//第几轮 主要比较的对象 第i个元素
                for(var k=i+1;k<arr.length;k++){//与第i个元素后面的元素进行比较
                    if(arr[i]<arr[k]){
                        var temp=arr[i];
                        arr[i]=arr[k];
                        arr[k]=temp;
                    }
                }
             }
             return arr;
         }
         var arrs=[1,6,3,2,45,66,34,21];
         arrs.SelectSort();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值