July收集荷蘭國旗問題之三路partition

2021-06-22 20:17:16 字數 1812 閱讀 3812

這道題目和分成兩塊的partition的擴充套件,例如有一堆0 1 2 數字組成的陣列,要分成 00 00  11 1 1  222 2這種順序的。

利用lumoto版的partition可以很好的解決,比hoare好多了,而且直接利用loop invariant,變成i j k三個指標,[low,i]=0 [i+1,j]=1, [j+1,k-1]=2, 裡面如果新來2的話,直接k++,

如果是1的話,需要和a[j+1] swap, 同時j++, 如果0的話,需要先和a[i+1] swap i++, 然後和 a[j+1] swap j++, 因此演算法如下:

void nertherlandflags(int *a, int n)

else if(a[k]==0)

}}

**比較好寫,感覺這都是一類題,

1.快排的partition,注意留乙個pivot,算導是留最後乙個,所以loop到high-1就停了,裡面和pivot比,最後加一次swap把pivot放中間

loop invariant:  [low,i] pivot, =放那邊都行,exit loop時 j=high, 最後把swap跳進來

2.奇偶排序,整個區間劃分為左奇右偶,和%2=0 =1比,loop 到high,

loop invariant:  [low,i] 奇, [i+1, j-1]偶, exit時 j=high+1, 包含整個區間了

3.荷蘭國企問題,整個區間劃分為0 1 2 (紅 黃 藍三塊), loop 到high,

loop invariant:  [low,i] 0, [i+1, j] 1, [j+1, k-1]  exit時 j=high+1, 包含整個區間了

抱歉大家,這道荷蘭國旗**有bug,我才知道的,後經過分析主要是前面只有2 或者0 2時,如果來了0,後面swap(a[j],a[k]) 會多交換一次使得交換回去,所以如果只有0的情況,其實不需要交換,而swap(a[j],a[k]) swap(a[j],a[k])都是子交換,因此1次兩次不影響,於是統一到一起就是沒有1區間的時候,也即[i+1,j]區間空,根據性質最多相差1,因此是i==j的時候出錯,所以此時少一次swap, 但是i++ j++需要的 保持ij同步 

事實證明未經過oj測試的**很難保證正確性。leetcode setcolor題 就是上面的掛了,於是經過多種組合條件分析發現bug,單獨處理1 interval空的情況

void sortcolors(int a, int n) 

else

}else if(a[k]==1)

}}

附上july版本,前面 0 1區間 最後面2區間  1 2 之間沒處理的

void sortcolors(int a, int n) 

}

這種不用考慮特殊情況,比如 只有2 和只有0 2的區間的情況,其實也是單向掃瞄過來的,只是調整了未處理部分和 0 1 2 區間的順序而已,因為指標從current+1, 到end處理了,乙個

指標掃瞄的,還是單向掃瞄好,其實也不是hoart版啦,所以自己不用管hoard版,堅持lumoto版就可以了,sumous_t大神似乎也是的。

似乎還有一種改進第乙個版本的思路,就是不swap,而是覆蓋,像優化partition一樣的

附上july部落格 

sumous_t 大神**:

再附上sumous_t大神幫我修改後ac的**,膜拜下大神,還是女博士哦:)

void sortcolors(int a, int n)   

else if(a[k]==0)

}

快速排序之三路快速排序

之前介紹了快速排序和優化版的快速排序 下面再來介紹一種 三路快速排序 實現 三路快速排序 template typename t static void quicksort3ways t arr,int n template typename t static void quicksort3ways...

快速排序之三路快排

當大量出現重複值時,我們使用三路快排,如下 arr 表示排序陣列 l 表示陣列左邊界 r 表示陣列右邊界 public static void quicksortinternal3 int arr,int l,int r else if arr i v else 交換l與lt元素,可以確定基準值的位...

演算法排序之三路快速排序演算法

思想 將陣列分為三個部分v e v i ee v 將其和gt 1位置的元素交換,為 v塊第乙個元素 操作完成 i gt 將l和lt交換位置 include include include using namespace std 三路快排 void quicksort int arr,int l,in...