📄 d_stree.h
字号:
// t is current node in traversal, parent the previous node
stnode<T> *t = root, *parent = NULL, *newNode;
// terminate on on empty subtree
while(t != NULL)
{
// update the parent pointer. then go left or right
parent = t;
// if a match occurs, return a pair whose iterator
// component points at item in the tree and whose
// bool component is false
if (item == t->nodeValue)
return pair<iterator, bool> (iterator(t, this), false);
else if (item < t->nodeValue)
t = t->left;
else
t = t->right;
}
// create the new leaf node
newNode = getSTNode(item,NULL,NULL,parent);
// if parent is NULL, insert as root node
if (parent == NULL)
root = newNode;
else if (item < parent->nodeValue)
// insert as left child
parent->left = newNode;
else
// insert as right child
parent->right = newNode;
// increment size
treeSize++;
// return an pair whose iterator component points at
// the new node and whose bool component is true
return pair<iterator, bool> (iterator(newNode, this), true);
}
template <typename T>
void stree<T>::erase(iterator pos)
{
// dNodePtr = pointer to node D that is deleted
// pNodePtr = pointer to parent P of node D
// rNodePtr = pointer to node R that replaces D
stnode<T> *dNodePtr = pos.nodePtr, *pNodePtr, *rNodePtr;
if (treeSize == 0)
throw
underflowError("stree erase(): tree is empty");
if (dNodePtr == NULL)
throw
referenceError("stree erase(): invalid iterator");
// assign pNodePtr the address of P
pNodePtr = dNodePtr->parent;
// If D has a NULL pointer, the
// replacement node is the other child
if (dNodePtr->left == NULL || dNodePtr->right == NULL)
{
if (dNodePtr->right == NULL)
rNodePtr = dNodePtr->left;
else
rNodePtr = dNodePtr->right;
if (rNodePtr != NULL)
// the parent of R is now the parent of D
rNodePtr->parent = pNodePtr;
}
// both pointers of dNodePtr are non-NULL.
else
{
// find and unlink replacement node for D.
// starting at the right child of node D,
// find the node whose value is the smallest of all
// nodes whose values are greater than the value in D.
// unlink the node from the tree.
// pOfRNodePtr = pointer to parent of replacement node
stnode<T> *pOfRNodePtr = dNodePtr;
// first possible replacement is right child of D
rNodePtr = dNodePtr->right;
// descend down left subtree of the right child of D,
// keeping a record of current node and its parent.
// when we stop, we have found the replacement
while(rNodePtr->left != NULL)
{
pOfRNodePtr = rNodePtr;
rNodePtr = rNodePtr->left;
}
if (pOfRNodePtr == dNodePtr)
{
// right child of deleted node is the replacement.
// assign left subtree of D to left subtree of R
rNodePtr->left = dNodePtr->left;
// assign the parent of D as the parent of R
rNodePtr->parent = pNodePtr;
// assign the left child of D to have parent R
dNodePtr->left->parent = rNodePtr;
}
else
{
// we moved at least one node down a left branch
// of the right child of D. unlink R from tree by
// assigning its right subtree as the left child of
// the parent of R
pOfRNodePtr->left = rNodePtr->right;
// the parent of the right child of R is the
// parent of R
if (rNodePtr->right != NULL)
rNodePtr->right->parent = pOfRNodePtr;
// put replacement node in place of dNodePtr
// assign children of R to be those of D
rNodePtr->left = dNodePtr->left;
rNodePtr->right = dNodePtr->right;
// assign the parent of R to be the parent of D
rNodePtr->parent = pNodePtr;
// assign the parent pointer in the children
// of R to point at R
rNodePtr->left->parent = rNodePtr;
rNodePtr->right->parent = rNodePtr;
}
}
// complete the link to the parent node.
// deleting the root node. assign new root
if (pNodePtr == NULL)
root = rNodePtr;
// attach R to the correct branch of P
else if (dNodePtr->nodeValue < pNodePtr->nodeValue)
pNodePtr->left = rNodePtr;
else
pNodePtr->right = rNodePtr;
// delete the node from memory and decrement tree size
delete dNodePtr;
treeSize--;
}
template <typename T>
int stree<T>::erase(const T& item)
{
int numberErased = 1;
// search tree for item
stnode<T> *p = findNode(item);
// if item found, delete the node
if (p != NULL)
erase(iterator(p,this));
else
numberErased = 0;
return numberErased;
}
template <typename T>
void stree<T>::erase(iterator first, iterator last)
{
if (treeSize == 0)
throw
underflowError("stree erase(): tree is empty");
iterator p = first;
if (first == begin() && last == end())
{
// we are asked to erase the entire tree.
// erase the tree nodes from memory
deleteTree(root);
// tree is emtpy
root = NULL;
treeSize = 0;
}
else
// erase each item in a subrange of the tree
while (p != last)
erase(p++);
}
template <typename T>
stree<T>::iterator stree<T>::begin()
{
stnode<T> *curr = root;
// if the tree is not empty, the first node
// inorder is the farthest node left from root
if (curr != NULL)
while (curr->left != NULL)
curr = curr->left;
// build return value using private constructor
return iterator(curr, this);
}
template <typename T>
stree<T>::const_iterator stree<T>::begin() const
{
const stnode<T> *curr = root;
// if the tree is not empty, the first node
// inorder is the farthest node left from root
if (curr != NULL)
while (curr->left != NULL)
curr = curr->left;
// build return value using private constructor
return const_iterator(curr, this);
}
template <typename T>
stree<T>::iterator stree<T>::end()
{
// end indicated by an iterator with NULL stnode pointer
return iterator(NULL, this);
}
template <typename T>
stree<T>::const_iterator stree<T>::end() const
{
// end indicated by an iterator with NULL stnode pointer
return const_iterator(NULL, this);
}
// recursive inorder scan used to build the shadow tree
template <typename T>
tnodeShadow *stree<T>::buildShadowTree(stnode<T> *t, int level, int& column)
{
// pointer to new shadow tree node
tnodeShadow *newNode = NULL;
// text and ostr used to perform format conversion
char text[80];
ostrstream ostr(text,80);
if (t != NULL)
{
// create the new shadow tree node
newNode = new tnodeShadow;
// allocate node for left child at next level in tree; attach node
tnodeShadow *newLeft = buildShadowTree(t->left, level+1, column);
newNode->left = newLeft;
// initialize data members of the new node
ostr << t->nodeValue << ends; // format conversion
newNode->nodeValueStr = text;
newNode->level = level;
newNode->column = column;
// update column to next cell in the table
column++;
// allocate node for right child at next level in tree; attach node
tnodeShadow *newRight = buildShadowTree(t->right, level+1, column);
newNode->right = newRight;
}
return newNode;
}
template <typename T>
void stree<T>::displayTree(int maxCharacters)
{
string label;
int level = 0, column = 0;
int colWidth = maxCharacters + 1;
//
int currLevel = 0, currCol = 0;
if (treeSize == 0)
return;
// build the shadow tree
tnodeShadow *shadowRoot = buildShadowTree(root, level, column);
// use during the level order scan of the shadow tree
tnodeShadow *currNode;
// store siblings of each tnodeShadow object in a queue so that
// they are visited in order at the next level of the tree
queue<tnodeShadow *> q;
// insert the root in the queue and set current level to 0
q.push(shadowRoot);
// continue the iterative process until the queue is empty
while(!q.empty())
{
// delete front node from queue and make it the current node
currNode = q.front();
q.pop();
// if level changes, output a newline
if (currNode->level > currLevel)
{
currLevel = currNode->level;
currCol = 0;
cout << endl;
}
// if a left child exists, insert the child in the queue
if(currNode->left != NULL)
q.push(currNode->left);
// if a right child exists, insert the child in the queue
if(currNode->right != NULL)
q.push(currNode->right);
// output formatted node label
if (currNode->column > currCol)
{
cout << setw((currNode->column-currCol)*colWidth) << " ";
currCol = currNode->column;
}
cout << setw(colWidth) << currNode->nodeValueStr;
currCol++;
}
cout << endl;
// delete the shadow tree
deleteShadowTree(shadowRoot);
}
template <typename T>
void stree<T>::deleteShadowTree(tnodeShadow *t)
{
// if current root node is not NULL, delete its left subtree,
// its right subtree and then the node itself
if (t != NULL)
{
deleteShadowTree(t->left);
deleteShadowTree(t->right);
delete t;
}
}
#endif // BINARY_SEARCH_TREE_CLASS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -