By
    
      被删
    
  
    
    更新日期:
    
  
	
		
		
		
		
		快速排序的javascript实现。
简单快速排序
排序问题
- 输入:n个数的一个序列<a1, a2, ..., an>
- 输出:输入序列的一个排列<a1', a2', ..., an'>,满足a1' <= a2' <= ... <= an'
思路
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
步骤为:
- 从数列中挑出一个元素,称为”基准”(pivot),
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
js基本思路实现
这里我们先使用两个数组分别保存“基准”左边、右边的子集。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 | function fakeQuickSort(iArr) {     var n = iArr.length;          if (n <=1) { return iArr; }          else{         var p = parseInt(n-1);         var pivot = iArr[p];         var leftArr = [], rightArr = [], arrVal;         for(var i = 0; i < n-1; i++){             arrVal = iArr[i];             if(arrVal <= pivot){                                  leftArr.push(arrVal);             }else{                                  rightArr.push(arrVal);             }         }                  return fakeQuickSort(leftArr).concat([pivot].concat(fakeQuickSort(rightArr)));     } }
 | 
验证
| 1 2 3 4 5 6 7 8
 | fakeQuickSort([5, 2, 4, 6, 1, 3]);  fakeQuickSort([2, 1, 3, 1, 5]); fakeQuickSort([5, 2, 12, 2, 134, 1, 3, 34, 4, 6, 1, 3, 4]); 
 | 
快速排序
原址排序
在排序算法中,如果输入数组中仅有常数个元素需要在排序过程中存储在数组之外,则称排序算法是原址的。
插入排序、堆排序、快速排序等都是原址排序。
归并排序不是原址的。
上面简单版本的缺点是,它需要Ω(n)的额外存储空间,也就跟归并排序一样不好。额外需要的存储器空间配置,在实际上的实现,也会极度影响速度和缓存的性能。有一个比较复杂使用原地(in-place)分区算法的版本,且在好的基准选择上,平均可以达到O(log n)空间的使用复杂度。
快速排序思路
上面我们移动位置是通过建立新的子集数组伪装的,这里我们则需要实现真正的位置交换。
- 获取基准值
- 将低于基准值的排列在左侧,剩下的排列在右侧
- 分别对左侧和右侧进行递归排序
这是原址排序算法,它分区了标示为”左边(left)”和”右边(right)”的序列部分,借由移动小于a[pivotIndex]的所有元素到子序列的开头,留下所有大于或等于的元素接在他们后面。
在这个过程它也为基准元素找寻最后摆放的位置,也就是它回传的值。它暂时地把基准元素移到子序列的结尾,而不会被前述方式影响到。
由于算法只使用交换,因此最后的数列与原先的数列拥有一样的元素。要注意的是,一个元素在到达它的最后位置前,可能会被交换很多次。
参考快速排序-wiki
js基本思路实现
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
 | function swap(arr, a, b) {     if(a == b){return;}     var c = arr[a];     arr[a] = arr[b];     arr[b] = c; } function quickSort(iArr, start, end) {     var n = end - start;          if (n <= 1) { return; }          else {         var p = end - 1;          var pivot = iArr[p];          var leftIndex = start;          for (var i = 0; i < n - 1; i++) {             arrVal = iArr[start + i];                          if (arrVal <= pivot) {                 swap(iArr, leftIndex++, start + i)             }                      }                  swap(iArr, leftIndex, p);                  quickSort(iArr, start, leftIndex);                  quickSort(iArr, leftIndex + 1, end);         return iArr;     } }
 | 
验证
| 1 2 3 4 5 6 7 8
 | quickSort([5, 2, 4, 6, 1, 3], 0, 6);  quickSort([2, 1, 3, 1, 5], 0, 5); quickSort([5, 2, 12, 2, 134, 1, 3, 34, 4, 6, 1, 3, 4], 0, 13); 
 | 
			查看Github有更多内容噢:https://github.com/godbasin
			
			更欢迎来被删的前端游乐场边撸猫边学前端噢