JS常见排序算法

JavaScript014

JS常见排序算法,第1张

排序算法说明:

(1)对于评述算法优劣术语的说明

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

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

内排序 :所有排序操作都在内存中完成;

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

时间复杂度 : 一个算法执行所耗费的时间。

空间复杂度 : 运行完一个程序所需内存的大小。

(2)排序算法图片总结:

1.冒泡排序:

解析:1.比较相邻的两个元素,如果前一个比后一个大,则交换位置。

 2.第一轮的时候最后一个元素应该是最大的一个。

 3.按照步骤一的方法进行相邻两个元素的比较,这个时候由于最后一个元素已经是最大的了,所以最后一个元素不用比较。

2.快速排序:

解析:快速排序是对冒泡排序的一种改进,第一趟排序时将数据分成两部分,一部分比另一部分的所有数据都要小。然后递归调用,在两边都实行快速排序。

3.插入排序:

解析:

 (1) 从第一个元素开始,该元素可以认为已经被排序

 (2) 取出下一个元素,在已经排序的元素序列中从后向前扫描

 (3) 如果该元素(已排序)大于新元素,将该元素移到下一位置

 (4) 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置

 (5)将新元素插入到下一位置中

 (6) 重复步骤2

2.二分查找:

解析:二分查找,也为折半查找。首先要找到一个中间值,通过与中间值比较,大的放又,小的放在左边。再在两边中寻找中间值,持续以上操作,直到找到所在位置为止。

(1)递归方法

(2)非递归方法

4.选择排序:

解析:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

以此类推,直到所有元素均排序完毕。

5.希尔排序:

解析:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序

6.归并排序:

解析:归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

7.堆排序:

解析:堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是

小于(或者大于)它的父节点。

8.计数排序:

 解析:计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。它只能对整数进行排序。

9.桶排序:

解析:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排

10.基数排序:

解析:基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优

先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以是稳定的。

基数排序 vs 计数排序 vs 桶排序

这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

基数排序:根据键值的每位数字来分配桶 计数排序:每个桶只存储单一键值 桶排序:每个桶存储一定范围的数值

数据结构算法中排序有很多种,常见的、不常见的,至少包含十种以上。根据它们的特性,可以大致分为两种类型:比较类排序和非比较类排序

冒泡排序是一次比较两个元素,如果顺序是错误的就把它们交换过来。,直到不需要再交换

快速排序的基本思想是通过一趟排序,将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可以分别对这两部分记录继续进行排序,以达到整个序列有序

从数列中挑出一个元素,称为 “基准”(pivot);然后重新排序数列,所有元素比基准值小的摆放在基准前面、比基准值大的摆在基准的后面;在这个区分搞定之后,该基准就处于数列的中间位置;然后把小于基准值元素的子数列(left)和大于基准值元素的子数列(right)递归地调用 quick 方法排序完成,这就是快排的思路

通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入,从而达到排序的效果

插入排序的思路是基于数组本身进行调整的,首先循环遍历从 i 等于 1 开始,拿到当前的 current 的值,去和前面的值比较,如果前面的大于当前的值,就把前面的值和当前的那个值进行交换,通过这样不断循环达到了排序的目的

将最小的元素存放在序列的起始位置,再从剩余未排序元素中继续寻找最小元素,然后放到已排序的序列后面……以此类推,直到所有元素均排序完毕

堆排序是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质,即子结点的键值或索引总是小于(或者大于)它的父节点。堆的底层实际上就是一棵完全二叉树,可以用数组实现

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并

通过 mid 可以把该数组分成左右两个数组,分别对这两个进行递归调用排序方法,最后将两个数组按照顺序归并起来

在Web开发中,JavaScript很重要,算法也很重要。下面整理了一下一些常见的算法在JavaScript下的实现,包括二分法、求字符串长度、数组去重、插入排序、选择排序、希尔排序、快速排序、冒泡法等等。仅仅是为了练手,不保证高效与美观,或许还有Bug,有时间再完善吧。

1.二分法:

