To do programming, sequencing is a necessary requirement. The front end is no exception, although not many, but you will certainly encounter.
But when it comes to sorting, the easiest thing to think about is bubble sort, sort by, and insert Sort.
Bubble sort
Compare adjacent two elements in turn, if the latter is less than the previous one, then swap, so that the maximum is placed at the End.
From start to finish again, because each round, the final is already the largest, so the next round need to compare the number of less than the last One. Although you can still let him compare from beginning to end, but behind the comparison is meaningless useless, for efficiency, you should optimize the Code.
The picture shows as Follows:
Code implementation:
|
function bubblesort (arr) { var len = arr.length; for (var i = 0, i < len- 1; i++) {for (var j = 0; J < len- 1-i; J + +) { If (arr[j] > arr[j+1]) { //adjacent element 22 vs var temp = arr[j+1]; //element Exchange arr[j+1] = arr[j]; arr[j] = temp;}} } return arr;}
|
Select sort
Select Sort I think is the simplest, a freshman to learn vb, just remember this sorting method, the principle is very simple: each time to find a maximum or the smallest row in the beginning Can.
First find the smallest (large) element in the unordered sequence, and place it at the beginning of the sort sequence
Then continue looking for the smallest (large) element from the remaining unsorted elements and place it at the end of the sorted sequence.
Repeat the second step until all the elements are Sorted.
Dynamic Diagram Demo:
Code demo:
|
function selectionsort (arr) {var len = arr.length; var minindex, temp; for (var i = 0; i < Len-1; I++) {minindex = i; for (var j = i + 1; J < len; J + +) {
if (arr[j] < arr[minindex]) {
//looking for the smallest number Minindex = j; //save The index of the smallest number}" temp = arr[i]; arr[i] = arr[minindex]; arr[minindex] = temp; } return arr;
|
Insert Sort
Inserting a sort is also relatively straightforward. Just like playing poker, the elements you get are inserted in the correct position in Turn.
The first element of the first order sequence is treated as an ordered sequence, and the second element to the last element as an unordered sequence.
Scans the unordered sequence from beginning to end, inserting each element scanned into the appropriate position of the ordered Sequence. (if the element you want to insert is equal to an element in an ordered sequence, insert the element you want to insert behind the equal element.) )
Dynamic Diagram Demo:
Code example:
|
function insertionSort(arr) { var len = arr.length; var preIndex, current; for (var i = 1; i < len; i++) { preIndex = i - 1; current = arr[i]; while(preIndex >= 0 && arr[preIndex] > current) { arr[preIndex+1] = arr[preIndex]; preIndex--; } arr[preIndex+1] = current; } return arr;}
|
The simple cost is inefficient
The above three kinds are very simple sorting methods, simple at the same time, the efficiency will be relatively low, or take the book of the comparison chart to illustrate:
The time complexity is up to o (n^2), and some of the sorting algorithms behind them have a basic O (n log n) of time Complexity.
My obsessive-compulsive disorder, I want a more efficient sorting method.
Merge sort
Simply put the contents of the book over again, then understand the merge sort, so here is a talk about this merge Sort.
The basic principle is divide and conquer, that is, separate and return the Sort.
The steps are as Follows:
- The space is applied to the sum of two sorted sequences, which is used to store the merged sequence;
- Set two pointers, the initial position is the starting position of two sorted sequences;
- Compare the elements pointed to by two pointers, select a relatively small element into the merge space, and move the pointer to the next position;
- Repeat step 3 until a pointer reaches the end of the sequence;
- Copies all the remaining elements of another sequence directly to the end of the merge Sequence.
Dynamic Diagram Demo:
Code example:
|
functionMergeSort (Arr) {Using a top-down recursive approachvar len = arr.length;If (len <2) {Return arr; }var middle =math.floor (len/2), left = Arr.slice ( 0, middle), right = Arr.slice (middle); return merge (mergesort (left), mergesort (right));} function merge ( left, right) {var result = []; 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;}
|
Since is a love toss the person, toss a must see effect bar.
Efficiency test
Because I'm learning this to sort not a simple array, an array is an object, you want to sort a property of an object, and you want to consider the ascending order.
So my code is implemented as Follows:
|
/** * [merge sort] * @param {[array]} arr [array to sort] * @param {[String]} prop [sort field, used for an array member is an object, sort by one of its properties, simple array direct sort ignores this parameter] * @ param {[String]} Order [sort by omitted or ASC to ascending otherwise descending] * @return {[array]} [sorted array, new array, not modified on original array] */var mergesort = (function) {Mergevar _merge =functionleft, right, PROP) {var result = [];Sort an attribute of a member within an arrayIf (PROP) {While (left.length && Right.length) {If (left[0][prop] <= right[0][prop]) {result.push (left.shift ());}else {result.push (right.shift ());}} }else {Array member Direct orderingWhile (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; };var _mergesort =functionarr, PROP) {Using a top-down recursive approachvar len = arr.length;If (len <2) {Return arr; }var middle =Math.floor (len/2), left = Arr.slice (0, middle), right = Arr.slice (middle); return _merge (_mergesort (left, prop), _mergesort (right, prop), prop);}; return function (arr, prop, order) {var result = _mergesort (arr, prop); if (!order | | order.tolowercase () = = = ' ASC ') {// Ascending return result; else {//descending var _ = []; Result.foreach (function (item) {_.unshift (item);}); return _;} };}) ();
|
Which property needs to be sorted is indeterminate and can be arbitrarily specified, so it is written as a parameter. There is a bit of redundancy in the code because you don't want these things to be judged in every loop.
The problem of descending, nor the addition of parameters, but the simple ascending order and then reverse the Output. The reason is that we do not want to judge the conditions in each loop recursively, so we simply deal with Them.
Here is the time to witness efficiency, a data simulation:
|
var getData = function() { return Mock.mock({ "list|1000": [{ name: ‘@cname‘, age: ‘@integer(0,500)‘ }] }).list;};
|
The actual test came:
|
Efficiency testvar arr = GetData ();Console.time (' Merge sort '); mergesort (arr,' Age '); console.timeend (' merge sort '); Console.time (' bubble sort '); for (var i = 0, L = arr.length; i < l- 1; ++i) { var temp; for (var j = 0; J < l-i- 1; ++j) { if (arr[j].age > arr[j + 1].age) {temp = arr[j + 1]; Arr[j + 1] = arr[j]; arr[j] = temp;}}} console.timeend (' bubble sort ');
|
Five times, the effect is as Follows:
|
// 归并排序: 6.592ms// 冒泡排序: 25.959ms// 归并排序: 1.334ms// 冒泡排序: 20.078ms// 归并排序: 1.085ms// 冒泡排序: 16.420ms// 归并排序: 1.200ms// 冒泡排序: 16.574ms// 归并排序: 2.593ms// 冒泡排序: 12.653ms
|
The lowest 4 times times, the highest nearly 16 times times the efficiency of the difference is more satisfactory.
Although 1000 of the data makes the front-end sort of a little less likely, there are hundreds of cases. In addition, because node, JavaScript can also run the service side, the efficiency of the promotion also has a useful.
A Little doubt
Recursion is used in the merge sort, and in the "DATA structure and algorithm JavaScript description", the author gives a bottom-up iterative method. But for the recursive method, the author thinks:
however, It is not possible to do so in JavaScript, as the recursion goes too deep for the language to Handle.
however, This approach is not feasible in JavaScript because the recursive depth of the algorithm is too deep for it.
The author of the book on Gitbook has doubts about it, and I have doubts about it.
Although recursion was used in the merge, he put it after Return. The recursion after Renturn is optimized by tail Recursion.
On the tail recursive optimization refers to: the outer function is called to call a function inside, because the outer function needs to wait for the inner layer function to return after the result, into the inner layer function, the outer function of the information, memory is to remember, that is, the call Stack. When the inner function is placed on the return keyword, it means that the outer function is ended, and after entering the inner function, it is not necessary to memorize all the information in the outer Function.
The above is my understanding of the description, do not know the calculation is not Accurate. It's possible to turn on tail-recursive optimization under chrome, and I don't think this recursion should affect his use of JavaScript.
At last
If you are interested, it is recommended to read this book and to sort it out, consider some more efficient methods.
however, It is important to note that these efficient sequencing methods generally require a relatively large amount of additional memory space, which needs to be weighed.
In addition, very small-scale data is not necessary. One is that the impact is too small, but the efficiency of our people, one minute to write a bubble, select, insert the sorting method, and instead of a merge sort?
From: Http://blog.cdswyda.com/post/javascript/2017-03-22-js-sort-not-only-bubblesort
JavaScript sort, not just bubbling