Seven sorting algorithms of the front end

Kobayashi, who was tortured by the algorithm in the front-end interview, is ready to work hard and prepare the high-frequency algorithm questions in the interview. Because the front-end algorithm is easier than the back-end hand tearing algorithm, Xiaobian is ready to start with the most basic seven sorting algorithms. High energy ahead, please hold the steering wheel

1, Bubble sorting
Bubble sorting idea: traverse the array, and then sink the maximum number to the bottom< Br / > time complexity: O(N^2)< Br / > space complexity: O(1)

function BubbleSort(arr) {

if(arr == null || arr.length <= 0){
    return [];
}
var len = arr.length;
for(var end = len - 1; end > 0; end--){
    for(var i = 0; i < end; i++) {
        if(arr[i] > arr[i + 1]){
            swap(arr, i, i + 1);
        }
    }
}
return arr;

}
function swap(arr, i, j){

// var temp = arr[i];
// arr[i] = arr[j];
// arr[j] = temp;
//The exchange can also use the XOR operator
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];

}
  

2, Select sort
Select the implementation idea of sorting: traverse the array and put the most decimal in the head< Br / > time complexity: O(N^2)< Br / > space complexity: O(1)

function SelectionSort(arr) {

if(arr == null || arr.length < 0) {
    return [];
}
for(var i = 0; i < arr.length - 1; i++) {
    var minIndex = i;
    for(var j = i + 1; j < arr.length; j++) {
        minIndex = arr[j] < arr[minIndex] ? j : minIndex;
    }
    swap(arr, i, minIndex);
}
return arr;

}

function swap(arr, i, j) {

arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];

}
3, Insert sort
Implementation idea of insertion sorting: compare a new number with the previous one. As long as the current number is less than the previous one, it will exchange positions with the previous one, otherwise it will terminate< Br / > time complexity: O(N^2)< Br / > space complexity: O(1)

function insertSort(arr) {

if(arr == null  || arr.length <= 0){
    return [];
}
var len = arr.length;
for(var i = 1; i < len; i++) {
    for(var j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
        swap(arr, j, j + 1);
    }
}
return arr;

}

function swap(arr, i, j){

var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;

}
4, Merge sort
The idea of merging and sorting: < br / > 1. Arrange the left part first < br / > 2. Then arrange the right part < br / > 3. Prepare an auxiliary array, use the method of outer row, start filling in small until one moves to the end, and copy the rest of the other array to the end < br / > 4. Then copy the auxiliary array back to the original array < br / > time complexity: O (n logn) < br / > space complexity: O(N)*

//Recursive implementation

function mergeSort(arr){

if(arr == null  || arr.length <= 0){
    return [];
}
sortProcess(arr, 0, arr.length - 1);
return arr;

}

function sortProcess(arr, L, R){

//The termination condition of recursion is that the left and right boundary indexes are the same
if(L == R){
    return;
}
var middle = L + ((R - L) >> 1);//Find the intermediate value
sortProcess(arr, L, middle);//Recursion of the left part
sortProcess(arr, middle + 1, R);//Recursion of the right part
merge(arr, L, middle, R);//Then the combination is carried out by means of efflux

}

function merge(arr, L, middle, R){

var help = [];
var l = L;
var r = middle + 1;
var index = 0;
//By means of external discharge
while(l <= middle && r <= R){
    help[index++] = arr[l] < arr[r] ? arr[l++] : arr[r++];
}
while(l <= middle){
    help.push(arr[l++]);
}
while(r <= R){
    help.push(arr[r++]);
}

for(var i = 0; i < help.length; i++) {
    arr[L + i] = help[i];
}
//arr.splice(L, help.length, ...help);// This takes advantage of the syntax of ES6

}

//Loop implementation

