js实现堆排序、归并排序、快速排序
排序的定义
对某一序列对象根据某个关键字进行排序
即高的在后面矮的在前面(矮的在后面高的在前面)
稳定
如果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));
注意
主要是堆的概念,必须先理解堆,才能真正的实现堆排序
- 插入排序,希尔排序,堆排序,归并排序,快速排序Java实现
- 各类排序算法实现(堆排序、希尔排序、快速排序、归并排序等)
- Java实现快速排序、归并排序、堆排序和希尔排序
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——C++实现
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 常见排序算法的实现(归并排序、快速排序、堆排序、选择排序、插入排序、希尔排序)
- 快速排序、堆排序和归并排序的实现
- 几种基本排序的实现:选择排序,冒泡排序,插入排序,堆排序,快速排序,归并排序
- js实现常见的三种排序方法(冒泡排序、快速排序、归并排序)
- 快速排序、堆排序、归并排序的python实现
- C++实现几种常用的时间复杂度为O(nlogn)的排序方法:归并排序、快速排序、堆排序、希尔排序
- 快速排序,归并排序,堆排序的java代码实现
- 用Java语言实现的各种排序,包括插入排序、冒泡排序、选择排序、Shell排序、快速排序、归并排序、堆排序、SortUtil等...
- 【程序员笔试面试必会——排序①】Python实现 冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、希尔排序
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序的C++代码实现
- java实现:快速排序,基数排序,计数排序,归并排序,堆排序,希尔排序
- Java实现快速排序、归并排序、堆排序
- 常用排序算法C++实现(堆排序,快速排序,归并排序,基数排序)
- 排序算法复习(Java实现):插入,冒泡,选择,Shell,快速排序, 归并排序,堆排序,桶式排序,基数排序