ScummVM API documentation
BinTree.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /*
23  * Copyright (C) 2006-2010 - Frictional Games
24  *
25  * This file is part of HPL1 Engine.
26  */
27 
28 #ifndef HPL_BINTREE_H
29 #define HPL_BINTREE_H
30 
31 #include "common/list.h"
32 
33 namespace hpl {
34 
35 enum eBinTreeNode {
36  eBinTreeNode_Left,
37  eBinTreeNode_Right
38 };
39 
41 // TREE NODE CLASS
43 
44 template<class T>
45 class BinTreeNode {
46 public:
47  T *GetData() {
48  return &mData;
49  }
50 
51  BinTreeNode(T aData, BinTreeNode<T> *aParent, eBinTreeNode aParentDir) {
52  for (int i = 0; i < 2; i++)
53  mChild[i] = NULL;
54  mData = aData;
55  mParent = aParent;
56  mParentDir = aParentDir;
57  }
58 
59  BinTreeNode<T> *AddChild(eBinTreeNode i, T aData) {
60  if (mChild[i] == NULL) {
61  mChild[i] = hplNew(BinTreeNode<T>, (aData, this, i));
62  return mChild[i];
63  }
64  return NULL;
65  }
66 
67  BinTreeNode<T> *GetChild(eBinTreeNode i) {
68  return mChild[i];
69  }
70 
71  BinTreeNode<T> *GetParent() {
72  return mParent;
73  }
74 
75 private:
76  BinTreeNode<T> *mChild[2];
77  BinTreeNode<T> *mParent;
78  T mData;
79  eBinTreeNode mParentDir;
80 };
81 
83 // MAIN TREE CLASS
85 
86 template<class T>
87 class BinTree {
88 public:
89  BinTree() {
90  mlNumOfNodes = 0;
91  mFirstNode = NULL;
92  }
93 
94  ~BinTree() {
95  Clear();
96  }
97 
102  int Clear() {
103  mlNum = 0;
104  DeleteNode(mFirstNode);
105  mFirstNode = NULL;
106  return mlNum;
107  }
108 
115  BinTreeNode<T> *Insert(T aData) {
116  if (mFirstNode == NULL) {
117  mFirstNode = hplNew(BinTreeNode<T>, (aData, NULL, eBinTreeNode_Left));
118  mlNumOfNodes++;
119 
120  return mFirstNode;
121  }
122 
123  // Insertion other then at the root is not supported!
124  BinTreeNode<T> *Node = mFirstNode;
125  eBinTreeNode c;
126  while (true) {
127  // if(Node->GetData()<aData)
128  c = eBinTreeNode_Left;
129  // else
130  // c = eBinTreeNode_Right;
131 
132  if (Node->GetChild(c) == NULL) {
133  Node = Node->AddChild(c, aData);
134  break;
135  } else {
136  Node = Node->GetChild(c);
137  }
138  }
139  mlNumOfNodes++;
140 
141  return Node;
142  }
143 
151  BinTreeNode<T> *InsertAt(T aData, BinTreeNode<T> *aNode, eBinTreeNode aChild = eBinTreeNode_Left) {
152  if (aNode == NULL)
153  return NULL;
154 
155  if (aNode->GetChild(aChild) != NULL) {
156  aChild = aChild == eBinTreeNode_Left ? eBinTreeNode_Right : eBinTreeNode_Left;
157  if (aNode->GetChild(aChild) != NULL)
158  return NULL;
159  }
160 
161  return aNode->AddChild(aChild, aData);
162  }
163 
168  int Size() {
169  return mlNumOfNodes;
170  }
171 
172  const Common::List<BinTreeNode<T> *> &GetLeafList() {
173  mlstNodes.clear();
174  PopulateLeafList(mFirstNode);
175  return mlstNodes;
176  }
177 
183  mlstNodes.clear();
184  PopulateNodeList(mFirstNode);
185  return mlstNodes;
186  }
187 
188 private:
189  int mlNumOfNodes;
190  BinTreeNode<T> *mFirstNode;
191  int mlNum;
192 
193  Common::List<BinTreeNode<T> *> mlstNodes;
194 
195  void DeleteNode(BinTreeNode<T> *aNode) {
196  if (aNode == NULL)
197  return;
198 
199  DeleteNode(aNode->GetChild(eBinTreeNode_Left));
200  DeleteNode(aNode->GetChild(eBinTreeNode_Right));
201 
202  hplDelete(aNode);
203  mlNum++;
204  }
205 
206  void PopulateNodeList(BinTreeNode<T> *aNode) {
207  if (aNode == NULL)
208  return;
209 
210  PopulateNodeList(aNode->GetChild(eBinTreeNode_Left));
211  mlstNodes.push_back(aNode);
212  PopulateNodeList(aNode->GetChild(eBinTreeNode_Right));
213  }
214 
215  void PopulateLeafList(BinTreeNode<T> *aNode) {
216  if (aNode == NULL)
217  return;
218 
219  if (aNode->GetChild(eBinTreeNode_Left) == NULL &&
220  aNode->GetChild(eBinTreeNode_Right) == NULL) {
221  mlstNodes.push_back(aNode);
222  }
223 
224  PopulateLeafList(aNode->GetChild(eBinTreeNode_Left));
225  PopulateLeafList(aNode->GetChild(eBinTreeNode_Right));
226  }
227 };
228 
229 } // namespace hpl
230 
231 #endif // HPL_BINTREE_H
Definition: AI.h:36
int Size()
Definition: BinTree.h:168
BinTreeNode< T > * InsertAt(T aData, BinTreeNode< T > *aNode, eBinTreeNode aChild=eBinTreeNode_Left)
Definition: BinTree.h:151
Definition: list.h:44
const Common::List< BinTreeNode< T > * > & GetNodeList()
Definition: BinTree.h:182
Definition: BinTree.h:87
void clear()
Definition: list.h:206
Definition: BinTree.h:45
BinTreeNode< T > * Insert(T aData)
Definition: BinTree.h:115
void push_back(const t_T &element)
Definition: list.h:140
Definition: lobject.h:332
int Clear()
Definition: BinTree.h:102