Preface
Sorting is one of the most common operations performed on stored data in a computer. The grammar is simple but exquisite. In the sorting algorithm, loops are indispensable. Only when we study the sorting algorithm in depth, we can find that the usual insignificant loop statements can not be underestimated.
Take the simplest bubble sort for example, I understand the truth, but why would you think of two nested loop statements? Why are the conditions of two-tier loop statements different? What is the correlation logic of two-tier loops? What role does circulation play in bubbling? What logic does the loop bubbles through? Wait. Behind these problems, it is worth exploring.
loop
Before we get to the point, we need to say a little episode. Because of the cold winter of the Internet, programmers have a sense of crisis. In this crisis, the screening conditions for programmers have become more stringent. Whether front-end or back-end, it is best to be familiar with some basic algorithms. So brush algorithm problems are also popular among programmers. A colleague next to me brushed an interesting algorithm and said it was interesting. Let me try it. Truth be told, as a front-end, in addition to simply processing the interface data, there is really no training exam-oriented algorithm.
The title is roughly like this. In the n*n plane, a number of numbers starting with 1 are arranged in an orderly spiral in half space.
The drawings are as follows:
<center>
</center>
With the deepening of thinking, suddenly found that this tm is not a mathematical problem? (Forgive me for speaking rudely)
Find out the known, list the unknown, and associate the known unknown, then the difference is x and y.
Take 5*5 as an example:
var arr = Array.from({length: 5}).map(item => ([])); var i = 1; function Sort(init, length){ let m = init, n= init; while(m < length){ arr[m++][init] = i++; } --m; while(n < length -1) { arr[--m][++n] = i++; } --n; while(n > init) { arr[m][n--] = i++; } if (length <= 3) return arr; Sort(n+1, length - 2); } console.log(Sort(0, 5), arr)
What changes is the unknown. Find out the cyclic conditions and correlate the known ones so that the equation can be listed. Here I imagine the plane as plane coordinates, m, n as x, y axis, array is the set of coordinate points, the condition of digital spiral inversion as a recursive condition, so a rough algorithm is completed.
Although it is not very relevant to this topic, it is very inspiring, so I think there is a close relationship between program and mathematics. Back in this section, take the simplest for loop for example.
let arr = [1, 2, 3]; for(let i = 0;i < arr.length; i++){}
This is the simplest for loop writing. From this simple for statement, we can know the number of cycles I (currently), the number of cycles arr.length and the driving i++ of the cycle. It's important to note that I increases with the cycle. The cycle is so simple, there is no other magic.
In sorting algorithm, there is another point to be noted, that is, array. In JavaScript, array elements are not contiguous in memory. We can refer to the elements of the corresponding location by index. More importantly, when we usually operate on an array element, we do not operate on the array element itself, but on variables at that location. We can imagine that each index position is a variable, and then by assigning array elements to variables.
Loops and arrays, if used alone, are nothing. If you combine the two, you will find that as the number of cycles increases, the array index will also increase, combined with some logic, you can move some elements to the designated location.
So, what kind of logic do they all combine?
Bubble sort
Bubble sorting logic assigns larger elements to the next index position of the current location index by comparing them. Then, as the cycle increases, the current index will increase, and ultimately the maximum value will be pushed to the end. Then the process is repeated many times, and finally the penultimate second and the penultimate third... Moves to the designated position.
function bubbleSort(arr){ let len = arr.length; for(let i = 0; i < len - 1; i++){ for(let j = 0; j < len - 1 - i; j++){ // Incremental replacement of current elements; if (arr[j] > arr[j+1]){ // Comparisons of adjacent elements; [arr[j], arr[j+1]] = [arr[j+1], arr[j]]; // Position interchange; } } } return arr; }
Selective Sorting
Select the sorting logic, compare the current array elements, find the index of the smallest elements, and move the elements of the location to the specified location. Then iterate over and over again, and finally move the second and third small elements of the remaining array elements to the specified location.
function selectionSort(arr){ let len = arr.length; for(let i = 0; i < len - 1; i++){ let minIndex = i; for(let j = i + 1; j < len; j ++){ // Incrementally replace the current element; if(arr[j] < arr[minIndex]){ minIndex = j; // Update Minimum Element Index; } } [arr[minIndex], arr[i]] = [arr[i], arr[minIndex]]; // Exchange position with minimum element; } return arr; }
Insertion sort
Insert sort logic, compare current array elements with previous array elements, and insert them into the appropriate location.
function insertionSort(arr){ let len = arr.length; for(let i = 1; i < len; i++){ let temp = arr[i]; let preIndex = i -1; while(preIndex >= 0 && arr[preIndex] > temp){ arr[preIndex + 1] = arr[preIndex--]; // If the location element is smaller than the current element, it will be moved later. } arr[preIndex+1] = temp; } return arr; }
Shell Sort
Hill sort is an upgraded version of insert sort. The insert sort is compared with the previous array elements one by one, while Hill sort is grouped several times at a specific interval, so it is very similar in code.
function shellSort(gap, arr){ let len = arr.length; for(let i = 0; i < gap.length; i++){ // Group comparison was made at different intervals. for(let j = gap[i]; j < len; j++){ // Start at the next index position of the interval. let temp = arr[j]; let preGapIndex = j - gap[i]; while(preGapIndex >= 0 && arr[preGapIndex] > temp){ // The current element is compared with the previous fixed interval index location element. arr[preGapIndex + gap[i]] = arr[preGapIndex]; preGapIndex = preGapIndex - gap[i]; } arr[preGapIndex + gap[i]] = temp; } } return arr; }
Merge Sort
Merge sorting logic divides arrays into smaller pairs by recursion, and resynthesizes complete arrays by comparison. In this paper, the top-down merge sort is adopted, and the bottom-up merge sort can also be used.
function mergeSort(arr){ let len = arr.length; if(len < 2) return arr; let middle = Math.floor(len/2); // Grouping; let left = arr.slice(0, middle); let right = arr.slice(middle); return merge(mergeSort(left), mergeSort(right)); } function merge(left, right){ let len = left.length + right.length; let result = [], m = 0, n = 0; left[left.length] = Infinity; right[right.length] = Infinity; for(let i = 0; i < len; i++){ // The number of cycles is the length of the new array. if(left[m] <= right[n]){ // Compare left and right elements of arrays and rearrange them into new arrays. result[i] = left[m]; m++; }else{ result[i] = right[n]; n++; } } return result; }
Quick sort
Quick sort logic chooses the base value from the array, moves the elements larger than the base value to the right array, moves the elements smaller than the base value to the left array, and recursively loops this operation until the array is empty. Then merge the arrays, and finally get the sorted new arrays.
function quickSort(arr){ if(arr.length < 1) return arr; let len = arr.length; let pivot = arr[0]; // Setting the reference value; let lesser = [], greater = []; for(let i = 1; i < len; i++){ if(arr[i] < pivot){ lesser.push(arr[i]); // Push the value below the base to the left. } else { greater.push(arr[i]); // Push the value above the base to the right. } } return quickSort(lesser).concat(pivot, quickSort(greater)); }
over!