Golang树结构的实现。
树结构Golang源代码:
1 /* 2 ** 3 ** Version : 0.1 4 ** 5 */ 6 7 package mnds 8 9 import ( 10 "errors" 11 "fmt" 12 "strings" 13 ) 14 15 type Tree struct { 16 name string 17 parent *Tree 18 son []*Tree 19 } 20 21 func (this *Tree) Create(name string) { 22 this.name = name 23 this.son = nil 24 } 25 26 func (this *Tree) GetName() string { 27 // Bug: when this is root, can get an nil parent point, it will panic... 28 return this.name 29 } 30 31 func (this *Tree) GetSon(nameofson string) (son *Tree, err error) { 32 for _, v := range this.son { 33 if v.GetName() == nameofson { 34 return v, nil 35 } 36 } 37 return nil, errors.New("No son's name call" + nameofson) 38 } 39 40 func (this *Tree) GetParent() *Tree { 41 return this.parent 42 } 43 44 func (this *Tree) GetPath() []*Tree { 45 var path []*Tree 46 47 path = append(path, this) 48 p := this.parent 49 if p != nil { 50 path = append(path, p.GetPath()...) 51 } 52 53 return path 54 } 55 56 func (this *Tree) AddSon(son interface{}) { 57 switch son.(type) { 58 case string: 59 var Son Tree 60 Son.name = son.(string) 61 Son.parent = this 62 this.son = append(this.son, &Son) 63 case *Tree: 64 this.son = append(this.son, son.(*Tree)) 65 son.(*Tree).parent = this 66 default: 67 break 68 } 69 } 70 71 func (this *Tree) DeleteSon(nameofson string) { 72 for k, v := range this.son { 73 if v.GetName() == nameofson { 74 this.son = append(this.son[:k], this.son[(k+1):]...) 75 } 76 } 77 } 78 79 func (this *Tree) FindNode(nameofnode string) []*Tree { 80 var t []*Tree 81 82 if strings.Contains(this.GetName(), nameofnode) { 83 t = append(t, this) 84 } else { 85 if this.son == nil { 86 t = nil 87 } else { 88 for _, v := range this.son { 89 t = append(t, v.FindNode(nameofnode)...) 90 } 91 } 92 } 93 94 return t 95 } 96 97 func (this Tree) GetDegree() int { 98 degree := len(this.son) 99 100 if this.son != nil { 101 for _, v := range this.son { 102 if degree < v.GetDegree() { 103 degree = v.GetDegree() 104 } 105 } 106 } 107 108 return degree 109 } 110 111 func (this Tree) GetDepth() int { 112 var depth int 113 p := this.parent 114 if p == nil { 115 depth = 0 116 } else { 117 depth = p.GetDepth() + 1 118 } 119 120 return depth 121 } 122 123 func (this Tree) GetHeight() int { 124 var height int = 0 125 126 if this.son == nil { 127 height = 0 128 } else { 129 sonheight := make([]int, len(this.son)) 130 // Get all height of sons 131 for k, v := range this.son { 132 if v.son != nil { 133 // If have son, get its height, and must add 1 134 sonheight[k] = v.GetHeight() + 1 135 } else { 136 // If son havn't son, and his parent's height is 1 137 height = 1 138 } 139 } 140 141 // Get the max height 142 for _, v := range sonheight { 143 if height < v { 144 height = v 145 } 146 } 147 } 148 149 return height 150 } 151 152 // To show all data of the tree. 153 // You can get all data of the tree like this. 154 func (this Tree) ShowAll() { 155 for k := 0; k < this.GetDepth(); k++ { 156 fmt.Printf(" ") 157 } 158 fmt.Printf("%s\n", this.GetName()) 159 if this.son != nil { 160 for _, v := range this.son { 161 for k := 0; k < v.GetDepth(); k++ { 162 fmt.Printf(" ") 163 } 164 v.ShowAll() 165 } 166 } 167 } 168 169 func (this Tree) ToJson() []byte { 170 171 return nil 172 } 173 174 func (this *Tree) FromJson(data []byte) error { 175 176 return nil 177 } 178 179 func (this Tree) ToMap() map[string]string { 180 181 return nil 182 } 183 184 func (this *Tree) FromMap(data map[string]string) error { 185 186 return nil 187 }
测试代码:
1 package main 2 3 import ( 4 "fmt" 5 6 "merrynuts/mnds" 7 ) 8 9 type country struct { 10 mnds.Tree 11 countryname string `json:"countryname"` 12 } 13 14 func main() { 15 var china country 16 var shanghai mnds.Tree 17 var leliu mnds.Tree 18 19 china.Create("中国") 20 china.countryname = china.GetName() 21 fmt.Println(china.countryname) 22 23 china.AddSon("广东省") 24 china.AddSon("吉林省") 25 china.AddSon("广西壮族自治区") 26 china.AddSon("湖南省") 27 china.AddSon("湖北省") 28 29 hn, err := china.GetSon("湖南省") 30 if err != nil { 31 fmt.Println(china.GetName(), "没有一个叫湖南省的儿子") 32 } else { 33 hn.AddSon("长沙市") 34 hn.AddSon("衡阳市") 35 hn.AddSon("张家界市") 36 cs, err := hn.GetSon("长沙市") 37 if err != nil { 38 fmt.Println(cs.GetName(), "没有一个叫长沙市的儿子") 39 } else { 40 cs.AddSon("芙蓉区") 41 cs.AddSon("天心区") 42 cs.AddSon("岳麓区") 43 cs.AddSon("开福区") 44 cs.AddSon("雨花区") 45 cs.AddSon("长沙县") 46 cs.AddSon("望城区") 47 cs.AddSon("浏阳市") 48 cs.AddSon("宁乡市") 49 } 50 } 51 52 gd, err := china.GetSon("广东省") 53 if err != nil { 54 fmt.Println(china.GetName(), "没有一个叫广东省的儿子") 55 } else { 56 gd.AddSon("深圳市") 57 gd.AddSon("广州市") 58 gd.AddSon("佛山市") 59 gd.AddSon("中山市") 60 gd.AddSon("东莞市") 61 fs, err := gd.GetSon("佛山市") 62 if err != nil { 63 fmt.Println(gd.GetName(), "没有一个叫佛山市的儿子") 64 } else { 65 fs.AddSon("顺德区") 66 fs.AddSon("南海区") 67 fs.AddSon("禅城区") 68 fs.AddSon("三水区") 69 fs.AddSon("高明区") 70 sd, err := fs.GetSon("顺德区") 71 if err != nil { 72 fmt.Println(fs.GetName(), "没有一个叫顺德区的儿子") 73 } else { 74 sd.AddSon("大良街道") 75 sd.AddSon("龙江街道") 76 sd.AddSon("伦教街道") 77 sd.AddSon("乐从街道") 78 sd.AddSon("容桂街道") 79 sd.AddSon("杏坛街道") 80 sd.AddSon("均安街道") 81 82 leliu.Create("勒流街道") 83 sd.AddSon(&leliu) 84 } 85 86 nh, err := fs.GetSon("南海区") 87 if err != nil { 88 fmt.Println(fs.GetName(), "没有一个叫南海区的儿子") 89 } else { 90 nh.AddSon("狮山街道") 91 nh.AddSon("罗村街道") 92 nh.AddSon("丹灶街道") 93 } 94 } 95 } 96 97 gx, err := china.GetSon("广西壮族自治区") 98 if err != nil { 99 fmt.Println(china.GetName(), "没有一个叫广西壮族自治区的儿子") 100 } else { 101 gx.AddSon("桂林市") 102 gx.AddSon("柳州市") 103 gx.AddSon("梧州市") 104 gx.AddSon("北海市") 105 gl, err := gx.GetSon("桂林市") 106 if err != nil { 107 fmt.Println(gx.GetName(), "没有一个叫桂林市的儿子") 108 } else { 109 gl.AddSon("桂平市") 110 gl.AddSon("顺德区") 111 } 112 var hechen mnds.Tree 113 hechen.Create("河辰市") 114 gx.AddSon(&hechen) 115 } 116 117 shanghai.Create("上海市") 118 shanghai.AddSon("静安区") 119 shanghai.AddSon("浦东区") 120 china.AddSon(&shanghai) 121 122 fmt.Println(china.GetName(), "的整体结构如下:") 123 fmt.Println("===========================================================") 124 china.ShowAll() 125 fmt.Println("-----------------------------------------------------------") 126 127 for { 128 var ss string 129 fmt.Printf("Search? ") 130 fmt.Scanf("%s\n", &ss) 131 if ss == "exit" { 132 break 133 } 134 result := china.FindNode(ss) 135 if result == nil { 136 fmt.Println("Can't find the node name's", ss) 137 } else { 138 for k, v := range result { 139 fmt.Println("===========================================================") 140 fmt.Println("Find the no.", k+1 , "of node name's", ss, "It's path to root is :") 141 path := v.GetPath() 142 for k := len(path) - 1; k >= 0; k-- { 143 if k > 0 { 144 fmt.Printf("%s-->", path[k].GetName()) 145 } else { 146 fmt.Printf("%s", path[k].GetName()) 147 } 148 } 149 fmt.Println() 150 fmt.Println("It's structure is :") 151 v.ShowAll() 152 fmt.Println("-----------------------------------------------------------") 153 } 154 } 155 } 156 }
运行效果:
D:\project\merrynuts\src>merrynuts 中国 中国 的整体结构如下: =========================================================== 中国 广东省 深圳市 广州市 佛山市 顺德区 大良街道 龙江街道 伦教街道 乐从街道 容桂街道 杏坛街道 均安街道 勒流街道 南海区 狮山街道 罗村街道 丹灶街道 禅城区 三水区 高明区 中山市 东莞市 吉林省 广西壮族自治区 桂林市 桂平市 顺德区 柳州市 梧州市 北海市 河辰市 湖南省 长沙市 芙蓉区 天心区 岳麓区 开福区 雨花区 长沙县 望城区 浏阳市 宁乡市 衡阳市 张家界市 湖北省 上海市 静安区 浦东区 ----------------------------------------------------------- Search?