归并排序算法和快速排序算法

目录

一、归并排序算法

二、快速排序算法


一、归并排序算法

基本思想:

先将序列一次次分成子序列,直到子序列的长度为1。再将已有序的子序列进行合并。得到完全有序序列。用到了分而治之的思想(分治法)

首先把数组依次折半,分成小的子数组,知道每一个子数组的长度都为一;

然后合并子数组,在合并的过程中进行排序;

 定义两个变量left和right,分别赋值为两个数组的首元素的索引;

初始化一个数组,数组长度为原数组大小;

在定义一个变量,t,初始化为新开的数组的第一个元素的索引

 

 然后每次从两个数组中找到相对较小的数,填到新开的数组中

 

 

 

/*
 合并方法:
   @param arr 待排序数组
   @param left 左边序列的初始索引
   @param mid 中间索引(用来判断左边序列何时结束:到mid结束,右边序列何时开始:即mid+1)
   @param right 右边数组结束的索引
   @param temp 临时存储的数组
*/

function merge(arr,left,mid,right,temp){
    var i = left; //左边有序系列的初始索引
    var j = mid+1;//右边有序系列的初始索引
    var t = 0;//指向临时数组的当前索引
    //将两边数组元素进行比较,一次填进临时数组直到将一边填完
    while(i<=mid && j<=right){
        if(arr[i]<=arr[j]){//选择较小的填进去
            temp[t] = arr[i];
            t += 1;
            i += 1;
        }else{
            temp[t] = arr[j];
            t +=1;
            j +=1;
        }
    }
    //把有剩余数据的数组全部填充到临时数组
    while(i<=mid){
        temp[t] = arr[i];
        t += 1;
        i += 1;
    }
    while(j<=right){
        temp[t]=arr[j];
        t += 1;
        j += 1;
    }
    //将temp数组的元素拷贝到arr
    t = 0;
    var k = left;
    while(k<=right){
        arr[k]=temp[t];
        t += 1;
        k += 1;
    }
}

//归并(分+治)方法
function mergeSort(arr,left,right,temp){
    if(left<right){
        var mid = parseInt((left+right)/2);//中间元素索引
        mergeSort(arr,left,mid,temp);//左边递归分解,每次都会调用mergeSort
                                     //逐层分解直到数组中只有一个元素,然后跳出
                                     //在逐层进行merge的合并,逐合并
        mergeSort(arr,mid+1,right,temp);//右边递归分解
        merge(arr,left,mid,right,temp);//合并
    }
}

var arr = [2,5,3,10,-3,1,6,4];
var temp = new Array(arr.length);
console.log("排序前的数组:",arr);
mergeSort(arr,0,arr.length-1,temp);
console.log("排序后的数组:",arr);

 注意:左右递归的分解是逐层分解,直至分解到数组中只有一个元素,然后再进行逐层的合并

二、快速排序算法

基本思想:

任取呆排序序列的一个元素作为中心元素(可以用第一个,子后一个,也可以是中间任何一个),习惯称其为pivot枢轴元素。用到了分而治之的思想(分治法)

将所有比枢轴元素小的放其左边,比枢轴元素大的放在右边,形成左右两个子表。然后对左右两个字表再按照前面的算法进行排序,知道每个子表的元素只剩下一个。

将一个数组分成两个数组的方法:

(1)先从数组右边找到一个比枢轴元素小的元素,将数组的第一个位置赋值为该元素;

(2)再从数组的左边找到一个比枢轴元素大的元素,将从上面取元素的位置赋值该值;

(3)一次进行,知道左右相遇,把枢轴元素赋值到相遇位置;

 

var arr = [39,28,55,87,66,3,17,39];
console.log("排序前的数组:",arr);
/*对每一个数组进行分化的代码如下:
   初始化pivot为数组第一个元素;
   只要left还小于right就进行循环;
外层循环内部如下:
   先从右边找一个比枢轴元素小的元素;
   将当前left所指元素赋值为找到的元素;
   再从左边找一个比枢轴元素大的元素;
   将当前right所指元素赋值为找到的元素;
   当left和right相等将枢轴元素赋值在此。
   最后返回中间元素的索引。
*/

function partition(arr,left,right){
    var pivot = arr[left];
    while(left<right){
        while(left<right && arr[right]>=pivot){
            right--;
        }
        arr[left] = arr[right];
        while(left<right && arr[left]<=pivot){
            left++;
        }
        arr[right]=arr[left];
    }
    arr[left]=pivot;
    return left;
}

/*
 排序:传数组,left为第一个元素索引0;right为最后一个元素索引数组长度减去1;
   定义一个将来划分为两个数组的中间元素的索引middle;
   如果left比right小,进行一次划分,将返回来的值赋值给middle;
   对left到middle - 1的部分进行一次快排(递归进行);
   对middle + 1到right的部分进行一次快排(递归进行)。
*/

function quickSort(arr,left,right){
    var middle;
    if(left<right){
        middle = partition(arr,left,right);
        quickSort(arr,left,middle-1);
        quickSort(arr,middle+1,right);
    }
}

quickSort(arr,0,arr.length-1);
console.log("排序后的数组:",arr);

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值