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

原创 2016年05月31日 20:08:32
 由于代码中包含了二叉树,栈,队列三种结构的实现,为了文件结构更清晰,我会列出各文件名以及它们各自所实现的功能。

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

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

栈,队列和二叉树均采用了类模板,而栈和队列的节点当中存放的是二叉树的节点,所以如果你想看懂下面的代码,最好知道类模板的用法。在完成这些代码之前,我对类模板还停留在一知半解的层面,但是完成了它们之后,才逐渐明白了一些类模板的妙处。
栈的实现头文件: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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

二叉树前中后序遍历的递归版本和非递归版本、队列实现的层次遍历

/* 数据结构分析与学习专栏 * Copyright (c) 2015, 山东大学 计算机科学与技术专业 学生 * All rights reserved. * 作 者: 高祥...

二叉树的非递归前序、中序以及后序遍历C++模版类实现

#include using namespace std; //////////////////////////////////////////////////////////////////...

二叉树的非递归前序、中序以及后序遍历C++模版类实现

#include using namespace std; //////////////////////////////////////////////////////////////////...

二叉树第K层的第M个节点 -- 采用非递归层次遍历实现

/*二叉树第K层的第M个节点 -- 采用非递归层次遍历实现 经调试可运行源码及分析如下: ***/ #include #include #include using std::cout; usin...

【算法导论】二叉树的前中后序非递归遍历实现

二叉树的非递归遍历

二叉树的建立及层次遍历及前中后序遍历递归与非递归的实现

该例主要展示Java实现二叉树,并实现二叉树的先序、中序和后序遍历 public class Node { private int value; private Node left; priv...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)