快速排序
快速排序(quick sort)的基本思想:通过一趟排序,将序列中的数据分割为两部分,其中一部分的所有数值都比另一个部分的小;然后按照此种方法,对两部分数据分别进行快速排序,直到参与排序的两部分都有序为止。(有递归)。
对于一个包含n 条记录的序列arr[],使用快速排序使序列调整为升序序列的基本操作如下:
- 设置变量i和j,分别记录序列中第一条 记录和最后一条(n-1)记录对应的下标,使用变量key记录序列中第一条记录的键值(这里的键值即为第一条记录,即key=arr[0])
- 若i<j 成立
- 比较arr[j]和key,若key>arr[j],使arr[i]=arr[j],否则从后往前移动j,即j - -. (比key小的arr[j]放在key的左边)
- 比较arr[i]和key,若key<arr[i],使arr[j]=arr[i],否则从前向后移动i,即i++.(比key大的arr[i]放在key的右边)
- 重复步骤2,直到i<j不成立为止,此时使arr[i]=key(最后确定 key)的位置
完成的快速排序就是对上述散步的递归调用,当left>=right成立时,递归结束。排序完成。
举例说明
数组为arr=[5,0,9,8,1,4,6,3,7,5] 使用快速排序将数组进行升序排序。
第一层排序说明
- 初始状态下,使用key记录arr[0]的值作为本层比较重的参考值,使用i和j记录第一个元素的下标和最后一个与最后一个元素的下标
- 本层的key值等于arr[0],也就是5,arr[0]对应的值可视为空值
- 首先使arr[j]与key比较,因为arr[j]=5=key,所以使j减去1,;i<j,再次比较arr[j]和key,同上,j再减去1;此时j7,i<j,arr[j]=3,arr[j]<arr[0],将arr[7]中存储的数据放到arr[i].此时arr[j]对应的位置可视为空值。
- 接着从前往后遍历序列,直到找到一个大于key的值为止。在i<j的前提下,arr[0]=3和arr[1]=0都小于key;i继续加1,此时i=2,arr[2]=9>key,所以使arr[j]=arr[i]=9.此时arr[i]的值可视为空值。
- 接着从后往前查找,使j减去1,往前查找小于key的数据,在i<j的情况下,找到j=5时,arr[j]=4<key,令arr[i]=arr[j], 此时arr[j]的值可视为空值
- 接着从前往后查找:使i加1,在i<j的情况下,找到i=3 时,arr[i]=8>key,令arr[j]=arr[i],此时arr[i]的值可视为空值。
- 接着从后往前查找:使j减去1,在i<j的情况下,找到j=4时,arr[j]=1<key, 令arr[i]=arr[j],此时arr[j]的值可视为空值
- 接着从前往后查找:使i加1,此时i=j 结束本层排序,原始序列分成两个字序列
一层排序 3 0 4 1
5(key)
8 6 9 7 5
js代码实现
//排序数组
arr=[5,0,9,8,1,4,6,3,7,5];
function QuickSort(arr,left,right){
if(left>=right){
return;
}
var i=left;
var j=right;
var key=arr[i];//使用key来保存作为键值的数据,将arr[i]空出来。
//本轮排序开始,当i=j时本轮排序结束,将键值赋给arr[i]
while(i<j){
//从后往前寻找比key小的数组元素
while(i<j && key<=arr[j]){
j--; //移动指针
}
//否则 就交换
//arr[i]=arr[j];
var temp;
//交换
temp=arr[j];
arr[j]=arr[i];//此时arr[i]的值看成是空的
arr[i]=temp;
//从前往后寻找比key大的数组元素
while(i<j && key>=arr[i]){
i++;//移动指针
}
//否则 交换
//arr[j]=arr[i];
temp=arr[i];
arr[i]=arr[j];//此时arr[j]应该看成空的
arr[j]=temp;
}
//第一层排序结束
arr[i]=key;
//递归调用排序函数对键值两边的子序列进行操作
QuickSort(arr,left,i-1);
QuickSort(arr,i+1,right);
}
// 0是数组的第一个下标,9是数组的最后一个下标
QuickSort(arr,0,9);
console.log(arr);//Array(10) [ 0, 1, 3, 4, 5, 5, 6, 7, 8, 9 ]