自己编的一个二叉搜索树的综合操作

          自己编的一个二叉搜索树的综合操作,感觉程序挺经典的。基本上二叉搜索树的各种操作都有了,不过还少一个二叉搜索树的后序非递归遍历。
#include  < iostream >
#define  max 10
using   namespace  std;
struct  BinTreeNode                                                                              // 二叉查找树的节点结构体
{
    
int m_data;
    
struct BinTreeNode *lchild, *rchild;
    BinTreeNode(
int item, BinTreeNode *left = NULL, BinTreeNode *right = NULL)
        : m_data(item), lchild(left), rchild(right) 
                                                                         
//构造函数默认的lchild,rchild为NULL
    {
    }

}
;

struct  MyQueue                    // 用于层次遍历的队列
{
    BinTreeNode 
*array[max];                                              //定义一个指针数组作为队列用于保存指向节点的指针
    int front, rear;                                                                  //int型的队首指针和队尾指针
    MyQueue()
    
{
        front 
= rear = 0;
    }

}
;

class   BinaryTree                                                                                   // 二叉搜索树类
{

private:
    BinTreeNode 
*root;   //根节点指针

public:
    BinaryTree()
    
{
        root 
= NULL;
    }

    
    
void Insert(const int node)                //迭带插入的方法建二叉搜索树
                                            
//ptr必须为根节点指针的引用                    
    {                                     
        BinTreeNode 
*currentpointer;        //当前节点指针  
        BinTreeNode *parentpointer;                         //父亲节点指针    
        BinTreeNode *newpointer; 
        
        BinTreeNode 
*ptr = root;
        newpointer 
= new BinTreeNode(node);                          //新动态分配一个节点
        
        
/*BinTreeNode *&ptr = root;        //或者这样写也行但必须使用指针的引用
        if(ptr == NULL)                        
        {
            ptr = newpointer;
        }
*/


        
if(root == NULL)                                                              //如果此时树为空,返回新开辟的节点
        {
            root 
= newpointer;
        }

        
else
        
{
            currentpointer 
= ptr;        //保存root指针
            while(currentpointer != NULL)    //当当前节点不为空的情况下
            {
                parentpointer 
= currentpointer; //用指向父亲节点的指针保存当前指针

                
if(currentpointer->m_data > node)
                
{
                    currentpointer 
= currentpointer->lchild;
                }

                
else
                
{
                    currentpointer 
= currentpointer->rchild;
                }

            }
  //一直移动到是使parentpointer指向叶子节点而currentpointer为NULL
               
//以下是将节点插入
            if(parentpointer->m_data > node)
            
{
                parentpointer
->lchild = newpointer;
            }

            
else
            
{
                parentpointer
->rchild = newpointer;
            }

        }

    }