function mergeSort(arr){

if(arr ==null || arr.length <= 0){
    return [];
}
var len = arr.length;
//i multiply by 2 each time, because after each merge, the group elements become twice as many
for(var i = 1; i < len; i *= 2){
    var index = 0;//Starting index of the first group
    while( 2 * i  + index <= len){
        index += 2 * i;
        merge(arr, index - 2 * i, index - i, index);
    }
    //Explain the remaining two groups, but the number of data in one group is less than the power of 2
    if(index + i < len){
        merge(arr, index, index + i, len);
    }
}
return arr;

}

//The combination is carried out by means of external discharge
function merge(arr, start, mid, end){

//Create a new auxiliary array
var help = [];
var l = start, r = mid;
var i = 0;
while(l < mid && r < end){
    help[i++] = arr[l] < arr[r] ? arr[l++] : arr[r++];
}
while(l < mid){
    help[i++] = arr[l++];
}
while(r < end){
    help[i++] = arr[r++];
}
for(var j = 0; j < help.length; j++){
    arr[start + j] = help[j];
}

}

5, Quick sort
Implementation idea of quick sorting: randomly take out a value and divide it. If it is greater than the value, put it on the right and if it is less than the value, put it on the left (the algorithm is modified based on the Dutch flag idea and random idea on the basis of classical quick sorting) < br / > time complexity: O (nlogn) < br / > space complexity: O(logN)*

function quickSort(arr) {

if(arr == null || arr.length <= 0){
    return [];
}
quick(arr, 0, arr.length - 1);

}

function quick(arr, L, R){

//The recursive end condition is l > = R
if(L < R){
    //Randomly find a value, and then exchange it with the last value to change the classical sort into quick sort
    swap(arr, L + Math.floor(Math.random() * (R - L + 1)), R);
    //The Dutch flag problem is used to obtain the divided boundary. The returned values are the maximum index less than the region and the minimum index greater than the region. In this case, the Dutch flag problem will be equal to the region and the part will not be moved
    var tempArr = partition(arr, L, R, arr[R]);
    quick(arr, L, tempArr[0]);
    quick(arr, tempArr[1], R);
}

}
//The return value is the last index less than the region and the first index greater than the region
function partition(arr, L, R, num){

var less = L - 1;
var more = R + 1;
var cur = L;
while(cur < more){
    if(arr[cur] < num){
        swap(arr, ++less, cur++);
    }else if(arr[cur] > num) {
        swap(arr, --more, cur);
    }else{
        cur++;
    }
}
return [less, more];

}
function swap(arr, i, j){

var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;

}
6, Heap sort
Heap sorting idea: < br / > 1. Make the array into a large root heap < br / > 2. Exchange the last position with the top of the heap < br / > 3. Then the maximum value is at the end, and the rest is heapify, Front end training Readjust to a large root heap, and the heap top position and the last position of this part are exchanged < br / > 4. Repeat until the subtraction is completed, and then the adjustment is completed. The whole array is sorted (in ascending order) < br / > time complexity: O (n logn) < br / > space complexity: O(1)*

function heapSort(arr) {

if(arr == null || arr.length <= 0) {
    return [];
}

//The first is the process of building a large top reactor
for(var i = 0; i < arr.length; i++) {
    heapInsert(arr, i);
}
var size = arr.length;//This value is used to specify how many arrays are stacked. When a sorted value is obtained, this value is subtracted by one
//Swap the top of the heap with the last position
/**
 * After the large top stack is established, the last position is continuously exchanged with the top of the stack;
 * In this way, the maximum value is at the end. The rest is heapify and readjusted to the large root heap. The heap top position and the penultimate position are exchanged and repeated until all sorting is completed*/
//Since there is already a large top pile in front, it is directly exchanged
swap(arr, 0, --size);
while(size > 0) {
    //Become a big top pile again
    heapify(arr, 0, size);
    //Exchange
    swap(arr, 0, --size);
}

}

