depth:n的depth為從root到n的路徑的長(zhǎng)度
height:n的height為從n到一個(gè)leaf的最長(zhǎng)路徑長(zhǎng)度。樹(shù)的height等于root的depth
preorder traversal: 遍歷順序弥锄,根秽誊,左子樹(shù),右子樹(shù)
postorder traversal: 遍歷順序桩引,左子樹(shù)崇败,右子樹(shù),根
inorder traversal: 遍歷順序, 左子樹(shù)奈偏,根,右子樹(shù)
- Bineary search tree
average depth = O(logN)
worst case depth is O(N)
implementation:
struct BinaryNode
{
Object element; //The data in the node
BinaryNode *left; //Left child
BinaryNode *right; //Right child
};
contains:
/*Internam method to test if an item is in a subtree
* x is itemto search for.
* t is the node that roots the subtree
*/
bool contains(const Comparable & x, BinaryNode *t) const
{
if (t == NULL) return false;
else if (x < t->element) return contains(x, t->left);
else if (x > t->element) return contains(x, t->right);
else return true; //match
}
findMin and findMax (recursion and iteration implementation):
//recursion, return node containing the smallest item
BinaryNode * findMin(BinaryNode *t) const
{
if(t == NULL) return NULL;
if(t->left == NULL) return t;
return findMin(t->left);
}
//iteration, return node containing the largest item
BinaryNode * findMax(BinaryNode *t) const
{
if(t != NULL)
{
while (t->right != NULL)
{
t = t->right;
}
}
return t;
}
insert:
/* x is the item to nsert
t is the node that roots the subtree
set the new root of the subtree
*/
void insert(const Comparable & x, BinaryNode * &t)
{
if(t == NULL) t = new BinaryNode(x, NULL, NULL);
else if (x < t->element) insert(x, t->left);
else if (x > t->element) insert(x, t->right);
else ; //duplicate, do nothing
}
remove:
需要考慮多種情況躯护。
如果結(jié)點(diǎn)是樹(shù)葉惊来,可以直接刪除。
如果結(jié)點(diǎn)有一個(gè)child棺滞,刪除后將child與父結(jié)點(diǎn)連接裁蚁,如下
如果結(jié)點(diǎn)有兩個(gè)child,一般的刪除策略是用其右字?jǐn)?shù)中的最小數(shù)據(jù)代替該節(jié)點(diǎn)并遞歸地刪除那個(gè)節(jié)點(diǎn)继准。例子如下
實(shí)現(xiàn):
//效率不高枉证,因?yàn)檠貥?shù)兩次搜索來(lái)查找和刪除右子樹(shù)中的最小節(jié)點(diǎn)
//如要提高效率,需要寫(xiě)一個(gè)特殊的removeMin
void remove(const Comparable & x, BinaryNode * &t)
{
if(t == NULL) return; //item not found, do nothing
if(x < t->element) remove(x,t->left);
else if(x > t->element) remove(x,t->right);
else if(t->left != NULL && t->right != NULL) //Two children
{
t->element = findMin(t->right)->element;
remove(t->element,t->right);
}
else //node has only one child
{
BinaryNode *oldNode = t;
t = (t->left != NULL) ? t->left : t->right;
delete oldNode;
}
}
makeEmpty and destructor:
~BinarySearchTree()
{
makeEmpty();
}
void makeEmpty(BinaryNode * &t)
{
if (t != NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = NULL; //important
}
operator= and clone:
//deep copy
const BinarySearchTree & operator=(const BinarySearchTree &rhs)
{
if(this != &rhs)
{
makeEmpty();
root = clone(rhs.root);
}
return *this;
}
//method to clone subtree
BinaryNode *clone(BinaryNode *t) const
{
if(t == NULL) return NULL;
return new BinaryNode(t->element,clone(t->left),clone(t->right));
}
Complexity analysis:
average case:
O(logN) for all operation
actually O(d) for all operations except makeEmpty and operator=
d = depth including the node visited
worst case: O(N)Tree traversal:
O(N) complexity
print tree in sorted order:
//inorder
void printTree(BinaryNode *t) const
{
if(t != NULL)
{
printTree(t->left);
cout << t->element << endl;
printTree(t->right);
}
}
compute height:
int height(BinaryNode *t)
{
if(t == NULL) return -1;
else return 1 + max(height(t->left),height(t->right));
}