【数据结构&&算法】树,支持无限子节点
【数据机构和算法】章节中的【树】,一直都觉得比较难。
使用C++语言用类进行了封装,以便于今后学习!
首先,定义了树的节点类
// TreeNode.h: interface for the TreeNode class.
// 树的节点 NODE
// 根节点 子节点链表
// 2011-12-16 chen ang
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_TREENODE_H__C6FD71B8_0809_43C0_B6C3_E6B7B5B032D2__INCLUDED_)
#define AFX_TREENODE_H__C6FD71B8_0809_43C0_B6C3_E6B7B5B032D2__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <deque>
using namespace std;
template<class T>
class TreeNode
{
private:
T m_element; //节点数据域
deque<TreeNode<T>* > m_deque_child; //子节点指针--队列存储
TreeNode<T>* m_pParent; //父节点指针
public:
//默认的构造函数
TreeNode()
{
memset(&m_element, 0, sizeof(T));
m_deque_child.clear();
m_pParent = NULL;
};
//析构函数
virtual ~TreeNode(){m_deque_child.clear();};
//传参的构造函数
TreeNode(const T& element)
{
m_element = element;
m_deque_child.clear();
m_pParent = NULL;
};
//设置当前节点的内容
void SetValue(const T &element)
{
m_element = element;
}
//设置当前节点的父节点
void SetParent(TreeNode<T>* p)
{
if (!IsChildAlready(this, p))
{
//设置当前节点的父节点
m_pParent = p;
//同时将父节点的子节点数,递增
p->SetChild(this);
}
};
//添加当前节点的子节点
void SetChild(TreeNode<T>* c)
{
m_deque_child.push_back(c);
};
//检查当前节点是否为父节点的子节点:已是子节点返回true;否返回false.
bool IsChildAlready(TreeNode<T>* child,TreeNode<T>* parent)
{
if (child != NULL && child->m_pParent == parent)
{
return true;
}
else
{
return false;
}
// if (!parent->IsLeaf())
// {
// for (size_t i=0; i<parent->GetChildSize(); i++)
// {
// if (child == parent->GetChild(i))
// {
// return true;
// }
// }
// }
// return false;
}
//判断当前是否为叶节点
bool IsLeaf() const
{
return m_deque_child.empty();
};
//获取节点内容
void DisplayValue() const
{
cout<<GetValue()<<" ";
};
//返回当前节点内容
T GetValue() const
{
return m_element;
}
//获取当前节点的父节点
TreeNode<T>* GetParent()
{
return m_pParent;
};
//获取当前节点的子节点数目
size_t GetChildSize()
{
return static_cast<size_t>(m_deque_child.size());
};
//获取当前节点的子节点数目
TreeNode<T>* GetChild(size_t s)
{
return m_deque_child.at(s);
};
};
#endif // !defined(AFX_TREENODE_H__C6FD71B8_0809_43C0_B6C3_E6B7B5B032D2__INCLUDED_)
其次:定义和实现了树
// Tree.h: interface for the Tree class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_TREE_H__557440FC_9DAA_415B_9496_D5B2706D4621__INCLUDED_)
#define AFX_TREE_H__557440FC_9DAA_415B_9496_D5B2706D4621__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "TreeNode.h"
template<class T>
class Tree
{
private:
TreeNode<T>* m_root; //树的根节点
public:
//默认的构造函数
Tree(){m_root=NULL};
//传参的构造函数
Tree(const T& element){m_root = new TreeNode<T>(element);};
//析构函数
virtual ~Tree(){DeleteTree(m_root);};
public:
//判断树是否为空:空返回true; 非空返回false.
bool IsEmpty() const
{
return ((m_root==NULL) ? true : false);
};
//返回树的根节点
TreeNode<T>* GetRoot() const
{
return m_root;
};
//打印节点数据
void DisplayValue(TreeNode<T>* node)
{
if (node)
{
cout<<"值等于"<<node->GetValue()<<endl;
}
else
{
cout<<"该节点为NULL!"<<endl;
}
}
//前序遍历
void PreOrder(TreeNode<T>* root)
{
if (NULL != root)
{
root->DisplayValue();
if (!root->IsLeaf())
{
for (size_t i=0; i<root->GetChildSize(); i++)
{
PreOrder(root->GetChild(i));
}
}
}
}
//后序遍历
void PostOrder(TreeNode<T>* root)
{
if (NULL != root)
{
if (!root->IsLeaf())
{
for (size_t i=0; i<root->GetChildSize(); i++)
{
PreOrder(root->GetChild(i));
}
}
if (root)
{
root->DisplayValue();
}
}
}
//删除树或其子树
void DeleteTree(TreeNode<T>* root)
{
//后序周游二叉树或其子树
if (root)
{
for (size_t i=0; i<root->GetChildSize(); i++)
{
DeleteTree(root->GetChild(i));
}
delete root; //删除根节点
root = NULL;
}
};
};
#endif // !defined(AFX_TREE_H__557440FC_9DAA_415B_9496_D5B2706D4621__INCLUDED_)
最后,就是对树进行数据录入,测试。
// 树.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Tree.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
//构造了一棵树
Tree<int> tree(0);
TreeNode<int>* pNode;
pNode = new TreeNode<int>(1);
pNode->SetParent(tree.GetRoot());
pNode = new TreeNode<int>(2);
pNode->SetParent(tree.GetRoot());
pNode = new TreeNode<int>(3);
pNode->SetParent(tree.GetRoot());
pNode = new TreeNode<int>(4);
pNode->SetParent(tree.GetRoot());
pNode = new TreeNode<int>(5);
pNode->SetParent(tree.GetRoot()->GetChild(0));
pNode = new TreeNode<int>(11);
pNode->SetParent(tree.GetRoot()->GetChild(0));
pNode = new TreeNode<int>(6);
pNode->SetParent(tree.GetRoot()->GetChild(2));
pNode = new TreeNode<int>(7);
pNode->SetParent(tree.GetRoot()->GetChild(1));
pNode = new TreeNode<int>(10);
pNode->SetParent(tree.GetRoot()->GetChild(2)->GetChild(0));
pNode = new TreeNode<int>(9);
pNode->SetParent(tree.GetRoot()->GetChild(2)->GetChild(0));
pNode = new TreeNode<int>(8);
pNode->SetParent(tree.GetRoot()->GetChild(2)->GetChild(0));
cout<<"树进行前序遍历:";
tree.PreOrder(tree.GetRoot());
cout<<endl<<"树进行后序遍历:";
tree.PostOrder(tree.GetRoot());
cout<<endl<<endl;
return 0;
}
总结:测试结果,输出数据,截图。