Ruby实现的快排 [Coursera Algorithms: Design and Analysis, Part 1]
def qsort1 array if array.size <= 1 #长度小于等于1,比较数为0,直接返回 return 0 end arr = array.dup #取第一个为pivot pivot = arr.shift #把当前arr拆分成比pivot小和比pivot大两部分 smaller,bigger = arr.partition {|x| x<pivot} return qsort1(smaller) + qsort1(bigger) + array.size - 1 end
结果全错, 错误原因是arr.partiton的实现与课上所讲的partition的实现不同,于是又去看了看slides:
手动实现了一下这个算法,因为实现方法不太一样,细节上有些小差异,导致还调整了几次才过(都是因为不认真看slide……),最终实现代码如下:
def pivot1 array #总是取第一个为pivot array.shift end def pivot2 array #总是取最后一个为pivot,方法是先交换最后一个和第一个数,然后取第一个 array[0],array[array.size-1] = array[array.size-1],array[0] array.shift end def pivot3 array #取中间数为pivot,不管中间数是哪一个,都把它和第一个数交换 mp = (array.size + 1)/2 - 1 h = array[0] m = array[mp] t = array[array.size-1] if (m<h||t<=h)&&(h<=m||h<=t) elsif (h<m||t<m)&&(m<h||m<t) array[0],array[mp] = array[mp],array[0] else array[0],array[array.size-1] = array[array.size-1],array[0] end array.shift end def qsort array,type # end condition if array.size <= 1return 0 end bigger = array.dup if type==1 pivot = pivot1 bigger elsif type==2 pivot = pivot2 bigger else pivot = pivot3 bigger end i = j = 0 while j < bigger.size if bigger[j] < pivot bigger[i],bigger[j] = bigger[j],bigger[i] i += 1 end j += 1 end smaller = bigger.shift(i) #因为最后要把smaller的最后一个数同位于第一个位置的pivot交换,所以做一次-1的rotate smaller.rotate! -1 return qsort(smaller, type) + qsort(bigger, type) + array.size - 1 end