您的位置:首页 > 编程语言 > C语言/C++

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

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


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

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

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

栈的实现头文件: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息