自己編的一個二叉搜索樹的綜合操作

          自己編的一個二叉搜索樹的綜合操作,感覺程序挺經典的。基本上二叉搜索樹的各種操作都有了,不過還少一個二叉搜索樹的後序非遞歸遍歷。
#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();

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章