什么是归并排序?咱们先看一张图:
归并排序的原理就是分治法,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并(这句话摘自百度百科)。
下边用自己的话讲一下:现在有一个数组,咱们先把他递归的两两拆分,就像一个二叉树一样,最后每个节点只有一个元素。从图中可以看到,最后的子节点都是一个(图中第四行)。那么此时咱们把兄弟节点相比较,把小的放前边,大的放后边,最后变成(图中的第五行)。这就是合并的第一步。那么下一次每个节点里边都有俩元素怎么办?因为上一步的合并,我们的每个节点已经是有序的了,那么我们只要每次比较节点的第一个元素,谁小就把谁拿出来就行,最后合并的结果肯定也是有序的。依次类推,直到合并完所有的节点。排序完成。
下边放js代码:
function merge(arr,begin,middle,end){
let n1 = middle - begin + 1
let n2 = end - middle
let A1 = [],A2 = []
for(let i = 0;i < n1;i++){
A1[A1.length] = arr[begin + i]
}
for(let i = 0;i < n2;i++){
A2[A2.length] = arr[middle + 1 + i]
}
A1[A1.length] = Infinity
A2[A2.length] = Infinity
let i = 0,j = 0,k = 0
while(k < n1 + n2){
if(A1[i] <= A2[j]){
arr[begin + k++] = A1[i++]
} else {
arr[begin + k++] = A2[j++]
}
}
}
function mergeSort(list){
function sort(arr,begin,end){
if(begin < end){
let middle = (begin + end) / 2 >> 0
sort(arr,begin,middle)
sort(arr,middle + 1,end)
merge(arr,begin,middle,end)
}
return arr
}
return sort(list,0,list.length - 1)
}
mergeSort(list)
为了大家能够清晰的理解每一步怎么执行的,我写了一个html,把每一步的执行结果用图表示出来了。先看图:
最后是html代码,大家把这段代码直接放入html打开就可以看到上图了(箭头是我后来加的)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.list {
display: flex;
margin: 20px;
}
.list .item {
width: 50px;
height: 30px;
font-size: 16px;
font-weight: 700;
text-align: center;
line-height: 30px;
border: 2px solid #2992e7;
border-right: none;
color: rgb(240, 33, 205);
}
.list .item.change_item {
background-color: rgb(92, 235, 240);
}
.list .item.key_item {
background-color: rgb(221, 230, 140);
}
.list .item:nth-last-child(1){
border-right: 2px solid #2992e7;
}
</style>
</head>
<body>
<script>
function merge(arr,begin,middle,end){
let n1 = middle - begin + 1
let n2 = end - middle
let A1 = [],A2 = []
for(let i = 0;i < n1;i++){
A1[A1.length] = arr[begin + i]
}
for(let i = 0;i < n2;i++){
A2[A2.length] = arr[middle + 1 + i]
}
A1[A1.length] = Infinity
A2[A2.length] = Infinity
let i = 0,j = 0,k = 0
while(k < n1 + n2){
if(A1[i] <= A2[j]){
arr[begin + k++] = A1[i++]
} else {
arr[begin + k++] = A2[j++]
}
}
}
function mergeSort(list){
function sort(arr,begin,end){
if(begin < end){
let middle = (begin + end) / 2 >> 0
sort(arr,begin,middle)
sort(arr,middle + 1,end)
merge(arr,begin,middle,end)
}
renderList(list,begin,end)
return arr
}
return sort(list,0,list.length - 1)
}
let list = [65,6,856,42,2,86,4,9]
renderList(list,1,-1)
console.log(mergeSort(list))
function renderList(arr,keyIndex,changeIndex){
let domList = document.createElement("div")
domList.classList = "list"
for(let i = 0;i < arr.length;i++){
let domItem = document.createElement("div")
domItem.classList = "item"
if(changeIndex == i){
domItem.classList = "item change_item"
}
if(keyIndex == i){
domItem.classList = "item key_item"
}
domItem.innerText = arr[i]
domList.appendChild(domItem)
}
document.body.appendChild(domList)
}
</script>
</body>
</html>
有帮助的话,希望点个赞,加个关注哦!
上一篇:js插入排序
下一篇:npm adduser或者npm login报错,npm login不能登陆解决办法。