Review the implementation of the two-fork search tree, including insert, find and delete operations, and by the way the next two fork tree three traversal operations. All operations take the form of a non recursive method.
#include <iostream>
#include <stack>
using namespace Std;
typedef int T; Value type
Node definition
struct Node {
T Val;
Node *left,*right;
Node (const t& val): Val (Val), left (null), right (NULL) {
}
};
typedef node* NODEPTR; Node pointer
Two-fork search tree implementation
Class BST {
Public
BST (Nodeptr r=null): root (R) {
}
Binary Tree Insert Element
void Insert (const t& val) {
if (root==null) {
Root=new node (val);
}
Cur is the predecessor node of the current node pre as cur
Node *cur=root,*pre;
Traversal to find the appropriate insertion location
while (cur) {
Pre=cur; Record precursor node
cur=cur->val>val?cur->left:cur->right; Forward
}
To determine whether to insert left or right according to the value of the precursor node
if (Pre->val>val) pre->left=new node (val);
else pre->right=new node (val);
}
Binary Tree Lookup Element
Nodeptr Find (const t& val) {
Nodeptr Cur=root;
while (cur) {
if (cur->val==val) return cur;
cur=cur->val>val?cur->left:cur->right; Forward
}
return NULL;
}
Deletes the specified element
void del (const t& val) {
Cur is the predecessor node of the current node pre as cur
Nodeptr Cur=root,pre;
while (cur) {
if (cur->val==val) break;
Pre=cur;
cur=cur->val>val?cur->left:cur->right; Forward
}
If the node is not found
if (!cur) return;
If the leaf node is deleted directly and the point of the predecessor node is changed to NULL
if (cur->left==null&&cur->right==null) {
if (cur==root)//If it happens to be the root node
Root=null;
else if (pre->left==cur)//Zuo
pre->left=null;
else//Right leaf
pre->right=null;
Delete cur;
///If the single son node is deleted and the predecessor node is changed to point to son node
else if (cur->left==null| | Cur->right==null) {
if (Cur==root)//root node
root=cur->left==null?cur->right:cur->left;
else if (pre->left==cur)//left son
pre->left=cur->left==null?cur->right:cur->left;
else//Right son
pre->right=cur->left==null?cur->right:cur->left;
Delete cur;
}//Two-son node
else {
Find the biggest in the left son.
Pre=cur;
Nodeptr p=pre->left;
Maximum on the far right
while (P->right) {
Pre=p;
p=p->right;
}
cur->val=p->val;
if (pre->left==p)
pre->left=null;
Else
pre->right=null;
Delete p;
}
}
/* Non-recursive pre-sequence traversal with stack implementation
For any node P:
1 Accessing the node p and putting the node p into the stack;
2 Determine if the left child of the node P is empty, if empty, then take the stack top node and carry out stack operation, and the top node of the stack of the right child into the current node p, loop to 1; if not empty, then P's left child is placed as the current node p;
3 until P is null and the stack is empty, the traversal ends.
*/
void Preorderprint () const{
if (root==null) return;
Stack<nodeptr> S;
Nodeptr Cur=root;
while (cur| |! S.empty ()) {
while (cur) {
cout<<cur->val<< ",";
S.push (cur);
cur=cur->left;
}
if (! S.empty ()) {
Cur=s.top (); S.pop ();
cur=cur->right;
}
}
cout<<endl;
}
/* Non-recursive sequential traversal with stack implementation
For any node p,
1 If the left child is not empty, the p is put into the stack and the left child of P is placed as the current p, then the current node p is treated the same;
2 If the left child is empty, take the top element of the stack and carry out stack operation, access the top node of the stack, and then put the current p as the stack top node of the right child;
3 until P is null and the stack is empty, the traversal ends
*/
void Inorderprint () const{
if (root==null) return;
Stack<nodeptr> S;
Nodeptr Cur=root;
while (cur| |! S.empty ()) {
while (cur)
{
S.push (cur);
cur=cur->left;
}
if (! S.empty ()) {//Access current node and right subtree into stack
Cur=s.top (); S.pop ();
cout<<cur->val<< ",";
cur=cur->right;
}
}
cout<<endl;
}
/*
Implementation of non-recursive sequence traversal using stack
To ensure that the root node is accessible to the left child and the right child, it is first put into the stack for any node p. If p does not exist for the left child and the right child, you can access it directly, or there is a left child or right child in P, but both the left and right children have been visited, and the node can be accessed directly.
In either case, the right child of P and the left child are sequentially placed in the stack, which ensures that every time the top element is taken, the left child is visited in front of the right child, and the left child and the right child are accessed before the root node.
*/
void Postorderprint () const {
if (root==null) return;
Stack<nodeptr> S;
Nodeptr Cur,pre=null; The current node and the previous Access node
S.push (root);
while (! S.empty ()) {
Cur=s.top ();
if ((cur->left==null&&cur->right==null) | | (pre!=null&& (pre==cur->left| | Pre==cur->right)))
{
cout<<cur->val<< ","; If the current node has no children or the child nodes have been visited
S.pop ();
Pre=cur;
}
Else
{
if (cur->right!=null)
S.push (Cur->right);
if (cur->left!=null)
S.push (Cur->left);
}
}
}
Private:
Nodeptr Root; Root node
};
int main (int argc, char* argv[])
{
BST BST;
Bst.insert (a); Bst.insert (2); Bst.insert (1); Bst.insert (122); Bst.insert (6);
Bst.insert (one); Bst.insert (3); Bst.insert (a); Bst.insert (30);
Bst.del (12);
Bst. Inorderprint ();
Bst. Preorderprint ();
Bst. Postorderprint ();
return 0;
}