    BinTreeNode 
*Creat(int data[],int len) //依次插入
    {
        
for(int i=0; i<len; i++)
        
{
            Insert(data[i]);
        }

        
return root;
    }

    
    
void PreOrder()
    
{
        cout
<<"前序遍历的结果为:"<<endl;
        PrePrint(root);
    }


    
void preOrder()    //前序非递归遍历
    {
        BinTreeNode 
*stack[50];  //定义一个指针数组作为堆栈
        BinTreeNode *= root;   //定义一个节点指针初始化指向头节点
        int top = 0;
        cout
<<endl<<"前序非递归遍历:"<<endl;
        
while(p != NULL || top > 0
        
{
            
while(p != NULL)
            
{
                cout
<<p->m_data<<" ";
                stack[top
++= p;  //p入栈
                p = p->lchild;
            }

            p 
= stack[--top];       //p出栈
            p = p->rchild;
        }

    }


    
void InOrder()
    
{
        cout
<<endl;
        cout
<<"中序遍历的结果为:"<<endl;
        InPrint(root);
    }


    
void inOrder()    //中序非递归遍历
    {
        BinTreeNode 
*stack[50];  //定义一个指针数组作为堆栈
        BinTreeNode *= root;   //定义一个节点指针初始化指向头节点
        int top = 0;

        cout
<<endl<<"中序非递归遍历:"<<endl;
        
while(p != NULL || top > 0
        
{
            
while(p != NULL)
            
{
                stack[top
++= p;  //p入栈
                p = p->lchild;
            }

            p 
= stack[--top];       //p出栈
            cout<<p->m_data<<" ";
            p 
= p->rchild;
        }

    }


    
void PostOrder()
    
{
        cout
<<endl;
        cout
<<"后序遍历的结果为:" <<endl;
        PostPrint(root);
    }


    
void Count()
    
{
        cout
<<endl;
        cout
<<"叶子节点数为:"<<CountLeafs(root)<<endl;
    }


    
void PrePrint(BinTreeNode *p) //前序遍历
    {
        
if(p != NULL)
        
{
            cout 
<< p->m_data << ',';
            PrePrint(p
->lchild);
            PrePrint(p
->rchild);
        }

    }


    
void InPrint(BinTreeNode *p)  //中序遍历
    {
        
if(p != NULL)
        
{
            InPrint(p
->lchild);
            cout
<< p->m_data<<',';
            InPrint(p
->rchild);
        }

    }

    
    
    
void PostPrint(BinTreeNode *p)  //后序遍历
    {
        
if(p != NULL)
        
{
            PostPrint(p
->lchild);
            PostPrint(p
->rchild);
            cout
<< p->m_data<< ',';
        }

    }


    
void LevelOrder()   //层次遍历
    {
        cout
<<endl<<"层次遍历:"<<endl;
        MyQueue queue;
        BinTreeNode 
*temp = root;                                      //一个指向头节点的指针temp

        
if(temp != NULL)
            cout
<<root->m_data<<" ";

        queue.array[queue.rear] 
= temp;                                  //头节点指针入队列
        queue.rear = (queue.rear + 1% max;                         //rear尾指针加一 

        
while(queue.front <= queue.rear)                                   //当队列不空
        {
            temp 
= queue.array[queue.front];
            queue.front 
= (queue.front + 1% max;   //对首元素出队列

            
if(temp->lchild != NULL)                           //如果有左孩子
            {
                cout
<<temp->lchild->m_data<<" ";       //打印左孩子
                queue.array[queue.rear] = temp->lchild; //左孩子入队列
                queue.rear = (queue.rear + 1% max;
            }

            
if(temp->rchild != NULL)                                 //如果有右孩子
            {
                cout
<<temp->rchild->m_data<<" ";       //打印右孩子
                queue.array[queue.rear] = temp->rchild; //右孩子入队列
                queue.rear = (queue.rear + 1% max;
            }

            
        }

    }


    BinTreeNode 
* Find(const int &c)  //用迭带的方法寻找特定的节点
    {
        BinTreeNode 
*pCurrent = root;
        
if(pCurrent  != NULL)
        
{
            
while(pCurrent  != NULL)
            
{
                
if(pCurrent->m_data == c)
                
{
                    
return pCurrent;
                }

                
else 
                
{
                    
if(c > pCurrent->m_data)
                        pCurrent  
= pCurrent->rchild;
                    
else
                        pCurrent  
= pCurrent ->lchild;
                }

            }

        }

        
return NULL;
    }

    
    
bool DeleteBT(const int &key)   //删除节点的函数定义
    {
        BinTreeNode 
*q, *s;
        BinTreeNode 
*current = root; //找到要删除的节点
        BinTreeNode *prt = NULL;    //current的父亲节点

        
while ((NULL != current) && (current->m_data != key))
                                   
//通过查找找到值为key的节点和它的父亲节点
        {
            prt 
= current;
              
             
if (current->m_data > key)
                     current 
= current->lchild;
             
else
                     current 
= current->rchild;
        }


        
if(current == NULL) //current为NULL说明节点不存在
        {
            cout
<<"没有此节点!"<<endl;
            
return false;
        }

        
if(current->lchild == NULL && current->rchild == NULL)
                       
//当找到的节点即没有左孩子也没有右孩子
        {
            
if(current == root)
            
{
                root 
= NULL;
            }

            
else 
            
{
                
if(current == prt->lchild)
                
{
                    prt
->lchild = NULL;
                }

                
else
                
{
                    prt
->rchild = NULL;
                }

            }

        }

        
if(current->lchild == NULL && current->rchild != NULL)
                        
//当找到的节点有右孩子而没有左孩子
        {
            
if(current == root)
            
{
                current 
= current->rchild;
            }

            
else 
            
{
                
if(current == prt->lchild)  //如果当前节点是prt指向节点的左孩子
                {
                    prt
->lchild = current->rchild;
                }

                
else
                
{
                    prt
->rchild = current->rchild;
                }

            }

        }

        
if(current->rchild == NULL && current->lchild != NULL) 
                                        
//如果当前节点有左孩子而没有右孩子
        {
            
if(current == root)
            
{
                current 
= current->lchild;
            }

            
else
            
{
                
if(current == prt->lchild)
                
{
                    prt
->lchild = current->lchild;
                }

                
else
                
{
                    prt
->rchild = current->lchild;
                }

            }

        }


        
if(current ->lchild != NULL && current->rchild != NULL)//当前节点左右孩子都有
        {
            q 
= current;    //用q保存current节点指针
            s = current;    //s是current的前驱指针

            current 
= current->lchild;
            
//先向左走
            while(current->rchild) //然后向右走到尽头,其实就是寻找左子树当中最大的节点
            {                      //补充:寻找右子树当中最小的节点也是可以的
                s = current;       //s指向current的前驱
                current = current->rchild;
            }


            q
->m_data = current->m_data;  //用找到的节点替换当前节点
        
            
if(q != s)                    //将current节点从树中拆下来
                s->rchild = current->lchild;
            
else
                q
->lchild = current->lchild;
        }

        delete current;        
//释放current指向的空间
        current = NULL;
        
return true;
    }


    
void destroy(BinTreeNode *current) //销毁二叉树
    {
        
if(current != NULL)
        
{
            destroy(current
->lchild);
            destroy(current
->rchild);
            delete current;
            current 
= NULL;
        }

    }


    
int CountLeafs(BinTreeNode *current)
    
{
        
if(current == NULL)
        
{
            
return 0;
        }

        
else 
        
{
            
if( current->lchild == NULL  &&  current->rchild == NULL )
            
{
                
return 1;
            }

            
else
            
{
                
int num1 = CountLeafs(current->lchild);
                
int num2 = CountLeafs(current->rchild);
                
return (num1+num2);
            }

        }

    }


    
virtual  ~BinaryTree() 
    
{
        destroy(root);
    }

}
;
main()
{
    BinaryTree myTree;
    
int a[]={6347826901};
    myTree.Creat(a, max);  
//创建二叉搜索树
    myTree.PreOrder();     //先序遍历
    myTree.preOrder();    //前序非递归遍历
    myTree.InOrder();      //中序遍历
    myTree.inOrder();      //中序非递归遍历
    myTree.PostOrder();    //后序遍历
    myTree.LevelOrder();   //层次遍历
    myTree.Count();        //输出叶子节点的数目
    cout<<"输入你想要找的节点"<<endl;
    
int x;
    cin
>>x;
    
if(myTree.Find(x))     //进行查找
        cout<<"查找成功!"<<endl;
    
else
        cout
<<"查找失败!"<<endl;
    cout
<<"输入一个你想删除的节点: "<<endl;
    cin
>>x;
    
if(myTree.DeleteBT(x))  //进行删除
        cout<<"删除成功!"<<endl;
    
else
        cout
<<"删除失败!"<<endl;
    myTree.PreOrder();

}

你可能感兴趣的:(c,struct,null,Class,insert,iostream)