QuickSort
<script type="text/javascript">
- 快速排序
//快速排序
//思想:每次都把待排序的序列分成两组,左边的比关键字大
//右边的比关键字小,关键字的位置就是有序的时候它的位置
//时间复杂度:时间复杂度与选取的关键字,如果关键字是平衡二叉树的
//跟节点,递归次数为平衡二叉树的高度O(nlogn); 平均O(nlogn)
//若是一颗斜的排序二叉树,递归n-1次;O(n2)
//空间复杂度:最好/平均O(log n) 最坏O(n)
//稳定性:不稳定
function QuickSort(obj)
{
//分割待排序的序列
QSort(obj.data,1,obj.length);
//QSort1(obj.data,1,obj.length);
}
//交换两个数的位置
function swap(arr,i,j)
{
var temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//对序列做快速排序
function QSort(arr,low,high)
{
var k;
if(low<high)
{
k=Partition(arr,low,high);
QSort(arr,low,k-1);
QSort(arr,k+1,high);
}
}
//用关键字分割待排序的序列
function Partition(arr,low,high)
{
//可以用三数取中法选出关键字
SelectCenter(arr,low,high);
var key=arr[low];
while(low<high)
{
/*while(low<high && key<=arr[high])
high--;
swap(arr,low,high);
while(low<high && key>=arr[low])
low++;
swap(arr,low,high);*/
//可以减少交换次数
while(low<high && key<=arr[high])
high--;
arr[low]=arr[high];
while(low<high && key>=arr[low])
low++;
arr[high]=arr[low];
}
arr[low]=key;
return low;
}
//直接插入排序
function InsertSort(obj)
{
var temp;
for(var i=1;i<obj.length;i++)
{
if(obj.data[i]>obj.data[i+1])
{
temp=obj.data[i+1];
while(obj.data[i]>temp&&i>0)
{
obj.data[i+1]=obj.data[i];
i--;
}
obj.data[i+1]=temp;
}
}
}
//优化:由于快速排序用到了递归,当待排序的数组很小时,他的
//效率不如直接插入排序
function QSort1(arr,low,high)
{
var k;
//当子序列小于7时用直接插入排序
if(high-low>7)
{
k=Partition(arr,low,high);
QSort(arr,low,k-1);
QSort(arr,k+1,high);
}
else
{
InsertSort(obj);
}
}
//优化:快速排序的时间复杂度与关键字的选择有关
//所以总用第一个选取并不总是最好的
//三数取中法
function SelectCenter(arr,low,high)
{
var i=Math.floor(low+(high-low)/2);
if(arr[low]>arr[i])
swap(arr,low,i);
if(arr[i]>arr[high])
swap(arr,i,high);
if(arr[low]<arr[i])
swap(arr,low,i);
}
//待排序的序列,第一个数不参与
var obj={
data:[0,-11,2,-36,2,200,34,11],
length:7
}
QuickSort(obj);
console.log(obj.data);
</script>