1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
template <class T>
bool BST<T>::fGS2(T grandFather, BTNode<T> *cur) {
if (cur == NULL) return false;
if (cur->item == grandFather) {
cout << endl << "Grandfather " << cur->item << " has grandsons" << endl;
fGS3(cur, 0); // do another TT to find grandsons
return true;
}
if (fGS2(grandFather, cur->left)) return true;
return fGS2(grandFather, cur->right);
}
template <class T>
void BST<T>::fGS3(BTNode<T> *cur, int level) {
if (cur == NULL) return;
if (level==2) {
cout << '\t' << cur->item;
return; // No need to search downward
}
fGS3(cur->left, level+1);
fGS3(cur->right, level+1);
}
template <class T>
void BST<T>::topDownLevelTraversal() {
BTNode<T> *cur;
Queue<BTNode<T> *> q;
if (empty()) return; // special case
q.enqueue(root); // Step 1: enqueue the first node
while (!q.empty()) { // Step 2: do 2 operations inside
q.dequeue(cur);
if (cur != NULL) {
cout << cur->item << ' ';
if (cur->left != NULL) q.enqueue(cur->left);
if (cur->right != NULL) q.enqueue(cur->right);
}
}
}
template <class T>
void BST<T>::insert2(BTNode<T> *cur, BTNode<T> *newNode) {
if (cur->item > newNode->item) {
if (cur->left == NULL)
cur->left = newNode;
else
insert2(cur->left, newNode);
}
else {
if (cur->right == NULL)
cur->right = newNode;
else
insert2(cur->right, newNode);
}
}
//insert for BST
template <class T>
bool BST<T>::insert(T newItem) {
BTNode<T> *cur = new BTNode<T>(newItem);
if (!cur) return false; // special case 1
if (root==NULL) {
root = cur;
count++;
return true; // special case 2
}
insert2(root, cur); // normal
count++;
return true;
}
template <class T>
void BST<T>::case3(BTNode<T> *cur) {
BTNode<T> *is, *isFather;
// get the IS and IS_parent of current node
is = isFather = cur->right;
while (is->left!=NULL) {
isFather = is;
is = is->left;
}
// copy IS node into current node
cur->item = is->item;
// Point IS_Father (grandfather) to IS_Child (grandson)
if (is==isFather)
cur->right = is->right; // case 1: There is no IS_Father
else
isFather->left = is->right; // case 2: There is IS_Father
// remove IS Node
free(is);
}
template <class T>
void BST<T>::case2(BTNode<T> *pre, BTNode<T> *cur) {
// special case: delete root node
if (pre==cur) {
if (cur->left!=NULL) // has left son?
root = cur->left;
else
root = cur->right;
free(cur);
return;
}
if (pre->right==cur) { // father is right son of grandfather?
if (cur->left==NULL) // father has no left son?
pre->right = cur->right; // connect gfather/gson
else
pre->right = cur->left;
}
else { // father is left son of grandfather?
if (cur->left==NULL) // father has no left son?
pre->left = cur->right; // connect gfather/gson
else
pre->left = cur->left;
}
free(cur); // remove item
}
template <class T>
bool BST<T>::remove2(BTNode<T> *pre, BTNode<T> *cur, T item) {
// Turn back when the search reaches the end of an external path
if (cur == NULL) return false;
// normal case: manage to find the item to be removed
if (cur->item == item) {
if (cur->left == NULL || cur->right == NULL)
case2 (pre, cur); // case 2 and case 1: cur has less than 2 sons
else
case3 (cur); // case 3, cur has 2 sons
count--; // update the counter
return true;
}
// Current node does NOT store the current item -> ask left sub-tree to check
if (cur->item > item)
return remove2(cur, cur->left, item);
// Item is not in the left subtree, try the right sub-tree instead
return remove2(cur, cur->right, item);
}
template <class T>
bool BST<T>::remove(T item) {
if (root == NULL) return false; // special case 1: tree is empty
return remove2(root, root, item); // normal case
}
#endif
|