Golang以OO的方式實現二叉尋找樹

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

二叉尋找樹是一種滿足如下性質的二叉樹:

(1)  某個節點的左子樹中的所有節點的值都比這個節點的值小

(2)  某個節點的右子樹中的所有節點的值都比這個節點的值大


下面有Go實現的非常詳盡的代碼,採用了Go風格的OO進行了封裝。代碼中主函數的例子的參照圖如下:



這是我的二叉尋找樹的使用手冊:

type BiSearchTree struct func (bst *BiSearchTree) Add(data float64)                        //插入節點func (bst *BiSearchTree) Delete(data float64)                   //刪除節點func (bst BiSearchTree) GetRoot() *TreeNode                       //擷取根節點func (bst BiSearchTree) IsEmpty() bool                            //檢查樹是否為空白func (bst BiSearchTree) InOrderTravel()                           //中序遍曆(也就是從小到大輸出)func (bst BiSearchTree) Search(data float64) *TreeNode            //尋找節點func (bst BiSearchTree) GetDeepth() int                           //擷取樹的深度func (bst BiSearchTree) GetMin() float64                          //擷取值最小的節點func (bst BiSearchTree) GetMax() float64                          //擷取值最大的節點func (bst BiSearchTree) GetPredecessor(data float64) *TreeNode    //擷取直接前驅func (bst BiSearchTree) GetSuccessor(data float64) *TreeNode      //擷取直接後繼func (bst *BiSearchTree) Clear()                                  //清空樹

實現代碼:

