计数排序
可以说是右移负数直方图,然后对直方图再进行整理后的排序
可以进行改善,就是再那个计数的那个可以进行修改countArr变成距离而不是最大值驱动
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
// 时间复杂度 n+k
// 空间复杂度 n+k
// 使用计数排序
// 时间 计数排序步骤是;
// 第一步:算出最大值、最小值、以及之间的距离
let min = nums[0],max = nums[0]
for(let i = 1;i < nums.length;i++){
min = Math.min(nums[i],min)
max = Math.max(nums[i],max)
}
let d = max - min
// 如果是负数需要额外添加一些数字
let add = min < 0?-min:0
// 第二步:创建一个计数的数组,用来存储数据对应的次数
let countArr = new Array(max+add+1).fill(0)
for(let i = 0;i < nums.length;i++){
// 对应的下标
let index = nums[i]+add
countArr[index]++
}
// 第三步:对已经存储的次数进行排序
let arr = []
for(let i = 0;i < countArr.length;i++){
if(countArr[i] === 0){
continue
}
let count = countArr[i]
// 下标表示数字,值表示次数,然后将对应的次数进行push
while(count !== 0){
// 如果是负数的话,需要减去转化为整数的值
arr.push(i-add)
count--
}
}
return arr
// 09点03分
};
快速排序
- 时间复杂度 nlog2n
- 空间复杂度 nlog2n
主要是递归的使用,然后还有将数组截取成两段使用splice,把小的放在左边,大的放在右边,然后再进行拼合,
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
// 快速排序
var quickSort = (arr) => {
if(arr.length == 1 || arr.length === 0) return arr
// 第一步:确定左边、右边和中间数
let left = [],right = [], mid = Math.floor(arr.length / 2)
let midNum = arr[mid]
// 第二步,对中间数进行截取,使用splice可以对数组直接进行修改
arr.splice(mid,1)
for(let i = 0;i < arr.length;i++){
if(arr[i] < midNum){
left.push(arr[i])
}else{
right.push(arr[i])
}
}
return quickSort(left).concat(midNum,quickSort(right))
}
return quickSort(nums)
};
归并排序
本质上就是变成两个有序数组然后进行排序
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
// 09点36分 归并排序
// 先把它进行拆分,然后比较,知道最后一个,然后进行合并
// 10点51分 玩了一会儿
// 第二个步骤,对两个进行合并
// 12点10分
let merge = (left,right) => {
// 进行合并
let result = []
let leftIndex = 0 ,rightIndex = 0
while(leftIndex < left.length && rightIndex < right.length){
let tem = left[leftIndex] < right[rightIndex] ? left[leftIndex++]:right[rightIndex++]
result.push(tem)
}
while(leftIndex < left.length){
result.push(left[leftIndex++])
}
while(rightIndex < right.length){
result.push(right[rightIndex++])
}
// 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())
// }
return result
}
// 第一个步骤:进行拆分,分成左边和右边
let mergeSort = (arr) => {
if(arr.length <= 1)return arr
let midIndex = Math.floor(arr.length / 2)
// 对数组进行拆分
let left = arr.slice(0,midIndex) //有包含midIndex
let right = arr.slice(midIndex)
let mergeLeft = mergeSort(left)
let mergeRight = mergeSort(right)
return merge(mergeLeft,mergeRight)
}
return mergeSort(nums)
};
插入排序
就是如果前面的比大,让前面的牌到后面去,然后重新
var sortArray = function(nums) {
// 12点16分 插入排序
// 就是从后面往前面进行调换
for(let i = 0;i < nums.length;i++){
// 进行插入的数组
let cur = nums[i],
preIndex = i - 1
// 如果下标大于0,并且数大于要插入的数的话,就要进行插入
while(preIndex >= 0 && nums[preIndex] > cur){
nums[preIndex+1] = nums[preIndex]
preIndex--
}
// 插入的点
nums[preIndex+1] = cur
}
return nums
};
选择排序
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortArray = function(nums) {
// 15点57分 选择排序,找出后面最小的,然后每次放在最前面
let len = nums.length
for(let i = 0;i < nums.length;i++){
// 找出之后的最小值的坐标
let minIndex = i
for(let j = i+1;j < nums.length;j++){
minIndex = nums[minIndex] < nums[j]?minIndex:j
}
// 最小坐标对应值进行交换
let tem = nums[i]
nums[i] = nums[minIndex]
nums[minIndex] = tem
}
return nums
// 16点09分
};