荷兰国旗问题:给定一个数组arr,和一个数num,请把小于num的数放在数组的 左边,等于num的数放在数组的中间,大于num的数放在数组的 右边。
function partition (arr, left, right, num) {
// arr:数组 left:左边界 right: 右边界
let index = left;
let equalNumArray = []; // 保存等于num 区域的左右边界
let less = left - 1; // 小于num区域的下标指针
let more = right + 1; // 大于num区域的下标指针
// debugger;
while(index < more) {
if (arr[index] < num) {
swap(arr, ++less, index++);
} else if (arr[index] > num) {
swap(arr, --more, index);
} else {
index++;
}
}
equalNumArray.push(less+1 ,more-1)
return equalNumArray;
}
// 交换数组对应参数位置的元素
function swap(arr, i, j) {
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function generateArray() {
let arr = new Array(10);
for (let i = 0; i< arr.length; i++) {
arr[i] = Math.floor(Math.random() * 5);
}
return arr;
}
let test = generateArray();
console.log(test);
let res = partition(test, 0, test.length-1, 2);
console.log(test);
console.log(res[0] + "---" + res[1]);
经典快排(跟数组的数据状况有关,最坏情况时间复杂度为 O(N*N))和随机快排,时间复杂度是一个概率事件,数学期望为O(N*logN)
function quickSort(arr) {
// 对传入的所有数组进行快排, 选取的基准值为数组的最后一项
if (arr.length < 2) {
return;
}
quickSortRandom(arr, 0, arr.length - 1);
}
function quickSortRandom(arr, leftIndex, rightIndex) {
// 随机元素快排
if (leftIndex < rightIndex) {
swap(arr, leftIndex + Math.floor((rightIndex - leftIndex + 1) * Math.random()), rightIndex);
let p = partition(arr, leftIndex, rightIndex); // p接收 partition后的等于选取的那个区域的左边界和有边界
quickSortRandom(arr, leftIndex, p[0] - 1);
quickSortRandom(arr, p[1] + 1, rightIndex);
}
}
function partition(arr, left, right) {
let equalArrayIndex = [];
let less = left - 1;
let more = right;
while (left < more) {
if (arr[left] < arr[right]) {
swap(arr, ++less, left++);
} else if (arr[left] > arr[right]) {
swap(arr, --more, left);
} else {
left++;
}
}
swap(arr, more, right);
equalArrayIndex.push(less+1, more);
return equalArrayIndex;
}
function swap(arr, index1, index2) {
let temp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = temp;
}
// 判断两个数组是否相等
function isEqual(arr1, arr2) {
if (arr1 !==0 && arr2.length === 0) {
return false;
}
if (arr1.length === 0 && arr2.length !== 0) {
return false;
}
if (arr1.length !== arr2.length) {
return false;
}
if (arr1.length === 0 && arr2.length === 0) {
return true;
}
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) {
return false;
}
}
return true;
}
// 随机数组发生器
function generateRandomArray(maxSize, maxValue) {
let arr = new Array(Math.floor((maxSize+1) * Math.random()))
for (let i = 0; i < arr.length; i++) {
arr[i] = Math.floor((maxValue + 1) * Math.random()) - Math.floor(maxValue * Math.random())
}
return arr;
}
let testTime = 50000,
maxSize = 100,
maxValue = 100,
isSucceed = true;
for (let i = 0; i < testTime; i++) {
let arr1 = generateRandomArray(maxSize, maxValue);
let arr2 = arr1.slice(0);
quickSort(arr1);
arr2.sort((a,b) => a-b);
if (!isEqual(arr1, arr2)) {
isSucceed = false;
console.log("快排结果" + arr1);
console.log("对数器排序结果" + arr2);
break;
}
}
if (isSucceed) {
console.log("it works");
} else {
console.log('it falsed');
}
let array1 = generateRandomArray(maxSize, maxValue);
console.log(array1);
quickSort(array1);
console.log("排序后" + array1);