最差情况为线性时间的选择
2017-02-02 13:14
197 查看
这个算法写了我好久,在这里记一下。
算法的原理是利用中位数来作为划分元素选择第M小的元素,中位数需要递归自身来求得。算法的最优,平均,最差时间复杂度都为O(N)。相对于随机算法改善了最差时间复杂度。
和快排用了同样的partition,但是这个算法所使用的pivot是确定的,即中位数。
代码版本为golang 1.8.0。
路径goWorkSpace/algorithms/worseLinearSelect.go
main包路径goWorkSpace/golangTest/test.go,测试代码如下:
后来发现代码还有小缺陷,partition方法会影响到切片中不需要重新划分的部分,但不影响算法的复杂度,只是多了一点无意义的操作。
代码对于所有测试用例都能通过。
算法的原理是利用中位数来作为划分元素选择第M小的元素,中位数需要递归自身来求得。算法的最优,平均,最差时间复杂度都为O(N)。相对于随机算法改善了最差时间复杂度。
和快排用了同样的partition,但是这个算法所使用的pivot是确定的,即中位数。
代码版本为golang 1.8.0。
路径goWorkSpace/algorithms/worseLinearSelect.go
package algorithms import ( "fmt" ) func WorseLinearSelect(array []int, startIndex, stopIndex, rank int)(selectedValue int) { if startIndex + 5 > stopIndex { insertionSort(array) return array[rank] } midValueArrays := getMidValueArray(array, startIndex, stopIndex) midValue := WorseLinearSelect(midValueArrays, 0, len(midValueArrays), (len(midValueArrays) - 1)/2) devideIndex := partitionWithPiovt(array, midValue) if devideIndex == rank { return array[devideIndex] } else if devideIndex > rank { return WorseLinearSelect(array, startIndex, devideIndex, rank) } else { return WorseLinearSelect(array, devideIndex + 1, stopIndex, rank) } } //sort array by groups and return the mid value array func getMidValueArray(array []int, startIndex, stopIndex int)(midValues []int) { array = array[startIndex : stopIndex] arrayGroups := len(array) / 5 if len(array) % 5 == 0 { midValues = make([]int, arrayGroups) } else { midValues = make([]int, arrayGroups + 1) } //j := 0 for i, j := 0, 0; i < len(array); i += 5 { if i + 5 <= len(array) { b := array[i : i + 5] insertionSort(b) midValues[j] = array[i + 2] } else { insertionSort(array[i : len(array)]) midValues[j] = array[(i + len(array)) / 2] } //(i + 5 <= len(array)) ? (insertionSort(array[i : i + 5])) : (insertionSort(array[i : len(array)])) j ++ } return midValues } func partitionWithPiovt(array []int, pivotValue int)(firstIndex int) { firstIndex = -1 for secondIndex := 0; secondIndex != len(array); secondIndex ++ { if array[secondIndex] < pivotValue { firstIndex ++ swap(&array[firstIndex], &array[secondIndex]) } else if array[secondIndex] == pivotValue { firstIndex ++ swap(&array[firstIndex], &array[secondIndex]) swap(&array[0], &array[firstIndex]) } } swap(&array[0], &array[firstIndex]) return firstIndex } func insertionSort(array []int) { defer func() { if r := recover(); r != nil { fmt.Println(r) } }() for i := 1; i != len(array); i++ { selectValue := array[i] for j := i - 1; j >= 0; j -- { if array[j] > selectValue { swap(&array[j], &array[j + 1]) } else { break } } } } func swap(a *int, b *int) { temp := *b *b = *a *a = temp } func Partition(array []int, pivotValue int) int { return partitionWithPiovt(array, pivotValue) }
main包路径goWorkSpace/golangTest/test.go,测试代码如下:
package main import ( "fmt" "algorithms" "sort" "time" "math/rand" ) func main() { //to new a random slice rand.Seed(time.Now().UnixNano()) arrayLen := rand.Intn(400) + 200 array := make([]int, arrayLen) for index, _ := range array { array[index] = rand.Intn(5 * arrayLen) fmt.Print(",", array[index]) } rank := rand.Intn(arrayLen) fmt.Println("array befor select\n", array) fmt.Println("rank", rank) fmt.Println("array length", arrayLen) //run the select function selectedValue := algorithms.WorseLinearSelect(array[:], 0, len(array), rank) sort.Ints(array[:]) fmt.Println("\nselectedValue by sort", array[rank]) fmt.Println("\nselectedValue", selectedValue) }
后来发现代码还有小缺陷,partition方法会影响到切片中不需要重新划分的部分,但不影响算法的复杂度,只是多了一点无意义的操作。
代码对于所有测试用例都能通过。
相关文章推荐
- <算法导论>第九章3 最坏情况线性时间的选择
- 一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS.
- 算法导论-第九章-中位数和顺序统计量:最坏情况为线性时间的选择算法C++实现
- 最坏情况为线性时间的选择算法---算法导论学习笔记(2)
- 最坏情况为线性时间的选择算法
- 分治策略(最差情况下查找为线性时间算法)
- CLRS 9.3最坏情况为线性时间的选择算法
- 《算法导论》读书笔记之第9章 中位数和顺序统计学 最坏情况是线性时间的选择算法
- 算法之分治——最坏情况线性时间的选择
- 最坏情况下的线性时间的选择算法
- 第九章中位数和顺序统计学 之 “寻找第i小元素之最坏情况线性时间的选择 最坏运行时间就为O(n)算法”
- 最坏情况为线性时间的选择算法
- 算法导论第9章最坏情况为线性时间的选择算法
- (p123)最坏情况为线性时间的选择算法
- 最坏情况为线性时间的选择算法
- 最坏情况线性时间选择O(n)
- 《算法导论》笔记 第9章 9.3最坏情况线性时间选择
- 一种最坏情况线性运行时间的选择算法 - The missing worst-case linear-time Select algorithm in CLRS.
- 《算法导论》笔记 第9章 9.3最坏情况线性时间选择
- 算法导论 最坏情况为线性时间的选择算法 9.3-8 9.3-9