package mainimport ("fmt")type TreeNode struct {data   float64lchild *TreeNoderchild *TreeNodeparent *TreeNode}type BiSearchTree struct {root   *TreeNodecur    *TreeNodecreate *TreeNode}func (bst *BiSearchTree) Add(data float64) {bst.create = new(TreeNode)bst.create.data = dataif !bst.IsEmpty() {bst.cur = bst.rootfor {if data < bst.cur.data {//如果要插入的值比當前節點的值小,則當前節點指向當前節點的左孩子,如果//左孩子為空白,就在這個左孩子上插入新值if bst.cur.lchild == nil {bst.cur.lchild = bst.createbst.create.parent = bst.curbreak} else {bst.cur = bst.cur.lchild}} else if data > bst.cur.data {//如果要插入的值比當前節點的值大,則當前節點指向當前節點的右孩子,如果//右孩子為空白,就在這個右孩子上插入新值if bst.cur.rchild == nil {bst.cur.rchild = bst.createbst.create.parent = bst.curbreak} else {bst.cur = bst.cur.rchild}} else {//如果要插入的值在樹中已經存在,則退出return}}} else {bst.root = bst.createbst.root.parent = nil}}func (bst *BiSearchTree) Delete(data float64) {var (deleteNode func(node *TreeNode)node       *TreeNode = bst.Search(data))deleteNode = func(node *TreeNode) {if node == nil {return}if node.lchild == nil && node.rchild == nil {//如果要刪除的節點沒有孩子,直接刪掉它就可以(毫無挂念~.~!)if node == bst.root {bst.root = nil} else {if node.parent.lchild == node {node.parent.lchild = nil} else {node.parent.rchild = nil}}} else if node.lchild != nil && node.rchild == nil {//如果要刪除的節點只有左孩子或右孩子,讓這個節點的父節點指向它的指標指向它的//孩子即可if node == bst.root {node.lchild.parent = nilbst.root = node.lchild} else {node.lchild.parent = node.parentif node.parent.lchild == node {node.parent.lchild = node.lchild} else {node.parent.rchild = node.lchild}}} else if node.lchild == nil && node.rchild != nil {if node == bst.root {node.rchild.parent = nilbst.root = node.rchild} else {node.rchild.parent = node.parentif node.parent.lchild == node {node.parent.lchild = node.rchild} else {node.parent.rchild = node.rchild}}} else {//如果要刪除的節點既有左孩子又有右孩子,就把這個節點的直接後繼的值賦給這個節//點,然後刪除直接後繼節點即可successor := bst.GetSuccessor(node.data)node.data = successor.datadeleteNode(successor)}}deleteNode(node)}func (bst BiSearchTree) GetRoot() *TreeNode {if bst.root != nil {return bst.root}return nil}func (bst BiSearchTree) IsEmpty() bool {if bst.root == nil {return true}return false}func (bst BiSearchTree) InOrderTravel() {var inOrderTravel func(node *TreeNode)inOrderTravel = func(node *TreeNode) {if node != nil {inOrderTravel(node.lchild)fmt.Printf("%g ", node.data)inOrderTravel(node.rchild)}}inOrderTravel(bst.root)}func (bst BiSearchTree) Search(data float64) *TreeNode {//和Add操作類似,只要按照比當前節點小就往左孩子上拐,比當前節點大就往右孩子上拐的思路//一路找下去,知道找到要尋找的值返回即可bst.cur = bst.rootfor {if bst.cur == nil {return nil}if data < bst.cur.data {bst.cur = bst.cur.lchild} else if data > bst.cur.data {bst.cur = bst.cur.rchild} else {return bst.cur}}}func (bst BiSearchTree) GetDeepth() int {var getDeepth func(node *TreeNode) intgetDeepth = func(node *TreeNode) int {if node == nil {return 0}if node.lchild == nil && node.rchild == nil {return 1}var (ldeepth int = getDeepth(node.lchild)rdeepth int = getDeepth(node.rchild))if ldeepth > rdeepth {return ldeepth + 1} else {return rdeepth + 1}}return getDeepth(bst.root)}func (bst BiSearchTree) GetMin() float64 {//根據二叉尋找樹的性質,樹中最左邊的節點就是值最小的節點if bst.root == nil {return -1}bst.cur = bst.rootfor {if bst.cur.lchild != nil {bst.cur = bst.cur.lchild} else {return bst.cur.data}}}func (bst BiSearchTree) GetMax() float64 {//根據二叉尋找樹的性質,樹中最右邊的節點就是值最大的節點if bst.root == nil {return -1}bst.cur = bst.rootfor {if bst.cur.rchild != nil {bst.cur = bst.cur.rchild} else {return bst.cur.data}}}func (bst BiSearchTree) GetPredecessor(data float64) *TreeNode {getMax := func(node *TreeNode) *TreeNode {if node == nil {return nil}for {if node.rchild != nil {node = node.rchild} else {return node}}}node := bst.Search(data)if node != nil {if node.lchild != nil {//如果這個節點有左孩子,那麼它的直接前驅就是它左子樹的最右邊的節點,因為比這//個節點值小的節點都在左子樹,而這些節點中值最大的就是這個最右邊的節點return getMax(node.lchild)} else {//如果這個節點沒有左孩子,那麼就沿著它的父節點找,知道某個父節點的父節點的右//孩子就是這個父節點,那麼這個父節點的父節點就是直接前驅for {if node == nil || node.parent == nil {break}if node == node.parent.rchild {return node.parent}node = node.parent}}}return nil}func (bst BiSearchTree) GetSuccessor(data float64) *TreeNode {getMin := func(node *TreeNode) *TreeNode {if node == nil {return nil}for {if node.lchild != nil {node = node.lchild} else {return node}}}//參照尋找直接前驅的函數對比著看node := bst.Search(data)if node != nil {if node.rchild != nil {return getMin(node.rchild)} else {for {if node == nil || node.parent == nil {break}if node == node.parent.lchild {return node.parent}node = node.parent}}}return nil}func (bst *BiSearchTree) Clear() {bst.root = nilbst.cur = nilbst.create = nil}func main() {var bst BiSearchTreebst.Add(15)bst.Add(6)bst.Add(18)bst.Add(3)bst.Add(7)bst.Add(17)bst.Add(20)bst.Add(2)bst.Add(4)bst.Add(13)bst.Add(9)bst.Add(14)fmt.Printf("The nodes of the BiSearchTree is: ")bst.InOrderTravel()fmt.Printf("\n")fmt.Printf("The deepth of the tree is: %d\n", bst.GetDeepth())fmt.Printf("The min is: %g\n", bst.GetMin())fmt.Printf("The max is: %g\n", bst.GetMax())if bst.Search(17) != nil {fmt.Printf("The 17 exists.\n")}fmt.Printf("root node's predecessor is: %g\n", bst.GetPredecessor(bst.GetRoot().data).data)fmt.Printf("root node's successor is: %g\n", bst.GetSuccessor(bst.GetRoot().data).data)bst.Delete(13)fmt.Printf("Nodes after delete the 13: ")bst.InOrderTravel()fmt.Printf("\n")}


輸出結果:





如果轉載請註明出處:http://blog.csdn.net/gophers/article/details/23552925




相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.