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

JavaScript算法 ,Python算法,Go算法,java算法,系列之【归并排序】篇

2017-06-09 00:00 1011 查看
常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括:





归并排序(英语:Mergesort,或mergesort),是创建在归并操作上的一种有效的排序算法,效率为O(nlogn)。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(DivideandConquer)的一个非常典型的应用,且各层分治递归可以同时进行。





作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第2种方法);
自下而上的迭代;
在《数据结构与算法JavaScript描述》中,作者给出了自下而上的迭代方法。但是对于递归法,作者却认为:
However,itisnotpossibletodosoinJavaScript,astherecursiongoestoodeepforthelanguagetohandle.
然而,在JavaScript中这种方式不太可行,因为这个算法的递归深度对它来讲太深了。
说实话,我不太理解这句话。意思是JavaScript编译器内存太小,递归太深容易造成内存溢出吗?还望有大神能够指教。
和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(nlogn)的时间复杂度。代价是需要额外的内存空间。

算法步骤

申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

设定两个指针,最初位置分别为两个已经排序序列的起始位置;

比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

重复步骤3直到某一指针达到序列尾;

将另一序列剩下的所有元素直接复制到合并序列尾。

动图演示





1、JavaScript代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
functionmergeSort(arr){
<
3ff8
p>varlen=arr.length;if(len<2){
returnarr;
}
varmiddle=Math.floor(len/2),
left=arr.slice(0,middle),
right=arr.slice(middle);
returnmerge(mergeSort(left),mergeSort(right));
}

functionmerge(left,right){
varresult=[];

while(left.length&&right.length){
if(left[0]<=right[0]){
result.push(left.shift());
}else{
result.push(right.shift());
}
}

while(left.length)
result.push(left.shift());

while(right.length)
result.push(right.shift());

returnresult;
}
2、Python代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
defmergeSort(arr):
importmath
if(len(arr)<2):
returnarr
middle=math.floor(len(arr)/2)
left,right=arr[0:middle],arr[middle:]
returnmerge(mergeSort(left),mergeSort(right))

defmerge(left,right):
result=[]
whileleftandright:
ifleft[0]<=right[0]:
result.append(left.pop(0));
else:
result.append(right.pop(0));
whileleft:
result.append(left.pop(0));
whileright:
result.append(right.pop(0));
returnresult
3、Go代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
funcmergeSort(arr[]int)[]int{
length:=len(arr)
iflength<2{
returnarr
}
middle:=length/2
left:=arr[0:middle]
right:=arr[middle:]
returnmerge(mergeSort(left),mergeSort(right))
}

funcmerge(left[]int,right[]int)[]int{
varresult[]int
forlen(left)!=0&&len(right)!=0{
ifleft[0]<=right[0]{
result=append(result,left[0])
left=left[1:]
}else{
result=append(result,right[0])
right=right[1:]
}
}

forlen(left)!=0{
result=append(result,left[0])
left=left[1:]
}

forlen(right)!=0{
result=append(result,right[0])
right=right[1:]
}

returnresult
}
4、Java实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
publicstaticint[]sort(int[]nums,intlow,inthigh){
intmid=(low+high)/2;
if(low<high){

sort(nums,low,mid);

sort(nums,mid+1,high);

merge(nums,low,mid,high);
}
returnnums;
}

/**
*将数组中low到high位置的数进行排序
*nums待排序数组
*low待排的开始位置
*mid待排中间位置
*high待排结束位置
*/
publicstaticvoidmerge(int[]nums,intlow,intmid,inthigh){
int[]temp=newint[high-low+1];
inti=low;
intj=mid+1;
intk=0;

while(i<=mid&&j<=high){
if(nums[i]<nums[j]){
temp[k++]=nums[i++];
}else{
temp[k++]=nums[j++];
}
}

while(i<=mid){
temp[k++]=nums[i++];
}

while(j<=high){
temp[k++]=nums[j++];
}


for(intk2=0;k2<temp.length;k2++){
nums[k2+low]=temp[k2];
}
}
登录乐搏学院官网http://www.learnbo.com/

或关注我们的官方微博微信,还有更多惊喜哦~

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