zoukankan      html  css  js  c++  java
  • 二叉排序树节点的删除(C++,算法导论),前中后序遍历(递归/非递归,栈实现),按层次遍历(队列实现)

     由于代码中包含了二叉树,栈,队列三种结构的实现,为了文件结构更清晰,我会列出各文件名以及它们各自所实现的功能。
    

    栈和队列只是为二叉树而创建的,所以它们的头文件只是实现了最基本的函数,如压栈,出栈,入队列,出队列,获取节点元素……

    二叉树实现了节点插入和删除,数据搜索按照算法导论一书而来;先序,中序,后序的递归和非递归算法,非递归算法使用栈实现;按层次遍历用队列实现。

    栈,队列和二叉树均采用了类模板,而栈和队列的节点当中存放的是二叉树的节点,所以如果你想看懂下面的代码,最好知道类模板的用法。在完成这些代码之前,我对类模板还停留在一知半解的层面,但是完成了它们之后,才逐渐明白了一些类模板的妙处。
    栈的实现头文件:Stack.h

    #ifndef STACK_H_INCLUDED
    #define STACK_H_INCLUDED
    #include <iostream>
    using namespace std;
    template<class T>
    struct Stack_Node
    {
        T Date;
        Stack_Node* Next_Node;
        Stack_Node(T  date=0)
        {
            Date=date;
            Next_Node=NULL;
        }
    };
    template<class T>
    class Stack
    {
        int Node_Count;
        Stack_Node<T>* Top_Point;
    public:
        Stack(int node_count=0)
        {
            Node_Count=node_count;
            Top_Point=NULL;
        }
        ~Stack()
        {
            Clear_Stack();
        }
        Stack_Node<T>* Get_Top()
        {
            return Top_Point;
        }
        int Get_Node_count()
        {
            return Node_Count;
        }
        void Print_Stack()//从栈顶开始输出,测试所用函数
        {
            Stack_Node<T>*p=Top_Point;
            while(p!=NULL)
            {//如果不是系统定义类型,比如类,下句cout则无法输出。
                cout<<p->Date<<"  ";
                if(p->Next_Node==NULL)  return;
                p=p->Next_Node;
            }
        }
        void  Push_Stack_Node(T date)//节点入栈顶
        {
            Stack_Node<T>*p=new Stack_Node<T>(date);
            p->Next_Node=Top_Point;
            Top_Point=p;
            Node_Count++;
        }
        bool Popup_Stack_Node()//弹出栈顶节点
        {
            if(Node_Count<=0)  return false;
            Stack_Node<T>*p=Top_Point;
            Top_Point=Top_Point->Next_Node;
            delete p;
            Node_Count--;
        }
        T Get_Top_Date()//获取栈顶元素
        {
            return Top_Point->Date;
        }
            void Clear_Stack()//清空栈
        {
            for(int i=1; i<=Node_Count; i++)
            {
                Stack_Node<T>*p=Top_Point;
                Top_Point=Top_Point->Next_Node;
                delete p;
            }
            Node_Count=0;
        }
    };
    
    #endif // STACK_H_INCLUDED

    队列的实现:Queue.h

    #ifndef QUEUE_H_INCLUDED
    #define QUEUE_H_INCLUDED
    #include <iostream>
    using namespace std;
    template<class T>
    struct Queue_Node
    {
        T Date;
        Queue_Node* Next_Node;
        Queue_Node(T  date=0)
        {
            Date=date;
            Next_Node=NULL;
        }
    };
    template<class T>
    class Queue
    {
        int Node_Count;
        Queue_Node<T>* Head_Point;
        Queue_Node<T>* Tail_Point;
    public:
        Queue(int node_count=0)
        {
            Node_Count=node_count;
            Head_Point=NULL;
            Tail_Point=NULL;
        }
        ~Queue()
        {
            Clear_Queue();
        }
        Queue_Node<T>* Get_Head()
        {
            return Head_Point;
        }
        T Get_Head_Date()
        {
            return Head_Point->Date;
        }
        int Get_Node_count()
        {
            return Node_Count;
        }
        void Print_Queue()//队列的输出
        {
            Queue_Node<T>*p=Head_Point;
            while(p!=NULL)
            {
                cout<<p->Date<<"  ";
                if(p->Next_Node==NULL)  return;
                p=p->Next_Node;
            }
        }
        void  Push_Queue_Node(T date)//队列尾部插入元素
        {
    
            Queue_Node<T>*p=new Queue_Node<T>(date);
            if(Node_Count==0)
            {
                Head_Point=p;
                Tail_Point=p;
                Node_Count++;
                return;
            }
            Tail_Point->Next_Node=p;
            Tail_Point=Tail_Point->Next_Node;
            Node_Count++;
        }
        bool Popup_Queue_Node()//队列头部插入元素
        {
            if(Node_Count<=0)  return false;
            Queue_Node<T>*p=Head_Point;
            Head_Point=Head_Point->Next_Node;
            delete p;
            Node_Count--;
        }
        void Clear_Queue()//清空队列
        {
            for(int i=1; i<=Node_Count; i++)
            {
                Queue_Node<T>*p=Head_Point;
                Head_Point=Head_Point->Next_Node;
                delete p;
            }
            Node_Count=0;
        }
    };
    #endif // QUEUE_H_INCLUDED

    二叉树的实现:Bnary_Trees.h

    #ifndef BINARY_TREES_H_INCLUDED
    #define BINARY_TREES_H_INCLUDED
    #include <iostream>
    #include"Stack.h"
    #include"Queue.h"
    using namespace std;
    template<class T>
    struct Trees_node
    {
        T Date;
        Trees_node* Left_Children;
        Trees_node* Right_Children;
        Trees_node(T date=0)
        {
            Date=date;
            Left_Children=NULL;
            Right_Children=NULL;
        }
    };
    template<class T>
    class Binary_Trees
    {
        Trees_node<T>  *Root_Point;
    public:
        Binary_Trees(T date=0)
        {
            Root_Point=new Trees_node<T>(date);
        }
        Trees_node<T> * Get_Root()
        {
            return Root_Point;
        }
        T Get_Date(Trees_node<T> *node)
        {
            return node->Date;
        }
        //获得子二叉树的最小值的指针
        Trees_node<T>* Get_Minimum(Trees_node<T>* p)
        {
            while(p->Left_Children!=NULL)
            {
                p=p->Left_Children;
            }
            return p;
        }
        //获得子二叉树的最大值的指针
        Trees_node<T>* Get_Maximum(Trees_node<T>* p)
        {
            while(p->Right_Children!=NULL)
            {
                p=p->Right_Children;
            }
            return p;
        }
        //先序遍历递归算法
        void Pre_Print_Trees_Re(Trees_node<T> *node)
        {
            if(node)
            {
                cout<<node->Date<<"  ";
                Pre_Print_Trees_Re(node->Left_Children);
                Pre_Print_Trees_Re(node->Right_Children);
            }
        }
        //先序遍历非递归算法,栈实现
        void Pre_Print_Trees()
        {
            Trees_node<T>*p=Root_Point;
            Stack<Trees_node<int>*>  Pre;
            while(p!=NULL||Pre.Get_Node_count())
            {
                if(p!=NULL)
                {
                    cout<<p->Date<<"  ";
                    Pre.Push_Stack_Node(p);
                    p=p->Left_Children;
                }
                else
                {
                    p=Pre.Get_Top_Date();
                    Pre.Popup_Stack_Node();
                    p=p->Right_Children;
                }
            }
        }
        //中序遍历递归算法
        void In_Print_Trees_Re(Trees_node<T> *root_node)
        {
            if(root_node)
            {
                In_Print_Trees_Re(root_node->Left_Children);
                cout<<root_node->Date<<"  ";
                In_Print_Trees_Re(root_node->Right_Children);
            }
        }
         //中序遍历非递归算法,栈实现
        void In_Print_Trees()
        {
            Trees_node<T>*p=Root_Point;
            Stack<Trees_node<int>*>  In;
            while(p!=NULL||In.Get_Node_count())
            {
                if(p!=NULL)
                {
                    In.Push_Stack_Node(p);
                    p=p->Left_Children;
                }
                else
                {
                    p=In.Get_Top_Date();
                    In.Popup_Stack_Node();
                    cout<<p->Date<<"  ";
                    p=p->Right_Children;
                }
    
            }
        }
         //后序遍历递归算法
        void Post_Print_Trees_Re(Trees_node<T> *root_node)
        {
            if(root_node)
            {
                In_Print_Trees_Re(root_node->Left_Children);
                In_Print_Trees_Re(root_node->Right_Children);
                cout<<root_node->Date<<"  ";
            }
        }
        //后序遍历非递归算法,栈实现
        void Post_Print_Trees()
        {
            Stack<Trees_node<int>*>  Post,Read;
            Post.Push_Stack_Node(Root_Point);
            while (Post.Get_Node_count())
            {
                Trees_node<T> *p = Post.Get_Top_Date();
                Post.Popup_Stack_Node();
                Read.Push_Stack_Node(p);//逆序压入栈中
                if (p->Left_Children) Post.Push_Stack_Node(p->Left_Children);
                if (p->Right_Children) Post.Push_Stack_Node(p->Right_Children);
            }
            while(Read.Get_Node_count())
            {
                cout<<Get_Date(Read.Get_Top_Date())<<"   ";
                Read.Popup_Stack_Node();
            }
        }
        //按层次遍历,队列实现
        void  Layer_Print_Trees()
        {
            if (Root_Point == NULL) return ;
    
            Trees_node<T> *p = Root_Point;
            Queue<Trees_node<T> *> Layer;
            Layer.Push_Queue_Node(p);
            while(Layer.Get_Node_count())
            {
                p=Layer.Get_Head_Date();
                Layer.Popup_Queue_Node();
                cout<<p->Date<<"  ";
                if (p->Left_Children) Layer.Push_Queue_Node(p->Left_Children);
                if (p->Right_Children) Layer.Push_Queue_Node(p->Right_Children);
            }
        }
        //搜索数据的递归方法
        Trees_node<T>* Search_Node_Re(Trees_node<T> *root_node,T date)
        {
            if(root_node==NULL||root_node->Date==date)
                return  root_node;
            if(date<root_node->Date)    return  Search_Node(root_node->Left_Children,date);
            else   return  Search_Node(root_node->Right_Children,date);
        }
        //搜索数据的非递归方法
        Trees_node<T>* Search_Node(Trees_node<T> *root_node,T date)
        {//如果没有找到节点,返回空的指针,可以用于bool判断
            while(root_node!=NULL&&root_node->Date!=date)
            {
                if(date<root_node->Date)  root_node=root_node->Left_Children;
                else  root_node=root_node->Right_Children;
            }
            return root_node;
        }
        bool Insert_Node(T date)
        {
            Trees_node<T> *q,*p,*r;
            p=new Trees_node<T>(date);
            q=NULL;
            r=Root_Point;
            while(r!=NULL)
            {
                q=r;
                if(date<r->Date) r=r->Left_Children;
                else if(date>r->Date) r=r->Right_Children;
                else//if(date=r->Date)
                    return false;
            }
            if(q==NULL) Root_Point=p;
            else if(date<q->Date)  q->Left_Children=p;
            else q->Right_Children=p;
            return true;
        }
        //删除节点的辅助函数
        void Trans_Plant(Trees_node<T> *delete_parent,Trees_node<T> *delete_node,Trees_node<T> * replace_node)
        {
            if(delete_parent==NULL)  Root_Point=replace_node;
            else if(delete_node==delete_parent->Left_Children)
                delete_parent->Left_Children=replace_node;
            else //if(delete_node==delete_parent->Right_Children)
                delete_parent->Right_Children=replace_node;
    
        }
        //删除节点是根据算法导论而写,四种情况的分析
        bool  Delete_Node(T date)
        {
            Trees_node<T> *delete_parent=NULL;
            Trees_node<T> *delete_node=Root_Point;
            Trees_node<T> *replace_parent;
            Trees_node<T> *replace_node;
            while(delete_node!=NULL&&delete_node->Date!=date)//查找删除节点以及它的双亲节点
            {
    
                delete_parent=delete_node;
                if(date<delete_node->Date)  delete_node=delete_node->Left_Children;
                else  delete_node=delete_node->Right_Children;
            }
            if(!delete_node)  return false;//如果没有该节点,返回Error
    
            if(delete_node->Left_Children==NULL)//处理了两种情况,无孩子和只有右孩子
                Trans_Plant(delete_parent,delete_node,delete_node->Right_Children);
            else if(delete_node->Right_Children==NULL)//处理只有左孩子的情况
                Trans_Plant(delete_parent,delete_node,delete_node->Left_Children);
            else   //if(delete_node->Left_Children!=NULL&&delete_node->Left_Children!=NULL)
            {//处理有左右孩子的情况
                replace_node=delete_node->Right_Children;
                replace_parent=delete_node;
                while(replace_node->Left_Children!=NULL)//代替被删除节点只能是它的前驱节点或者后继节点,
                {          //这儿查找它的后继节点作为替补,前驱和后继指的是中序遍历的前后节点
                    replace_parent=replace_node;
                    replace_node=replace_node->Left_Children;
                }
                if(delete_node!=replace_parent)  //替换节点不是删除节点的孩子节点
                {
                    Trans_Plant(delete_parent,replace_node,replace_node->Right_Children);
                    replace_node->Right_Children=delete_node->Right_Children;
                }
                Trans_Plant(delete_parent,delete_node,replace_node);
                replace_node->Left_Children=delete_node->Left_Children;
            }
            return  true;
        }
    };
    
    
    
    #endif // BINARY_TREES_H_INCLUDED
    

    测试文件如下:main.cpp

    #include <iostream>
    #include"Binary_Trees.h"
    using namespace std;
    int main()
    {
        cout<<"二叉树的测试如下:"<<endl<<endl;
        Binary_Trees< int> Test(5);
        Test.Insert_Node(4);
        Test.Insert_Node(6);
        Test.Insert_Node(9);
        Test.Insert_Node(7);
        Test.Insert_Node(8);
        Test.Insert_Node(2);
        Test.Insert_Node(9);
        Test.Insert_Node(10);
        Test.Insert_Node(3);
        Test.Insert_Node(1);
       Test.Layer_Print_Trees();
        cout<<endl;
        if(Test.Search_Node(Test.Get_Root(),3))
        {
            cout<<"Find!";
        }
        else
        {
            cout<<"Not Find!";
        }
        cout<<Test.Get_Date(Test.Get_Maximum(Test.Get_Root()));
        cout<<endl;
        Test.Delete_Node(1);
       //  Test.In_Print_Trees_Re(Test.Get_Root());
         cout<<endl;
         cout<<Test.Get_Date(Test.Get_Root());
          cout<<endl;
         cout<<"栈的测试如下:"<<endl<<endl;
         Stack<int> Test1;
         Test1.Push_Stack_Node(1);
         Test1.Push_Stack_Node(2);
         Test1.Push_Stack_Node(4);
         Test1.Print_Stack();
         cout<<endl;
         Test1.Popup_Stack_Node();
     //  Test1.Popup_Stack_Node();
     //  Test1.Popup_Stack_Node();
     //Test1.Clear_Stack();
     cout<<Test1.Get_Top_Date();
         Test1.Print_Stack();
         cout<<endl;
         cout<<"队列的测试如下:"<<endl<<endl;
         Queue<int> Test2;
         Test2.Push_Queue_Node(5);
         Test2.Push_Queue_Node(8);
         Test2.Push_Queue_Node(9);
         Test2.Print_Queue();
         cout<<endl;
        Test2.Popup_Queue_Node();
      //  Test2.Print_Queue();
      //  Test2.Clear_Queue();
        Test2.Push_Queue_Node(8);
        Test2.Push_Queue_Node(5);
         Test2.Push_Queue_Node(8);
         Test2.Push_Queue_Node(9);
      //   Test2.Clear_Queue();
        Test2.Print_Queue();
         cout<<endl;
        return 0;
    }
  • 相关阅读:
    流浪西邮之寻找火石碎片
    给你一个666
    似魔鬼的步伐
    括号匹配2019
    挑剔程度
    到底有到少个小和尚?
    获取任务栏所有正在运行程序
    EXTJS4创建多级菜单
    关于时间的一些理解
    kof97调隐藏人物
  • 原文地址:https://www.cnblogs.com/lizijuna/p/11907436.html
Copyright © 2011-2022 走看看