function binary(items,value){

var startIndex=0,

stopIndex=items.length-1,

midlleIndex=(startIndex+stopIndex)>>>1

while(items[middleIndex]!=value &&startIndex

if(items[middleIndex]>value){

stopIndex=middleIndex-1

}else{

startIndex=middleIndex+1

}

middleIndex=(startIndex+stopIndex)>>>1

}

return items[middleIndex]!=value ? false:true

}

2.十六进制颜色值的随机生成:

function randomColor(){

var arrHex=["0","2","3","4","5","6","7","8","9","a","b","c","d"],

strHex="#",

index

for(var i=0i <6i++){

index=Math.round(Math.random()*15)

strHex+=arrHex[index]

}

return strHex

}

一个求字符串长度的方法:

function GetBytes(str){

var len=str.length,

bytes=len

for(var i=0i <leni++){

if(str.CharCodeAt>255){

bytes++

}

}

return bytes

}

3.js实现数组去重:

Array.protype.delRepeat=function(){

var newArray=new Array()

var len=this.length

for(var i=0i <leni++){

for(var j=i+1j <lenj++)

{

if(this[i]==this[j])

{

++i

}

}

newArray.push(this[i])

}

return newArray

}

4.插入排序。所谓的插入排序,就是将序列中的第一个元素看成一个有序的子序列,然后不段向后比较交换比较交换。

function insertSort(arr){

var key

for(var j = 1j <arr.length j++){

//排好序的

var i = j - 1

key = arr[j]

while(i >= 0 &&arr[i] >key){

arr[i + 1] = arr[i]

i --

}

arr[i + 1] = key

}

return arr

}

5.选择排序。其实基本的思想就是从待排序的数组中选择最小或者最大的,放在起始位置,然后从剩下的数组中选择最小或者最大的排在这公司数的后面。

function selectionSort(data)

{

var i, j, min, temp , count=data.length

for(i = 0i <count - 1i++) {

/* find the minimum */

min = i

for (j = i+1j <countj++)

{

if (data[j] <data[min])

{ min = j}

}

/* swap data[i] and data[min] */

temp = data[i]

data[i] = data[min]

data[min] = temp

}

return data

}

6.希尔排序,也称递减增量排序算法。其实说到底也是插入排序的变种。

function shellSort(array){

var stepArr = [1750, 701, 301, 132, 57, 23, 10, 4, 1]//

reverse()在维基上看到这个最优的步长较小数组

var i = 0

var stepArrLength = stepArr.length

var len = array.length

var len2 = parseInt(len/2)

for(i <stepArrLengthi++){

if(stepArr[i] >len2){

continue

}

stepSort(stepArr[i])

}

// 排序一个步长

function stepSort(step){

//console.log(step) 使用的步长统计

var i = 0, j = 0, f, tem, key

var stepLen = len%step >0 ? parseInt(len/step) + 1 : len/step

for(i <stepi++){// 依次循环列

for(j=1/*j <stepLen &&*/step * j + i <len

j++){//依次循环每列的每行

tem = f = step * j + i

key = array[f]

while((tem-=step) >= 0){// 依次向上查找

if(array[tem] >key){

array[tem+step] = array[tem]

}else{

break

}

}

array[tem + step ] = key

}

}

}

return array

}

7.快速排序。其实说到底快速排序算法就系对冒泡排序的一种改进,采用的就是算法理论中的分治递归的思想,说得明白点,它的做法就是:通过一趟排序将待排序的纪录分割成两部分,其中一部分的纪录值比另外一部分的纪录值要小,就可以继续分别对这两部分纪录进行排序不段的递归实施上面两个操作,从而实现纪录值的排序。

function quickSort(arr,l,r){

if(l <r){

var mid=arr[parseInt((l+r)/2)],i=l-1,j=r+1

while(true){

while(arr[++i] <mid)

while(arr[--j]>mid)

if(i>=j)break

var temp=arr[i]

arr[i]=arr[j]

arr[j]=temp

}

quickSort(arr,l,i-1)

quickSort(arr,j+1,r)

}

return arr

}

8.冒泡法:

function bullSort(array){

var temp

for(var i=0i <array.lengthi++)

{

for(var j=array.length-1j >ij--){

if(array[j] <array[j-1])

{

temp = array[j]

array[j]=array[j-1]

array[j-1]=temp

}

}

}

return array

}