This is a creation in Article, where the information may have evolved or changed.
Package main//gets top-k elements in @description element stream, elements need to implement Comple interface//@author chenbintao//@data 2017-03-3114:19 First Draft// 2017-03-3117:44 Compile validation via import ("FMT" "Log")//element interface design, participate in the ordering element, need to implement the method within the interface type ELEM interface {//Compare the current element with the O element size, true: Greater than Ocomple (interface{}) Bool}/**top-k-heap used to filter out pre-K extremum elements from data **/type topkheap struct {heap []elem//physically implemented with an array (interface is pointer) size Int64//Heap Size index Int64//heap element number (point to next available) Bigmode bool//is the large top mode}func New (size int64, bigmode bool) *topkheap {if size & lt;= 0 {return nil}//constructs a large/small top heap of a specified size this: = new (topkheap) this.heap = make ([]elem, size) this.size = Sizethis.index = 0this.b Igmode = Bigmodereturn this}//Get heap capacity func (this *topkheap) GetSize () Int64 {return this.size}//gets the number of elements func (this *topkheap) Ge TCount () Int64 {return this.index}//into heap func (this *topkheap) Push (i interface{}) {if nil = = i {return}var o ELEM = i. (ELEM) If This.index < this.size {//a. Not full, add at the end, build heap after full this.heap[this.index] = othis.index++if This.index >= this.size { This.build ()}} else {//b. Full, replace and adjust if ((!o.comple (this.heap[0])) && this.bigmode)/* into a heap element smaller than the heap top of a large top heap */| | ((O.comple (this.heap[0)) &&!this.bigmode)/* * into heap element larger than small top heap top */{//Meet replacement condition this.heap[0] = O//replace heap top this.adjust (0)// Heap Top start adjustment heap}}return}//out heap func (this *topkheap) Pop () (o interface{}) {if This.index <= 0 | | This.size <= 0 {return nil}//backtrack to tail element this.index--if This.index <= 0 {this.index = 0}o = This.heap[0] Get heap top this.heap[0] = This.heap[this.index]//Swap heap top this.heap[this.index] = nil//delete tail element this.adjust (0) Adjust heap return o}//build heap func (this *topkheap) build () {//First non-leaf node start adjustment i: = This.getfather (this.index-1) for I >= 0 { This.adjust (i) i--}return}//print heap func (this *topkheap) string () string {return FMT. Sprint (this.heap)}//adjustment Heap (Recursive implementation) func (this *topkheap) adjust (i int64) Int64 {if This.checkindex (i) < 0 {return-1}//Adjust left sub-heap (Exchange and recursion adjustment) var child int64child = This.getleft (i) if the child > 0 && (((This.heap[i]). Comple (This.heap[child]) &&!this.bigmode/* Root greater than small top heap child */) | | (! (This.heap[i]). Comple (ThiS.heap[child]) && this.bigmode/* Root smaller than the big Top heap Child */)) {tmp: = this.heap[i]this.heap[i] = this.heap[child]this.heap[ Child] = Tmpthis.adjust (children)}//adjusts the right sub-heap (interchange with recursive adjustment) for the this.getright (i) if the > 0 && (((This.heap[i]). Comple (This.heap[child]) &&!this.bigmode/* Root greater than small top heap child */) | | (! (This.heap[i]). Comple (This.heap[child]) && this.bigmode/* Root smaller than the big Top heap Child */)) {tmp: = This.heap[i]this.heap[i] = This.heap[child] This.heap[child] = tmpthis.adjust (child)}return i}//determine if the heap needs to adjust Func (this *topkheap) needadjust (root, child int64) bool { if ((This.heap[root]). Comple (This.heap[child]) &&!this.bigmode/* Root greater than small top heap child */) | | (! (This.heap[root]). Comple (This.heap[child]) && this.bigmode/* Root less than Big top heap child */) {return True}return false}//get parent node (heap top is 0, return 1 when capacity is exceeded) func (This *topkheap) getfather (i Int64) int64 {//(I-1)/2 down-rounded var j int64j = (i-1)/2if this.checkindex (i) >= 0 && This.checkindex (j) >= 0 {return j}return-1}//get left child node (heap top is 0, returns-1) func (this *topkheap) getLeft (i intInt64 {//(i+1) *2-1var J int64j = (i+1) *2-1if this.checkindex (i) >= 0 &&this.checkindex (j) >= 0 {return j}return-1}//Get right child node (heap top is 0, return 1) func (this *topkheap) getRight (i Int64) int64 {//(i+1) *2var J int64j = (i + 1) * 2if This.checkindex (i) >= 0 &&this.checkindex (j) >= 0 {return j}return-1}//check the legality of the node (heap top is 0, return 1 when capacity is exceeded) func ( This *topkheap) CheckIndex (i Int64) Int64 {if I < 0 | | I >= this.size | | I >= This.index | | Nil = = This.heap[i] {return-1}return i}//=============================================== test program//Sample element type used for sorting type Elem struct {i int}func (this Elem) comple (i interface{}) bool {//elem is an interface, the method uses the Elem type var o Elem = i. (Elem) if this.i > o.i {return true} else {return False}}func (this *elem) sring () string {return FMT. Sprint (THIS.I)}func main () {heap: = New (6, false) for I: = 0; i <; i++ {e: = elem{i:i}heap. Push (e) log. Println (heap. String ())}for heap. GetCount () > 0 {e: = heap. Pop (). (Elem) log. Println (E.sring ())}}
Operation can be found in http://studygolang.com/topics/2602
472 Reads