话不多说直接上代码 超级详细只能说~
- 首先我们定义和初始化一个数
struct TreeNode {
DataType data;//这个Datatype 自己定义就好了
TreeNode *LChild;
TreeNode *RChild;
TreeNode (DataType Value)//这个是结构体里面的函数 用于给这个节点赋值
{
data = Value;
LChild = NULL;
RChild = NUll;
}
};
typedef TreeNode* LinkTreeNode;
- 然后我们选择将我们 要用的函数封装在 一个类里面
class CTree
{
public:
LinkTreeNode pRoot;
public:
CTree() {
cout<<"无参构造函数"<<endl;
}
CTree( DataType value) {
pRoot = new TreeNode(value);
if(pRoot == NULL)
return ;
}
~CTree() ;
public:
//插入左元素
void Insert(DataType parentValue,DataType Value);
// 插入右元素
void InsertRight(LinkTreeNode LinkparentNode,DataType value);
//查找元素
LinkTreeNode Search(LinkTreeNode Node,DataType value);
//先序遍历
void Perorder(LinkTreeNode Node);
//中序遍历
void Inorder(LinkTreeNode Node);
//后序遍历
void Postorder(LinkTreeNode Node);
//打印节点中的值
void CoutNode(LinkTreeNode Node);
//释放空间
void FreeMemory(LinkTreeNode Node);
};
这些事我们要用的所有函数,下次写别的提的时候调过去,直接删减就可以了
接下来我们写这里面的函数
- 首先我们把这个 Free 函数给他搞掉
void CTree::FreeMemory(LinkTreeNode Node)
{
//如果说节点为空就直接退出去
if(Node == NULL)
return ;
//如果第一个不为空 释放第一个
if(Node->LChild !=NULL) FreeMemory(Node->LChild);
//一样的 哪个不为空就释放哪一个
if(Node->RChild !=NULL ) FreeMemory(Node->RChild);
//删掉这个节点
delete Node;
//让他指向空
Node = NULL;
}
- 接下来我们顺便把这个析构函数也给他写了
CTree::~CTree(){
if(pRoot == NULL) return ;
FreeMemory(pRoot);
}
- 接下来就是一些重头戏了,最先来的是我们的插入函数
void CTree::Insert(DataType parentValue,DataType Value) {
// 我们决定在 parentValue 后面插入value
if(pRoot == NULL ) return ;
//创建一个NODE 来接受我们找到的这个父亲节点
LinkTreeNode FindNode = Search(pRoot,parentValue);
//如果说没有找到 就直接return出去
if(FindNode==NULL) return ;
//如果说左边的孩子为空就直接插入 反之 插入到右边
if(FindNode->LChild == NULL)
{
FindNode->LChild = new TreeNode(Value);
return ;
}
else
{
InsertRight(FindNode->LChild,value);
//这个函数是我们后面将要写的
return ;
}
}
void CTree::InsertRight(LinkTreeNode LinkparentNode,DataType value)
{
if(pRoot == NULL) return ;
if(LinkparentNode->RChild != NULL )
{
InsertRight(LinkparentNode->RChild,value);
}
else
{
LinkparentNode->RChild = new TreeNode(value);
}
}
我们为什么不用一个函数来插入是因为这个就可以不光给二叉树插入这种思想
就是我们发现第一个儿子不为空之后就找第一个儿子右边的儿子是否为空,右边的儿子不为空就继续这样找下去,找到了就插入,没找到,就返回出来
- 在树中以Node为根来查找这个元素value的位置
LinkTreeNode CTree::Search(LinkTreeNode Node,DataType value)
{
//如果说这个节点是空的 就直接返回出去
if(Node == NULL) return NULL ;
//如果不为空
//1.如果这个数正好在这个数的根部位置 所以 就直接指向这个数
if(Node->data == value) return pRoot;
//2.如果说这个树只有一个根部的元素
if(Node->LChild ==NULL && Node->RChild == NULL)
return NULL;//没有找到 return 出去
else
{
//注意这个里面就需要好好地理解一下
//如果说这个树的 第一个孩子不为空
if(Node->LChild != NULL)
{
//定义一个节点来接收我们再次查找这个值得结果
LinkTreeNode NodeTemp = Search(Node->LChild,value);
//如果说这个节点找到了 也就是不为空 那么这个就是我们要找的点 以此类推
if(NodeTemp != NULL) return NodeTemp;
else {
return Search(Node->RChild,value);
}
}
else
{
return Search(Node->RChild,value);
}
}
}
接下来就是几个遍历
- 先序遍历
void CTree::Perorder(LinkTreeNode Node)
{
//如果是空树 直接return出去
if(Node == NULL) return ;
//如果不为空 先把这个根部给他输出来
cout<<' '<<Node->data<<' ';
//接着是一样的思想 在函数里面调用函数
Perorder(Node->LChild);
Perorder(Node->RChild);
}
- 中序遍历
void CTree::Inorder(LinkTreeNode Node)
{
//还是判断是否为空树
if(Node==NULL) return ;
//一样的 按照先序遍历的规则输出循环调用就可以了
Inorder(Node->LChild);
cout<<' '<<Node->data<<' ';
Inorder(Node->RChild);
}
- 后序遍历
void CTree::Postorder(LinkTreeNode Node)
{
//哎 小编都累了 哈哈哈哈 看到这里了就给个小赞吧
//还是判断是否为空啦
if(Node== NULL) return ;
//一样的循环操作了
Postorder(Node->LChild);
Postorder(Node->RChild);
}
最后大家一起加油努力,做一个放荡不羁热爱生活的码皇