牛客网题目地址:
1 冒泡排序(Bubble)
1.1 两个相邻元素比较,如果不满足顺序立即交换。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
for (let i = 0; i < result.length; i++) {
for(let j = 1; j < result.length - i; j++) {
if (arr[j-1] > arr[j]) {
let temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
}
}
return result;
}
module.exports = {
MySort: MySort,
};
2 选择排序(Selection)
2.2 选择剩余元素中最小或最大的,和已排好序的后一位进行交换。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
for (let i = 0; i < result.length; i++) {
let minIndex = i;
for(let j = i + 1; j < result.length; j++) {
if (result[j] < result[minIndex]) {
minIndex = j;
}
}
let temp = result[minIndex];
result[minIndex] = result[i];
result[i] = temp;
}
return result;
}
module.exports = {
MySort: MySort,
};
3 二分插入排序(Insertion)
3.1 二分法找到下一个元素,应该插入到已排序数组中的哪个位置
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 0) {
result = [arr[0]];
for (let i = 1; i < arr.length; i++) {
let startIndex = 0;
let endIndex = result.length - 1;
let middleIndex = 0;
const originValue = arr[i];
while (startIndex <= endIndex) {
middleIndex = Math.floor((endIndex + startIndex + 1) / 2);
if (originValue < result[middleIndex]) {
endIndex = middleIndex - 1;
} else {
startIndex = middleIndex + 1;
}
}
result.splice(startIndex, 0, originValue);
}
}
return result;
}
module.exports = {
MySort: MySort,
};
4 快速排序(Quick)
我写了三种快速排序算法,另外两种优化的写法,比较复杂,难以记忆。
4.1 左右指针法
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
quickSort(result, 0, result.length - 1);
}
return result;
}
function quickSort(arrArg, startIndexArg, endIndexArg) {
if (startIndexArg < endIndexArg) {
let startIndex = startIndexArg;
let endIndex = endIndexArg;
const firstValue = arrArg[startIndex];
while (startIndex < endIndex) {
while (startIndex < endIndex && arrArg[endIndex] >= firstValue) {
endIndex--;
}
while (startIndex < endIndex && arrArg[startIndex] <= firstValue) {
startIndex++;
}
swapItem(arrArg, startIndex, endIndex);
}
swapItem(arrArg, startIndexArg, startIndex);
quickSort(arrArg, startIndexArg, startIndex - 1);
quickSort(arrArg, startIndex + 1, endIndexArg);
}
}
function swapItem(arrArg, fromIndex, toIndex) {
let temp = arrArg[fromIndex];
arrArg[fromIndex] = arrArg[toIndex];
arrArg[toIndex] = temp;
}
module.exports = {
MySort: MySort,
};
4.2 留坑
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
quickSort(result, 0, result.length - 1);
}
return result;
}
function quickSort(arrArg, startIndexArg, endIndexArg) {
if (startIndexArg < endIndexArg) {
let startIndex = startIndexArg;
let endIndex = endIndexArg;
let emptyIndex = startIndex;
const firstValue = arrArg[startIndex];
while (startIndex < endIndex) {
while (startIndex < endIndex && arrArg[endIndex] > firstValue) {
endIndex--;
}
arrArg[emptyIndex] = arrArg[endIndex];
emptyIndex = endIndex;
while (startIndex < endIndex && arrArg[startIndex] < firstValue) {
startIndex++;
}
arrArg[emptyIndex] = arrArg[startIndex];
emptyIndex = startIndex;
}
arrArg[emptyIndex] = firstValue;
quickSort(arrArg, startIndexArg, emptyIndex - 1);
quickSort(arrArg, emptyIndex + 1, endIndexArg);
}
}
module.exports = {
MySort: MySort,
};
4.3 前后指针法
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
quickSort(arr, 0, arr.length - 1);
}
return result;
}
function quickSort(arrayArg, startIndex, endIndex) {
if (startIndex < endIndex) {
const keyValue = arrayArg[startIndex];
let currentIndex = startIndex + 1;
let prevIndex = startIndex;
while (currentIndex <= endIndex) {
if (
arrayArg[currentIndex] < keyValue &&
++prevIndex !== currentIndex
) {
swapItem(arrayArg, prevIndex, currentIndex);
}
currentIndex++;
}
swapItem(arrayArg, prevIndex, startIndex);
quickSort(arrayArg, startIndex, prevIndex - 1);
quickSort(arrayArg, prevIndex + 1, endIndex);
}
}
function swapItem(arrayArg, fromIndex, toIndex) {
let temp = arrayArg[fromIndex];
arrayArg[fromIndex] = arrayArg[toIndex];
arrayArg[toIndex] = temp;
}
module.exports = {
MySort: MySort,
};
5 归并排序(Merge)
5.1 先把所有元素,尝试递归折半分成两组,直到左右两边各只剩一个,然后再合并左右两边的数组,合并两个有序数组是简单算法题,这里不细说。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
result = divideSort(arr);
}
return result;
}
function divideSort(arrayArg) {
let result = arrayArg;
if (arrayArg.length > 1) {
result = [];
const middle = Math.floor(arrayArg.length / 2);
let leftArray = divideSort(arrayArg.slice(0, middle));
let rightArray = divideSort(arrayArg.slice(middle));
let leftIndex = 0;
let rightIndex = 0;
while (result.length < arrayArg.length) {
if (leftArray[leftIndex] < rightArray[rightIndex]) {
result.push(leftArray[leftIndex++]);
if (leftIndex === leftArray.length) {
result.push(...rightArray.slice(rightIndex));
}
} else {
result.push(rightArray[rightIndex++]);
if (rightIndex === rightArray.length) {
result.push(...leftArray.slice(leftIndex));
}
}
}
}
return result;
}
module.exports = {
MySort: MySort,
};
6 堆排序(Heap)
6.1 堆排序,也可以理解为二叉树排序,这里的堆分为两种,一种是大顶堆,一种是小顶堆,我们所有的排序方法都以升序为主,其实倒序原理也都差不多,所以这里我们主要分析的是大顶堆。大顶堆就是根节点不小于他的两个子节点。
sd
7 桶排序(Bucket)
7.1 桶排序是将数组分散到有限的桶中,然后每个桶再分别排序,而每个桶的排序又可以使用其他排序方式进行排序,可以是桶排序也可以是其他排序。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
result = divideSort(arr);
}
return result;
}
function divideSort(arrayArg) {
let result = arrayArg;
if (arrayArg.length > 1) {
result = [];
const middle = Math.floor(arrayArg.length / 2);
let leftArray = divideSort(arrayArg.slice(0, middle));
let rightArray = divideSort(arrayArg.slice(middle));
let leftIndex = 0;
let rightIndex = 0;
while (result.length < arrayArg.length) {
if (leftArray[leftIndex] < rightArray[rightIndex]) {
result.push(leftArray[leftIndex++]);
if (leftIndex === leftArray.length) {
result.push(...rightArray.slice(rightIndex));
}
} else {
result.push(rightArray[rightIndex++]);
if (rightIndex === rightArray.length) {
result.push(...leftArray.slice(leftIndex));
}
}
}
}
return result;
}
module.exports = {
MySort: MySort,
};
8 基数排序(Radix)
8.1 基数排序的方式可以采用最低位优先LSD(Least sgnificant digital)法或最高位优先MSD(Most sgnificant digital)法,LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
result = divideSort(arr);
}
return result;
}
function divideSort(arrayArg) {
let result = arrayArg;
if (arrayArg.length > 1) {
result = [];
const middle = Math.floor(arrayArg.length / 2);
let leftArray = divideSort(arrayArg.slice(0, middle));
let rightArray = divideSort(arrayArg.slice(middle));
let leftIndex = 0;
let rightIndex = 0;
while (result.length < arrayArg.length) {
if (leftArray[leftIndex] < rightArray[rightIndex]) {
result.push(leftArray[leftIndex++]);
if (leftIndex === leftArray.length) {
result.push(...rightArray.slice(rightIndex));
}
} else {
result.push(rightArray[rightIndex++]);
if (rightIndex === rightArray.length) {
result.push(...leftArray.slice(leftIndex));
}
}
}
}
return result;
}
module.exports = {
MySort: MySort,
};
9 希尔排序(Shell)
9.1 希尔排序也成缩小增量排序,原理是将待排序列划分为若干组,每组都是不连续的,有间隔step,step可以自己定,但间隔step最后的值一定是1,也就说最后一步是前后两两比较。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
result = divideSort(arr);
}
return result;
}
function divideSort(arrayArg) {
let result = arrayArg;
if (arrayArg.length > 1) {
result = [];
const middle = Math.floor(arrayArg.length / 2);
let leftArray = divideSort(arrayArg.slice(0, middle));
let rightArray = divideSort(arrayArg.slice(middle));
let leftIndex = 0;
let rightIndex = 0;
while (result.length < arrayArg.length) {
if (leftArray[leftIndex] < rightArray[rightIndex]) {
result.push(leftArray[leftIndex++]);
if (leftIndex === leftArray.length) {
result.push(...rightArray.slice(rightIndex));
}
} else {
result.push(rightArray[rightIndex++]);
if (rightIndex === rightArray.length) {
result.push(...leftArray.slice(leftIndex));
}
}
}
}
return result;
}
module.exports = {
MySort: MySort,
};
10 树排序(Tree)
10.1 利用二叉搜索树(BST)结构进行排序,插入元素时维护二叉树的有序性,最后进行中序遍历得到有序序列。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
result = divideSort(arr);
}
return result;
}
function divideSort(arrayArg) {
let result = arrayArg;
if (arrayArg.length > 1) {
result = [];
const middle = Math.floor(arrayArg.length / 2);
let leftArray = divideSort(arrayArg.slice(0, middle));
let rightArray = divideSort(arrayArg.slice(middle));
let leftIndex = 0;
let rightIndex = 0;
while (result.length < arrayArg.length) {
if (leftArray[leftIndex] < rightArray[rightIndex]) {
result.push(leftArray[leftIndex++]);
if (leftIndex === leftArray.length) {
result.push(...rightArray.slice(rightIndex));
}
} else {
result.push(rightArray[rightIndex++]);
if (rightIndex === rightArray.length) {
result.push(...leftArray.slice(leftIndex));
}
}
}
}
return result;
}
module.exports = {
MySort: MySort,
};
11 计数排序(Counting)
11.1 计数排序是一个非基于比较的排序算法,他首先要找到数组的最大值和最小值然后再根据最大值和最小值申请频率表,其实就是个数组,每个数在数组中出现的频率。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
result = divideSort(arr);
}
return result;
}
function divideSort(arrayArg) {
let result = arrayArg;
if (arrayArg.length > 1) {
result = [];
const middle = Math.floor(arrayArg.length / 2);
let leftArray = divideSort(arrayArg.slice(0, middle));
let rightArray = divideSort(arrayArg.slice(middle));
let leftIndex = 0;
let rightIndex = 0;
while (result.length < arrayArg.length) {
if (leftArray[leftIndex] < rightArray[rightIndex]) {
result.push(leftArray[leftIndex++]);
if (leftIndex === leftArray.length) {
result.push(...rightArray.slice(rightIndex));
}
} else {
result.push(rightArray[rightIndex++]);
if (rightIndex === rightArray.length) {
result.push(...leftArray.slice(leftIndex));
}
}
}
}
return result;
}
module.exports = {
MySort: MySort,
};
12 拓扑排序(Topological)
12.1 对有向无环图(DAG)进行顶点排序,使得对于每一条有向边U -> V,顶点U在顶点V之前出现在排序中。
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 将给定数组排序
* @param arr int整型一维数组 待排序的数组
* @return int整型一维数组
*/
function MySort(arr) {
// write code here
let result = arr;
if (result.length > 1) {
result = divideSort(arr);
}
return result;
}
function divideSort(arrayArg) {
let result = arrayArg;
if (arrayArg.length > 1) {
result = [];
const middle = Math.floor(arrayArg.length / 2);
let leftArray = divideSort(arrayArg.slice(0, middle));
let rightArray = divideSort(arrayArg.slice(middle));
let leftIndex = 0;
let rightIndex = 0;
while (result.length < arrayArg.length) {
if (leftArray[leftIndex] < rightArray[rightIndex]) {
result.push(leftArray[leftIndex++]);
if (leftIndex === leftArray.length) {
result.push(...rightArray.slice(rightIndex));
}
} else {
result.push(rightArray[rightIndex++]);
if (rightIndex === rightArray.length) {
result.push(...leftArray.slice(leftIndex));
}
}
}
}
return result;
}
module.exports = {
MySort: MySort,
};