//During stacking
function heapInsert(arr, index) {

//Compare the current position with its parent position. If it is greater than its parent position, exchange and move the index to its parent position for circulation. Otherwise, skip
//The end condition is smaller than the parent position or reaches the root node
while(arr[index] > arr[parseInt((index - 1) / 2)]){
    //Exchange
    swap(arr, index, parseInt((index - 1) / 2));
    index = parseInt((index - 1) / 2);
}

}
//Reactor reduction process
/**

  • size refers to how many numbers in front of the array form a heap
  • If you want to eject the top of the heap, exchange the top of the heap with the last number, reduce the size by 1, and then experience heapify from position 0. Adjust it, and the rest will become a large top heap*/

function heapify(arr, index, size) {

var left = 2 * index + 1;
while(left < size) {
    var largest = (left + 1 < size && arr[left] < arr[left + 1]) ? left + 1 : left;
    largest = arr[index] > arr[largest] ? index : largest;

    //If the maximum index is the same as the passed in index, the value reaches the specified position and ends the cycle directly
    if(index == largest) {
        break;
    }

    //Swap and change the index and its left child node
    swap(arr, index, largest);
    index = largest;
    left = 2 * index + 1;
}

}

function swap(arr, i, j) {

var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;

}
7, Bucket sorting
Bucket sorting will go through three iterations: preparing an array, traversing the array and reconstructing the array. It is a sort based on right and wrong comparison. Here is a question to explain its idea< Br / > problem: < br / > given an array, finding the maximum difference between two adjacent numbers after sorting requires time complexity O(N), and comparison based sorting cannot be used < br / >

Idea: < br / > 1. Prepare buckets: if there are N buckets in the array, prepare N+1 buckets < br / > 2. Traverse the array and find the maximum value max and minimum value min

. If min = max, the difference = 0; If min ≠ max, the minimum value is placed in barrel 0 and the maximum value is placed in barrel N, and the remaining number belongs to which barrel < br / > 3. According to the pigeon cage principle, one barrel must be empty. The barrel is designed to deny that the maximum value is in one barrel, and the two numbers of the maximum difference must come from two barrels, However, the maximum value on both sides of the empty bucket is not necessarily < br / > 4. Therefore, only the minimum value min and maximum value Max entering the bucket and a Boolean value indicating whether the bucket has a value < br / > 5. Then traverse the array. If the bucket is empty, skip to the next number. If the bucket is not empty, find the previous non empty bucket, and the maximum difference = current bucket min - previous non empty bucket max, Update the maximum value with global variables < br / > time complexity: O(N) < br / > space complexity: O(N)

function maxGap(arr) {

if(arr == null || arr.length <= 0) {
    return 0;
}
var len = arr.length;
var max = -Infinity, min = Infinity;
//Traverse the array to find the maximum value max and the minimum value min
for(var i = 0; i < len; i++) {
    max = max > arr[i] ? max : arr[i];
    min = min > arr[i] ? arr[i] : min;
}

//If min = max, the difference is 0;
if(min == max) {
    return 0;
}

var hasNum = new Array(len + 1);
var mins = new Array(len + 1);
var maxs = new Array(len + 1);

var bid = 0;//Specifies the bucket number

for(var i = 0; i < len; i++) {
    bid = bucket(arr[i], min, max, len);//Obtain the bucket in which the value is in / / because there are N+1 buckets, the interval is N, so here you divide by len, and then use this function to get the bucket in which to put it
    maxs[bid] = hasNum[bid] ? Math.max(arr[i], maxs[bid]) : arr[i];
    mins[bid] = hasNum[bid] ? Math.min(arr[i], mins[bid]) : arr[i];
    hasNum[bid] = true;
}

var res = 0;
var lastMax = maxs[0];

for(var i = 0; i < len + 1; i++) {
    if(hasNum[i]) {
        res = Math.max(mins[i] - lastMax, res);
        lastMax = maxs[i];
    }
}
return res;

}

//Get bucket number
//This function is used to determine in which bucket the parameters are value, minimum value, maximum value and bucket interval
function bucket(value, min, max, len) {

return parseInt((value - min) / ((max - min) / len));

}

Tags: Front-end html5

Posted on Fri, 03 Dec 2021 05:08:11 -0500 by notionlogic