Fast-sorting JavaScript implementations

Source: Internet
Author: User

Thought

The idea of dividing the original array into smaller arrays (but not separating them as a merge sort).

    1. Main element selection: Selects an item from an array as a principal, usually the first item of an array, or arr[i]; or the middle term of an element, Arr[math.floor ((I+J)/2)];
    2. Divide operations: Create two pointers, one on the left pointing to the first item on the array, and the last item to the right of the array. Move the left pointer to the right until you find an item that is not less than the primary element, and move the right pointer to the left until you find an item that is not larger than the primary. Exchange them. Then repeat the process until the left pointer exceeds the right pointer. This makes the values that are smaller than the primary are ranked before the primary, and the values larger than the primary are ranked after the main element. Note: In this process, the location of the principal element may also be changed, and the principal itself will not be in the correct position after a partition operation, and its correct position should be on the partition point (i.e. Sliceindex) that is eventually obtained after this partition operation. The right half-way operation will immediately change the main element to the correct position .
    3. Duplicate sub-array operations: a sub-array of items that are smaller than the main element (that is, the part to the left of the main element), and another sub-array that is larger than the main element (that is, the part to the right of the main element). The main element selection and partitioning operation continues for these two decimal groups. Until the array is fully sorted.
Code

Code Snippet 1:

function QuickSort(arr){  return Quick(arr, 0, arr.length-1);}function Quick(arr,Left,Right{  if(arr.length>1){    ConstSliceindex= Partition(arr,Left,Right;    if(left<Sliceindex-1){      Quick(arr,Left,Sliceindex-1);    }    if(Sliceindex<Right{ //*1      Quick(arr,Sliceindex,Right;//*2    }  }  }function Partition(arr,Left,Right{   LetI=Left;   LetJ=Right;  //const pivot = Arr[math.floor ((i+j)/2)];  ConstPivot=Arr[i];   while(I<J{      while(Arr[i]<Pivot{ //    //q:*3,*4: Why is it necessary to use <, instead of <= or >=?    //a:*3 and * * * must be <, neither can include the case of =-the actual verification results are the same    //Because if it contains =, then the pivot and the value equal to pivot will never be processedI++;    }     while(Arr[j]>Pivot{ //J--;    }    if(I<J{ //    //Think: Why must this place be <= and not use <?    //a: It is actually for the following paragraph of the i++,j--。 If two paragraphs are written separately, then this should be i<j, and the following paragraph should be i<=j      ConstTemp=Arr[i];Arr[i]=ARR[J];ARR[J]=Temp;    }    if(I<=J{//*6      //Here conditions must be i<=j.       //If the condition is only i<j, then it will never enter this condition when i==j, and the return value is I and J. So this whole piece of partion code down, I may never change, and return unchanged I, that is, const SLICEINDEX = partition (arr, left, right), the Sliceindex is equal to the parameter left , then in the next quick (arr, sliceindex, right) is equal to the previous quick (arr,left,right), infinite loop ...       in short, the purpose of this condition is to make I must change onceI++;J--;    }  }  returnI;}
Thinking 1. In fact, after each partition operation, the main element is not in the correct position ... So why is it that each partitioning operation puts a value that is smaller than the main element in front of the principal, and that the value that is larger than the main element is in the main element?

The main element itself is not in the correct position after a partition operation, its correct position should be at the end of the division operation after the division (that is, sliceindex), the right side of the next operation will immediately put the main element to the correct position. So in fact, in this round division operation Finally, you can exchange the main element to the correct position, then the next operation, and then the next operation can be no matter sliceindex that position.

This kind of writing is actually put less than the main element to the left, greater than the main element to the right, equal to the main element may be left in the right, rather than put the main element in the correct position .

The code is better understood as follows.

Code Snippet 2:

function QuickSort(arr){  return Quick(arr, 0, arr.length-1);}function Quick(arr,Left,Right{  if(arr.length ===1){    return;  }  ConstSliceindex= Partition(arr,Left,Right;  if(left<Sliceindex-1){    Quick(arr,Left,Sliceindex-1);  }  //Next division no longer consider the main element.  if(Sliceindex+ 1 <Right{ //*1    Quick(arr,Sliceindex+ 1,Right;//*2  }}function Partition(arr,Left,Right{   LetI=Left;   LetJ=Right;  ConstPivot=Arr[i];   while(I<J{     while(Arr[i]<Pivot{ //*3I++;    }     while(Arr[j]>Pivot{J--;    }    if(I<J{      ConstTemp=Arr[i];Arr[i]=ARR[J];ARR[J]=Temp;    }    if(I<=J{I++;J--;    }  }  //Swap the main element to the partition position  ConstTemppivotindex= arr.indexOf(pivot); //*7Arr[temppivotindex]=Arr[i];//*8Arr[i]=Pivot;//*9  returnI;//actually also equals J's}

Compared to the original code, this writing: The 1,2 has been modified, the next partition operation no longer consider the slickindex (that is, the main element has been lined up); then add 7,8,*9, that is, in this division operation Finally, Exchange the main element to the correct position, this writing, and ES6 notation (code snippet 3) The idea is consistent

Work process

Pending drawing

Performance analysis
    • Time complexity: Best, Average O (nlogn), Worst O (n^2)
    • Space complexity: O (LOGN), unstable
    • Features: more performance but poor
Extension: implementation of ES6

Code Snippet 3:

  function QUICKSORTES6(arr){    if(!arr.length){       //The critical condition to be processed must be an empty case for arr, as there may be no left after filter filtering      the//arr length of 1 can not be handled separately because the length is 1 then [pivot, ... rest]=arr rest is []      return[];    }    Const[Pivot,...Rest]=Arr;    return[      ...QUICKSORTES6(Rest.Filter(item=Item<Pivot)),Pivot,...QUICKSORTES6(Rest.Filter(item=Item>=Pivot))//must have = otherwise the values that are equal to pivot will be filtered out]}

This is a better understanding than the previous row method.

Resources

-"Learning JavaScript data structure and algorithms" 10.1.5
-"Data structure (c language version)" 9.3.2

Fast-sorting JavaScript implementations

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.