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?