Go version of the sort binary tree, ample API and explanatory notes
Last Update:2018-06-22
Source: Internet
Author: User
The introduction of sort binary tree no more, the two-fork tree in this paper has all the functions of the following open interface. "' Gopackage Btreetype btreei interface {//if A BT contains Datacontain (Data interface{}) (bool, error)//get the node whic H has Max Datafindmax () (*binarynode, error)//get the node which have min datafindmin () (*binarynode, error)//insert a data Insert (x interface{}) (*binarynode, error)//delete a node which ' s data is x,if several nodes ' data be all x,only delete O NE of Themremove (x interface{}) (*binarynode, error)//get a node ' s depth in a btgetdepth (node *binarynode) (int, error)// Get the nearest ancestor of the Nodegetancestor (Node1, Node2 *binarynode) (*binarynode, error)//assume Node1 and Node2 is Contained,get the nearest distance of the Node,however,it didn ' t support compare the nodes which has the same data,new (11 ) and new (one) is uncomparable//if node1 or node2 isn ' t included,nil pointer error occurredgetdistance (NODE1, Node2 *binary Node) (int, error)//get max depth of a BT, returns Maxdepth,leftmaxdepth,rightmaxdepth,errorgetmaxdepth () (int, int, int, error)//get max distance of a btgetmaxdistance () (int, error)//get a BT ' s node number getnodesnum (sum *int)//get A BT ' s node number escaping Arggetnodesnumescapingargs () Int//get the maxheight of a btgetmaxheight () int//get A node ' s heightgetnodeheight (node *binarynode) Int//transfer a BT to a array ASC Sortedtoascarray (RS *[]interface{}, flag *int)//transfer A BT to an array ASC escaping Argstoascarrayescapingargs () []interface{}//transfer a BT to a array desc so Rtedtodescarray (Rs *[]interface{}, flag *int)//transfer a BT to an array desc escaping Argstodescarrayescapingargs () []int Erface{}//assume got a node, find its root by this functionfindroot () *binarynode//cached a BT in global cachecached () *b Treecache//get a BT s cache,if not existed,throws an Errorgetcache (*btreecache, error)//get a BT's cache,if not existed , generate one and return Itmustgetcache () *btreecache//transfer a BT to a linked list order asctoasclinkedlist () (*sorted LinkedList, error)//tranSfer a BT to a LinkedList desctodesclinkedlist () (*sortedlinkedlist, error)//balance a BT ' copy, no modifying to itself Bal Ancecopy () *binarynode//balance a BT to AVL Balance () *binarynode//pacakge a balanced BT to the specific new struct AVL,W Hich is extendable and now contains a root *binary Toavl () *avl} "" "Gopackage Btreeimport (" Reflect "" errors "" FMT ") type Bi Narynode struct {Data interface{}parant *binarynodeleft *binarynoderight *binarynode}type sortedlinkedlist struct { Start *binarynode}type AVL struct {root *binarynode}type redblack struct {root *binarynode}//new a nodefunc new (data Inter face{}) *binarynode {return &binarynode{data, nil, nil, nil}}//new a node with Parentfunc newwithparent (data interface {}, PRT *binarynode) *binarynode {return &binarynode{data, PRT, nil, nil}}//new a node with left Childfunc Newwithleft (Data interface{}, left *binarynode) *binarynode {return &binarynode{data, nil, left, nil}}//balance the copy of BT T O an avlfunc (root *binarynode)Balancecopy () *binarynode{copy: = *rootreturn copy. Balance ()}//balance the BT to an Avl//unfinishedfunc (BT *binarynode) Balance () *binarynode{if Bt==nil {return nil}if (BT.L Eft. Getmaxheight ()-BT. Right.getmaxheight ()) >1 {if Bt. Left.Left.GetMaxHeight () >=bt. Left.Right.GetMaxHeight () {return BT. Rotatewithleftchild ()}else{return BT. Doublerotateleftchild ()}}else{if (BT. Right.getmaxheight ()-BT. Left.getmaxheight ()) >1 {if Bt. Right.Right.GetMaxHeight () >=bt. Right.Left.GetMaxHeight () {return BT. Rotatewithrightchild ()}else{return BT. Doublerotaterightchild ()}}}//bt. Getmaxheightreturn Bt}func (BT *binarynode) Rotatewithleftchild () *binarynode{if BT. Left!=nil && bt. Left.right!=nil{tmp: = Bt. Leftbt.left =tmp. Righttmp.Right.Parant = bttmp. right = Bttmp. Parant = Bt. Parantif BT. Parant!=nil {if Bt. Parant.left = = bt {BT. Parant.left = TMP}ELSE{BT. Parant.right = TMP}}BT. Parant = Tmpreturn Tmp}else{return bt}}func (BT *binarynode) Doublerotateleftchild () *binarynode{if BT. LEFT!=NIL{BT.left = Bt. Left.rotatewithrightchild () return BT. Rotatewithleftchild ()}else{return bt}}func (BT *binarynode) Doublerotaterightchild () *binarynode{if BT. Right!=NIL{BT. right = BT. Right.rotatewithleftchild () return BT. Rotatewithrightchild ()}else{return bt}}func (BT *binarynode) Rotatewithrightchild () *binarynode {if Bt. Right!=nil &&BT. RIGHT.LEFT!=NIL{TMP:=BT. Rightbt.right = tmp. Lefttmp.Left.Parant = bttmp. left = bttmp. Parant = Bt. Parantif BT. Parant!=nil {if Bt. Parant.left = = bt {BT. Parant.left = TMP}ELSE{BT. Parant.right = TMP}}BT. Parant =tmpreturn Tmp}else{return bt}}//if A BT contains Datafunc (BT *binarynode) contain (Data interface{}) (bool, error) {if data = = Nil {return false, Nil}rs, err: = Compare (BT. data, data) if err! = Nil {return false, err}if rs = = 0 {return true, nil}if rs = = 1 {return BT. Left.contain (data)}if rs = =-1 {return BT. Right.contain (data)}return false, nil}//get the node which has Max Datafunc (BT *binarynode) Findmax () (*binarynode, error ) {if Bt. Right! = Nil {REturn BT. Right.findmax ()} else {return BT, nil}}//get the node which has min Datafunc (bt *binarynode) Findmin () (*binarynode, Erro R) {if BT. Left! = Nil {return BT. Left.findmin ()} else {return BT, Nil}}//insert a Datafunc (BT *binarynode) Insert (x interface{}) (*binarynode, error) {RS, ERR: = Compare (BT. Data, x) if err! = Nil {return nil, err}if rs = = 1 {if BT. Left! = Nil {return BT. Left.insert (x)} else {Bt. left = newwithparent (x, BT) return BT. Left, nil}} else {if Bt. Right! = nil {return BT. Right.insert (x)} else {Bt. right = Newwithparent (x, BT) return BT. Right, Nil}}return Nil, nil}//delete a node which's data is x,if several nodes ' data be all x,only Delete one of Themfunc (BT *binarynode) Remove (x interface{}) (*binarynode, error) {if BT = = Nil {return nil, nil}rs, er: = Compare (BT. Data, x) if er! = nil {return nil, er}if rs = =-1 {bt. Right, er = bt. Right.remove (x) if er! = nil {return nil, er}} else if rs = = 1 {bt. Left, er = bt. Left.remove (x) if er! = nil {return nil, er}} else if Bt. LeFT! = Nil && bt. Right! = Nil {tmp, _: = Bt. Right.findmin () bt. Right.remove (TMP. Data) if Bt. Parant.right ==BT && bt. PARANT!=NIL{BT. Parant.right = tmptmp. Parant = Bt. Paranttmp.left = Bt. Leftbt.Left.Parant = Tmpif bt. Right!= tmp{tmp. right = BT. Rightbt.Right.Parant = Tmp}return Tmp,nil}else if Bt. Parant.left ==BT && bt. PARANT!=NIL{BT. Parant.left = tmptmp. Parant = Bt. Paranttmp.left = Bt. Leftbt.Left.Parant = Tmpif bt. Right!= tmp{tmp. right = BT. Rightbt.Right.Parant = Tmp}return TMP,NIL}//BT. Right, _ = Bt. Right.remove (TMP. Data)} else {if Bt. Left! = Nil {bt = BT. Left} else {bt = BT. Right}}return BT, nil}//get a node ' s depth in a btfunc (BT *binarynode) getdepth (node *binarynode) (int, error) {RS, er: = Compare (node. Data, Bt. Data) if er! = nil {return-1, er}if rs = =-1 {tmpleft, _: = Bt. Left.getdepth (node) return Tmpleft + 1, nil} else if rs = = 0 {return 0, nil} else {tmpright, _: = Bt. Right.getdepth (node) return tmpright + 1, nil}}//get the nearest ancestor of the Nodefunc(BT *binarynode) GetAncestor (Node1, Node2 *binarynode) (*binarynode, error) {rs1, er: = Compare (Node1. Data, Bt. Data) if er! = nil {return nil, er}rs2, er: = Compare (node2. Data, Bt. Data) if er! = nil {return nil, er}if rs1 = = 1 && rs2 = = 1 {return BT. Right.getancestor (Node1, Node2)} else if rs1 = =-1 && rs2 = =-1 {return BT. Left.getancestor (Node1, Node2)} else {return BT, Nil}}//assume Node1 and Node2 is contained,get the nearest distance of TW o node,however,it didn ' t support compare-nodes which has the same data,new (one) and New (one) is uncomparable//if Node1 or node2 isn ' t included,nil pointer error occurredfunc (BT *binarynode) getdistance (Node1, Node2 *binarynode) (int, error) {ancestor, er: = bt. GetAncestor (Node1, node2) if er! = nil {return-1, er}tmp1, er: = ancestor. Getdepth (node1) if er! = nil {return-1, er}tmp2, er: = ancestor. Getdepth (node2) if er! = nil {return-1, Er}return tmp1 + tmp2, nil}//get max depth of a BT, returns MAXDEPTH,LEFTMAXDEPTH, Rightmaxdepth,Errorfunc (BT *binarynode) getmaxdepth (int, int, int, error) {if BT = = Nil {return 0, 0, 0, Nil}var Leftmax, Rightmax i Ntvar er errorif bt. Left! = Nil {Leftmax, _, _, er = bt. Left.getmaxdepth () if er! = nil {return-1,-1,-1, Er}leftmax++}if BT. Right! = Nil {Rightmax, _, _, er = bt. Right.getmaxdepth () if er! = nil {return-1,-1,-1, er}rightmax++}if Leftmax > Rightmax {return Leftmax, Leftmax, right Max, Nil}return Rightmax, Leftmax, Rightmax, Nil}//get Max, node distance of a btfunc (BT *binarynode) getmaxdistance () (int, error) {if BT = = Nil {return 0, Nil}var lMax1 = 0var RMax1 = 0var LMax2 = 0var rMax2 = 0var er error_, lMax1, rMax1, er = bt. Getmaxdepth () if Bt. Left! = nil {lMax2, er = bt. Left.getmaxdistance () if er! = nil {return-1, er}if bt. Right! = nil {lmax2++}}if BT. Right! = nil {rMax2, er = bt. Right.getmaxdistance () if er! = nil {return-1, er}if bt. Left! = Nil {Rmax2++}}return max ((LMax1 + rMax1), LMAX2, RMAX2), Nil}//get a BT ' s node Numberfunc (BT *binarynode) GetNodeSnum (sum *int) {if BT! = Nil {*sum + = 1if bt. Right! = nil {bt. Right.getnodesnum (sum)}if BT. Left! = nil {bt. Left.getnodesnum (sum)}}}//get a BT ' s node number escaping Argfunc (BT *binarynode) Getnodesnumescapingargs () int {var sum INTBT. Getnodesnum (&sum) return sum}//get the maxheight of a btfunc (BT *binarynode) getmaxheight () int {if BT = = Nil {return 0}tmp, _, _, _: = Bt. Getmaxdepth () return tmp}//get a node ' s Heightfunc (BT *binarynode) getnodeheight (node *binarynode) int {Total, _, _, _: = Bt. Getmaxdepth () tmp, _: = Bt. Getdepth (node) return total-tmp}//transfer a BT to a array ASC Sortedfunc (BT *binarynode) Toascarray (Rs *[]interface{}, Flag *int) {if Bt. Left! = nil {bt. Left.toascarray (RS, Flag)} (*RS) [*flag] = BT. Data*flag++if BT. Right! = nil {bt. Right.toascarray (RS, flag)}}//transfer a BT to an array ASC escaping Argsfunc (BT *binarynode) Toascarrayescapingargs () [] interface{} {var sum intvar rs []interface{}var flag INTBT. Getnodesnum (&sum) rs = make ([]interface{}, Sum) bt. ToAScarray (&rs, &flag) return rs}//transfer a BT to a array desc sortedfunc (BT *binarynode) Todescarray (Rs *[]interfa ce{}, Flag *int) {if Bt. Right! = nil {bt. Right.todescarray (RS, Flag)} (*RS) [*flag] = BT. Data*flag++if BT. Left! = nil {bt. Left.todescarray (RS, flag)}}//transfer a BT to an array desc escaping Argsfunc (BT *binarynode) Todescarrayescapingargs () []interface{} {var sum intvar rs []interface{}var flag INTBT. Getnodesnum (&sum) rs = make ([]interface{}, Sum) bt. Todescarray (&rs, &flag) return Rs}//assume got a node, find its root by this functionfunc (BT *binarynode) Findroo T () *binarynode {if Bt. Parant! = Nil {return BT. Parant.findroot ()} else {return bt}}//cached a BT in global Cachefunc (BT *binarynode) Cached () *btreecache {roottmp: = BT . FindRoot () for k: = Range Cache {if cache[k]. Root = = Bt. FindRoot () {cache[k]. Refresh () return cache[k]}}cache[roottmp] = &btreecache{root:bt. FindRoot ()}cache[roottmp]. Refresh () return cache[roottmp]}//get a BT s cache,if not exIsted,throws an Errorfunc (BT *binarynode) GetCache () (*btreecache, error) {for k, _: = Range Cache {if k = = Bt. FindRoot () {return cache[k], Nil}}return nil, errors. New ("This binary tree had not been cached Yet,use BT. Cached () first,or use BT. Mustgetcache () ")}//get a BT's cache,if not existed,generate one and then return Itfunc (BT *binarynode) Mustgetcache () *BTREEC Ache {for k: = Range Cache {if k = = Bt. FindRoot () {return Cache[k]}}return BT. Cached ()}//transfer a BT to a redblack pattern//what are a red-black tree,refer to www.baidu.com, Www.google.comfunc (BT *b Inarynode) Toredblack () error {return nil}//transfer a BT to an AVL parttern//what are an AVL tree,refer to WWW.BAIDU.COM,WW W.google.comfunc (BT *binarynode) Toavl () (*AVL) {tmp: = BT. Balancecopy () return &avl{root:tmp}}//transfer a BT to a linked list order Ascfunc (BT *binarynode) Toasclinkedlist () ( *sortedlinkedlist, error) {var sum intbt. Getnodesnum (&sum) var rs = make ([]interface{}, sum) var flag = 0BT. Toascarray (&rs, &amP;flag) Head: = New (Rs[0]) Tail: = Headvar tmp *binarynodefor i: = 1; I < Len (RS); i++ {tmp = New (Rs[i]) tail. right = Tmptmp. left = Tailtail = Tmp}return &sortedlinkedlist{head}, Nil}//transfer a BT to a LinkedList descfunc (BT *BinaryNode) to Desclinkedlist () (*sortedlinkedlist, error) {var sum intbt. Getnodesnum (&sum) var rs = make ([]interface{}, sum) var flag = 0BT. Todescarray (&rs, &flag) Head: = New (Rs[0]) Tail: = Headvar tmp *binarynodefor i: = 1; I < Len (RS); i++ {tmp = New (Rs[i]) tail. right = Tmptmp. left = Tailtail = Tmp}return &sortedlinkedlist{head}, nil}////rotate left//func (av *redblack) LeftRotate () (*AVL, err OR) {//return nil, nil//}//////rotate right//func (av *redblack) rightrotate () (*AVL, error) {//return nil, nil//}//compar E-interface{} value, only supports for Int,int64,int32,int16,int8,string,float32,float64func Compare (v1 interface{} , V2 interface{}) (int, error) {if reflect. TypeOf (v1). Kind (). String ()! = reflect. TypeOf (v2). Kind (). String () {RetuRn-1, errors. New ("The two types do not match, for a BT tree chain, it is not recommended to store different data types of objects")}switch v1. (type) {case INT:V1TMP: = v1. (int) V2tmp: = v2. (int) If v1tmp > v2tmp {return 1, nil} else if v1tmp = = v2tmp {return 0, nil} else {return-1, nil}case int64:v1tmp: = V 1. (Int64) V2tmp: = v2. (Int64) If v1tmp > v2tmp {return 1, nil} else if v1tmp = = v2tmp {return 0, nil} else {return-1, nil}case int32:v1tmp: = V1. (Int32) V2tmp: = v2. (Int32) if V1tmp > v2tmp {return 1, nil} else if v1tmp = = v2tmp {return 0, nil} else {return-1, nil}case int16:v1tmp: = V1. (int16) V2tmp: = v2. (int16) If v1tmp > v2tmp {return 1, nil} else if v1tmp = = v2tmp {return 0, nil} else {return-1, nil}case int8:v1tmp: = V1. (int8) V2tmp: = v2. (int8) If v1tmp > v2tmp {return 1, nil} else if v1tmp = = v2tmp {return 0, nil} else {return-1, nil}case string:v1tmp: = V1. (string) V2tmp: = v2. (string) If V1tmp > v2tmp {return 1, nil} else if v1tmp = = v2tmp {return 0, nil} else {return-1, nil}case float32:v1tmp : = v1. (float32) V2tmp: = v2. (float32) If v1tmp> v2tmp {return 1, nil} else if v1tmp = = v2tmp {return 0, nil} else {return-1, nil}case float64:v1tmp: = v1. (float64) V2tmp: = v2. (float64) If v1tmp > v2tmp {return 1, nil} else if v1tmp = = v2tmp {return 0, nil} else {return-1, nil}}return-1, error S.new ("Only support compare Int,int8,int16,int32,int64,float32,float64,string")}func max (args ... int) int {var maxtmp = Args[0]for I: = 0; I < Len (args)-1; i++ {for J: = i + 1, j < Len (args), J + + {if maxtmp < Args[j] {maxtmp = Args[j]}}}return maxtmp}func abs (arg int) int{ If arg>0 {return arg}else{return-arg}}func smartprint (i interface{}) {var kv = make (map[string]interface{}) Vvalue: = R Eflect. ValueOf (i) VType: = reflect. TypeOf (i) for i: = 0; I < Vvalue.numfield (); i++ {Kv[vtype.field (i). Name] = Vvalue.field (i)}fmt. Println ("Get to Data:") for K, V: = range kv {fmt. Print (k) fmt. Print (":") fmt. Print (v) fmt. Println ()}}func Ifzero (ARG interface{}) bool {if arg = = Nil {return True}switch V: = arg. (type) {case int, float64, Int32, Int16, int64, float32:if v = = 0 {return True}case string:if v = = "" | | v = = "percent" | | v = = "%" {return true}case *string, *int, *int64, *int32, *int16, *int8, *float32, *float64:if v = nil {return True}defau Lt:return False}return false} "project hosted in [Https://github.com/fwhezfwhez/go-BinaryTree] (github.com/fwhezfwhez/ Go-binarytree) 107 reads