对一个一维数组进行排序。(使用归并排序算法)
思路:
将一个数组进行排序。不断的进行切割,知道单位为一。则停止切割。
然后将其合并,再进行排序。
(即分割,再进行合并)
图的引用:https://www.cnblogs.com/chengxiao/p/6194356.html。(感谢该链接作者的介绍)。
JS的实现:(个人实现)
// 进行归并排序
function gb(arr){ //归并排序
let l= arr.length
if(l==1){
return arr[0]
}
let mid = Math.floor(l/2); //获得了一个中间值
//进行切割;
let leftvalue = arr.slice(0,mid); //左侧的数据
let rightvalue = arr.slice(mid,l); //右侧的数据
let final_left = gb(leftvalue); //分割到底的数据
let final_right = gb(rightvalue); //分割到底的数据
let result = hb(final_left,final_right);
return result
}
function hb(arr01,arr02){ //合并
let i=0; //记录数组一遍历的索引
let j=0;//记录数组二变脸的索引
let result =[];//接收合并结果;
//同为数据的处理
if(!(arr01 instanceof Array || arr02 instanceof Array)){
if(arr01>arr02){
result.push(arr02);
result.push(arr01);
}else{
result.push(arr01);
result.push(arr02);
}
return result;
}
// 一个数组,一个数据的处理
if(!((arr01 instanceof Array && arr02 instanceof Array) || (typeof arr01 =='number' && typeof arr02 == "number"))){
if(arr01 instanceof Array) {
result = arr01.slice(0);
for(let i in arr01){
if(arr02>arr01[i]){
// result.splice(i+1,0,arr02);
// break;
if(i==arr01.length-1){ //已经到达尾部了
resul.splice(i+1,0,arr02);
break;
}
}else{
// result.unshift(arr02);
// break;
result.splice(i,0,arr02)
break
}
}
return result
}else{
//进入死循环
result = arr02.slice(0);
for(let i in arr02){
if(arr01>arr02[i]){
// result.splice(i+1,0,arr01);
// break;
if(i==arr02.length-1){ //已经到达尾部了
result.splice(i+1,0,arr01);
break;
}
continue;
}else{
// result.unshift(arr01);
result.splice(i,0,arr01)
break
}
}
return result
}
}
// 两个数据都是数组的处理;
while(i<arr01.length && j<arr02.length){
if(arr01[i]<arr02[j]){
result.push(arr01[i]);
i++;
}else{
result.push(arr02[j]);
j++
}
}
//就是数组还没有遍历完,就到底了,其中有一个数组已经结束遍历的,则把后面的进行添加。
if(i<arr01.length){
result = result.concat(arr01.slice(i,arr01.length));
}
if(j<arr02.length){
result = result.concat(arr02.slice(j,arr02.length));
}
return result;
}
let arr = [1,4567,867,543,32,123,4236,754,123,234,756,867];
let result =gb(arr);
console.log(result);
拓展延伸题目:.合并二维有序数组成一维有序数组,归并排序的思路;
例子:let arr = [[1,2,35,],[2,3,6,7,8],[1,23,655,999]];
该例子的思路:进行归并排序,将其切割成一个个小数组,然后进行数组的合并。因为最小的数据,是数组,无论是合并之后的,还是合并之前,都是不需要进行数据的判断。
JS实现:
function mergeSort(arr) {
const len = arr.length
// 处理边界情况
if(len <= 1) {
return arr[0]
}
// 计算分割点
const mid = Math.floor(len / 2)
// 递归分割左子数组,然后合并为有序数组
const leftArr = mergeSort(arr.slice(0, mid))
// 递归分割右子数组,然后合并为有序数组
const rightArr = mergeSort(arr.slice(mid,len))
// 合并左右两个有序数组
arr = mergeArr(leftArr, rightArr)
// 返回合并后的结果
return arr
}
function mergeArr(arr1, arr2) {
// 初始化两个指针,分别指向 arr1 和 arr2
let i = 0, j = 0
// 初始化结果数组
const res = []
// 缓存arr1的长度
const len1 = arr1.length
// 缓存arr2的长度
const len2 = arr2.length
// 合并两个子数组
while(i < len1 && j < len2) {
if(arr1[i] < arr2[j]) {
res.push(arr1[i])
i++
} else {
res.push(arr2[j])
j++
}
}
// 若其中一个子数组首先被合并完全,则直接拼接另一个子数组的剩余部分
if(i<len1) {
return res.concat(arr1.slice(i))
} else {
return res.concat(arr2.slice(j))
}
}
var arr=[[1,2,4],[2,3,7],[3,5,7],[4,5,99]]
// mergeArr(arr)