快速排序的幾種寫法
阿新 • • 發佈:2020-07-28
快速排序是非常重要排序演算法
有許多寫法,不同寫法在數量級較小的情況下有不同的效能
這裡的標兵都是取頭 如果需要隨機化應該加入 如下幾行
int randomindex=l+1+random.nextInt(r-l);
int temp = nums[l];
nums[l]=nums[randomindex];
nums[randomindex]=temp;
No.1 填坑
取走標兵 ,從陣列尾開始填充陣列頭的空缺
有相對複雜的比較
public static void partition1(int[] nums,int l,int r){ if(l<r){ int pivot = nums[l]; int i=l,j=r; while(i<j){ while (i<j && nums[j]>=pivot){ j--; } nums[i]=nums[j]; while (i<j && nums[i]<=pivot){ i++; } nums[j]=nums[i]; } nums[i]=pivot; partition1(nums,l,i-1); partition1(nums,i+1,r); } return; }
No.2 雙指標交換
和填坑不同的是 直接交換
有浪費時間的函式交換
public static void partition2(int[] nums,int l,int r){ if(l<r){ int pivot=nums[l]; int i=l,j=r; while(i<j){ while (i<j && nums[j]>=pivot){ j--; } while (i<j && nums[i]<=pivot){ i++; } swap(nums,i,j); } swap(nums,i,l); partition2(nums,l,i-1); partition2(nums,i+1,r); } } public static void swap(int[] nums,int i,int j){ int temp=nums[i]; nums[i]=nums[j]; nums[j]=temp; }
No.3 單指標交換
單指標交換是程式碼量最少的
這裡的單指標意思是定了一個,而動另一個
較少的比較和交換
public static void swap(int[] nums,int i,int j){ int temp=nums[i]; nums[i]=nums[j]; nums[j]=temp; } public static void partition3(int[] nums,int l,int r){ if(l<r){ int pivot = nums[l]; int index=l; for(int i=l+1;i<=r;i++){ if(nums[i]<pivot) { ++index; swap(nums, i, index); } } swap(nums,l,index); partition3(nums,l,index-1); partition3(nums,index+1,r); } }
No.4 優化填坑
優化填坑相比於填坑 ,減少了比較次數 指標移動更加快了
沒有交換 ,減少了比較
public static void partition4(int[] nums,int l,int r){
if(l<r){
int i=l,j=r,pivort;
pivort=nums[l];
while(i<j){
while (i<j && nums[j]>=pivort){
j--;
}
if(i<j){
nums[i++]=nums[j];
}
while (i<j && nums[i]<=pivort){
i++;
}
if(i<j){
nums[j--]=nums[i];
}
}
nums[i]=pivort;
partition4(nums,i+1,r);
partition4(nums,l,i-1);
}
}
效率對比
用5次相同的隨機陣列測試平均值如下
數量級 | 數字範圍 | 優化填坑 | 填坑 | 雙指標交換 | 單指標交換 |
---|---|---|---|---|---|
100 | 0-100 | 22300.0 | 25960.0 | 28020.0 | 32480.0 |
100數量級排行 | 1 | 2 | 3 | 4 | |
1000 | 0-1000 | 158220.0 | 149360.0 | 188280.0 | 155400.0 |
1000數量級排行 | 3 | 1 | 4 | 2 | |
10000 | 0-10000 | 1112180.0 | 1607860.0 | 1629740.0 | 1133740.0 |
10000數量級排行 | 1 | 3 | 4 | 2 | |
100000之後差不多水平 On 限制 | |||||
綜合排行 | 1 | 2 | 4 | 3 |
從資料中可以得到 在數量較少的情況下
雙指標交換最耗時間 原因浪費在交換函式的進棧出棧並且邏輯有比較複雜的比較
優化填坑和單指標交換和填坑 效果差不多
最後
理解和記憶簡單取決於自己的選擇