您的位置:首页 > Web前端 > JavaScript

js实现堆排序、归并排序、快速排序

2019-06-14 14:47 211 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/weixin_39514724/article/details/91871997

排序的定义

对某一序列对象根据某个关键字进行排序
即高的在后面矮的在前面(矮的在后面高的在前面)

稳定

如果a原本在b的前面,而a= b,排序之后a仍然在b的前面

不稳定

如果a原本在b的前面,而a = ,排序之后a可能会出现在b的后面

内排序

所有操作都早内存中完成

外排序

由于数据太大,因此把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行

时间复杂度

一个算法执行所消费的时间

空间复杂度

运行完一个程序所需内存的大小

归并排序

归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。
算法简介
 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段 间有序。若将两个有序表合并成一个有序表,称为2-路归并。
即一分为二,一分到底
算法实现
<1>.把长度为n的输入序列分成两个长度为n/2的子序列;
<2>.对这两个子序列分别采用归并排序;
<3>.将两个排序好的子序列合并成一个最终的排序序列。
递归的思想来进行实现
js代码实现

function magerSort(array) {
var len = array.length;
if (len < 2) {
return array;
}
var middle = Math.floor(len / 2);
var left = array.slice(0, middle); //slice函数用来分割数组slice(开始,结束),无结束默认到最后
var right = array.slice(middle);
return mager(magerSort(left), magerSort(right));
}

function mager(left, right) {
var result = [];
//当左右元素都不为空时
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift()); //shift()函数用来移除数组中的首元素,返回是移除的元素,pop()移除数组中的尾元素
} else {
result.push(right.shift());
}
}

while (left.length) {
result.push(left.shift());
}
while
3ff7
(right.length) {
result.push(right.shift());
}
return result;
}

var arr = [8, 4, 6, 3];
console.log(magerSort(arr));

大白话系列
将一个数组分为两个数组,将两个数组分成四个数组,直到是单个的数据为止,然后对分开的数据进行比较和排序,返回上一级,对返回的数据进行比较排序,返回上一级,直到返回到顶级为止,排序完成。

快速排序

快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高! 它是**处理大数据**最快的排序算法之一了。

算法简介
快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
算法描述和实现
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
<1>.从数列中挑出一个元素,称为 “基准”(pivot);
<2>.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
<3>.递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
代码的实现思想-----递归
js代码的实现

function quickSort1(array) {
if (array.length <= 1) {
return array;
}
var pivot = Math.floor(array.length / 2)
var pivotIndex = array.splice(pivot, 1)[0]; //splice获取数组中的元素,返回的是一个数组,方法改变原始数组
var left = [];
var right = [];
for (let i = 0; i < array.length; i++) {
if (array[i] < pivotIndex) {
left.push(array[i]);
} else {
right.push(array[i]);
}
}
return quickSort1(left).concat([pivotIndex], quickSort1(right)); //concat连接两个或者多个数组list1.concat(list2.list3)
}

var arr = [8, 4, 6, 3];
console.log(quickSort1(arr));

大白话系列
找到数组中的一个数字作为“标杆”,比它大的放到一个数组,比它小的放到另一个数组。在将左侧和右侧的数组分别再找一个“标杆”,继续比较。直到数组的长度<=1,变为一个数,不需要比较。在将一个个被分开的数组连接起来。

堆排序

算法简介
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
算法描述
<1>.将初始待排序关键字序列(R1,R2…Rn)构建成大顶堆,此堆为初始的无序区;
<2>.将堆顶元素R[1]与最后一个元素R
交换,此时得到新的无序区(R1,R2,…Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R

<3>.由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,…Rn-1)调整为新堆,然后 再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2…Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元 素个数为n-1,则整个排序过程完成。
js代码的实现

function heapSort(array) {
var len = array.length;
var firstHeapIndex = Math.floor(len / 2 - 1); //堆的性质,第一个有下标的节点的index,获取的公式为Math.floor(array.length/2-1)
for (let i = firstHeapIndex; i >= 0; i--) {
heap(array, len, i);
}

//在当前树中,交换位于根节点的最大值和最后一个节点的值,这样就把最大值排在了最后一个节点,这样就排好了最大值
while (len > 1) {
temp = array[0];
array[0] = array[len - 1];
array[len - 1] = temp;
len--; //当前树中最后一个节点已经排好了值,故后面就不用再考虑这个节点,故新的树的大小减一
if (len > 1) {
heap(array, len, 0); ////上面的交换操作产生了新的根节点,新的根节点只是通过跟最后一个节点交换得到的值,故新的根节点不满足条件arr[parent[i]]<arr[i],所以要对根节点再次进行堆的排序
}
}

return array;
}
//建立堆
function heap(array, len, i) { //数组,数组的长度,当前的根节点
var left = 2 * i + 1; //下标为i的根节点的左子节点的下标
var right = 2 * i + 2; //下标为i的根节点的右子节点的下标
var bigestValueIndex = i;
if (left < len && array[left] > array[bigestValueIndex]) {
bigestValueIndex = left;
}
if (right < len && array[right] > array[bigestValueIndex]) {
bigestValueIndex = right
}
if (i != bigestValueIndex) { //说明最大值不在根节点上,需要对根节点的值进行替换
var temp = array[i];
array[i] = array[bigestValueIndex];
array[bigestValueIndex] = temp;
heap(array, len, bigestValueIndex); //根节点的值得到替换,但被替换的节点的值不一定满足堆的结构,需要对呗替换的节点的值重新进行堆的维护
}
}

var arr = [8, 3, 6, 4];
console.log(heapSort(arr));

注意
主要是堆的概念,必须先理解堆,才能真正的实现堆排序

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