树的子女-兄弟表示Tree
文章目录
主函数
#include "Tree.h"
#include <fstream>
#include <cassert>
#include <iomanip>
using namespace std;
void visit(TreeNode<int> * n){
cout << setw(4) << n->data;
}
int main(){
Tree<int> tree(0); //输入结束符为0
cout << "The Intended text of the tree is:\n";
ifstream fin("data.txt");
assert(fin);
fin >> tree;
fin.close();
cout << tree;
tree.Output();
cout << "\nThe preorder of the tree is:\n";
tree.PreOrder(visit);
cout << "\nThe levelorder of the tree is:\n";
tree.LevelOrder(visit);
cout << "\nThe postorder of the tree is:\n";
tree.PostOrder(visit);
cout << "\n\nPress enter to exit!\n";
char ch;
cin.get(ch);
return 0;
}
树结点类定义
template <typename T>struct TreeNode{
T data;
TreeNode<T> *firstChild, *nextSibling;
TreeNode(T value = 0, TreeNode<T> *fc = NULL, TreeNode<T> *ns = NULL)
:firstChild(fc), nextSibling(ns){
data = value;
}
};
Tree类定义
template <typename T>class Tree{
public:
Tree(){
root = current = NULL;
}
Tree(T value){
root = current = NULL;
RefValue = value;
}
bool Root(); //置根结点为当前结点
TreeNode<T> *getRoot(){
return root;
}
void setRoot(TreeNode<T> *rt){
root = rt;
}
bool IsEmpty(){
return root == NULL;
}
bool FirstChild(); //将当前结点的第一个子女置为当前结点
bool NextSibling(); //将当前结点的下一个兄弟置为当前结点
bool Parent(); //将当前结点的双亲置为当前结点
bool Find(T value); //搜索含value的结点,使之成为当前结点
void PreOrder(void (*visit)(TreeNode<T> *t)){//前序
TreeNode<T> *p = root;
while (p){
PreOrder(p, visit);
p = p->nextSibling;
}
}
void PostOrder(void (*visit)(TreeNode<T> *t)){//后序
TreeNode<T> *p = root;
while (p){
PostOrder(p, visit);
p = p->nextSibling;
}
}
void LevelOrder(void (*visit)(TreeNode<T> *t)){//层次
LevelOrder(root, visit);
}
//以先根次序输入树,以RefValue表示某结点没有子女或不再有兄弟
void CreateTree(istream &in = cin){
CreateTree(in, root);
}
void Output(ostream &out = cout){ //树状格式输出
Output(root, string(), out);
}
void IntendedText(ostream &out = cout){ //将树用网络文本形式输出
IntendedText(root, string(), out);//string()是构造函数
}
void ShowTree(ostream &out = cout){
ShowTree(root, out);
}
void reSetCurrent(){ //将current重新指向根节点
current = root;
}
friend istream& operator >> (istream &in, Tree<T> &tree)
{ tree.CreateTree(in,tree.root);
return in;
}; //tree不可误作Tree
friend ostream& operator << (ostream &out, Tree<T> &tree)
{ tree.IntendedText(out);
return out;
};
private:
TreeNode<T> *root, *current;
bool Find(TreeNode<T> *p, T value); //在以p为根的树中搜索value
void RemovesubTree(TreeNode<T> *subTree); //删除以p为根的子树
bool FindParent(TreeNode<T> *t, TreeNode<T> *p);
void PreOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t));
void PostOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t));
void LevelOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t));
void Output(TreeNode<T> *subTree, string str, ostream &out);
void IntendedText(TreeNode<T> *subTree, string str, ostream &out);
void ShowTree(TreeNode<T> *t, ostream &out);
void CreateTree(istream& in, TreeNode<T> *& subTree);
//以先根次序输入树,以RefValue表示某节点没有子女或不再有兄弟
T RefValue; //数据输入停止标志
};
Root
template <typename T> bool Tree<T>::Root(){
//让树的根节点成为当前节点
if (root == NULL){
current = NULL;
return false;
}
else{
current = root;
return true;
}
}
Parent与FindParent函数
template <typename T>bool Tree<T>::Parent(){
TreeNode<T> *p = current;
if (current == NULL || current == root){
current = NULL;
return false;
}
return FindParent(root, p);
}
template <typename T>bool Tree<T>::FindParent(TreeNode<T> *t, TreeNode<T> *p){
TreeNode<T> *q = t->firstChild;
while (q != NULL && q != p){
if (FindParent(q, p)){
return true;
}
q = q->nextSibling;
}
if (q != NULL && q == p){
current = t;
return true;
}
else{
current = NULL;
return false;
}
}
FirstChild函数
template <typename T>bool Tree<T>::FirstChild(){
if (current && current->firstChild){
current = current->firstChild;
return true;
}
current = NULL;
return false;
}
NextSibling
template <typename T> bool Tree<T>::NextSibling(){
if (current && current->nextSibling){
current = current->nextSibling;
return true;
}
current = NULL;
return false;
}
PreOrder函数
template <typename T>
void Tree<T>::PreOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t)){
if (subTree){
visit(subTree);
subTree = subTree->firstChild;
while (subTree){
PreOrder(subTree, visit);
subTree = subTree->nextSibling;
}
}
}
PostOrder函数
template <typename T>void Tree<T>::PostOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t)){
if (subTree){
TreeNode<T> *p = subTree;
p = p->firstChild;
while (p){
PostOrder(p, visit);
p = p->nextSibling;
}
visit(subTree);
}
}
LevelOrder 函数——层次遍历
Queue是先进先出的。
template <typename T>void Tree<T>::LevelOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t)){
SeqQueue<TreeNode<T>*> Q;
if (subTree){
while (subTree){
Q.EnQueue(subTree);
subTree = subTree->nextSibling;
}
while (!Q.IsEmpty()){
Q.DeQueue(subTree);
visit(subTree);
subTree = subTree->firstChild;
while (subTree){
Q.EnQueue(subTree);
subTree = subTree->nextSibling;
}
}
}
}
Find函数
template <typename T>bool Tree<T>::Find(T value){
if (IsEmpty()){
return false;
}
return Find(root, value);
}
template <typename T>bool Tree<T>::Find(TreeNode <T> *p, T value){
bool result = false;
if (p->data == value){
result = true;
current = p;
}
else{
TreeNode<T> *q = p->firstChild;
while (q != NULL && !(result = Find(q, value))){
//第一层递归进去还会继续向孩子结点递归,全部找不到才会继续滑翔nextSibling,找到了直接返回
q = q->nextSibling;
}
}
return result;
}
RemovesubTree函数
template<typename T>void Tree<T>::RemovesubTree(TreeNode<T> *subTree){ //若指针subTree不为空,则删除根为subTree的子树
if (subTree){
RemovesubTree(subTree->firstChild);
RemovesubTree(subTree->nextSibling);
delete s`在这里插入代码片`ubTree;
}
}
IntendedText 函数
template <typename T>void Tree<T>::IntendedText(TreeNode<T> *subTree, string str, ostream &out){
TreeNode<T> *p = subTree;
while (p){
cout << str << p->data << endl;
string temp = str + string("\t");
if (p->firstChild){
IntendedText(p->firstChild, temp, out);
}
p = p->nextSibling;
}
}
🌰:
The Intended text of the tree is:
1
2
3
4
5
6
7
8
9
10
11
Output函数
//公有函数
void Output(ostream &out = cout){ //树状格式输出
Output(root, string(), out); //string()是构造函数,一开始为空
}
template <typename T>void Tree<T>::Output(TreeNode<T> *subTree, string str, ostream &out){ //私有函数,调用Output必传入root
if (subTree == root){
current = root;
}
string temp;
TreeNode<T> *p = subTree;
while (p){ //结束条件,如果传入的东西是空,则无动作,回到有元素可打的位置
out << str << p->data << endl;
if (p == current && p->firstChild){
// str = str + "└--";
// temp = str;
temp= str + "└--";
}
else if (p == current && p->nextSibling){
current = current->nextSibling;
}
else if (p->firstChild && p->firstChild->nextSibling){
temp = string("| ") + str;
}
else{
temp = string(" ") + str;
}
Output(p->firstChild, temp, out);
//执行完子结点后会回归到兄弟结点继续执行
p = p->nextSibling;
}
}
The Output of the tree is:
1
└──2
│ └──3
│ └──4
└──5
│ └──6
│ │ └──7
│ │ └──8
│ └──9
│ └──10
└──11
ShowTree函数
template <typename T>void Tree<T>::ShowTree(TreeNode<T> *t, ostream &out){
if (!t){
return;
}
out << '(';
out << t->data;
for (TreeNode<T> *p = t->firstChild; p; p = p->nextSibling){
ShowTree(p, out);
//每次都输出、递归到下一层,到尾节点时再输出兄弟结点,以此类推
}
out << ')';
}
Createtree
template <typename T>void Tree<T>::CreateTree(istream& in, TreeNode<T> *& subTree){
T item;
if (in >> item){
if (item != RefValue){
subTree = new TreeNode<T>(item); //Create Root
assert(subTree);
CreateTree(in, subTree->firstChild); // Create first child tree
CreateTree(in, subTree->nextSibling); // Create nextSibling tree
}
else{
subTree = NULL;
}
}
}
整一个头文件
#ifndef TREE_H
#define TREE_H
#include <iostream>
#include <string>
#include "SeqQueue.h"
using namespace std;
template <typename T>struct TreeNode{
T data;
TreeNode<T> *firstChild, *nextSibling;
TreeNode(T value = 0, TreeNode<T> *fc = NULL, TreeNode<T> *ns = NULL)
:firstChild(fc), nextSibling(ns){
data = value;
}
};
template <typename T>class Tree{
public:
Tree(){
root = current = NULL;
}
Tree(T value){
root = current = NULL;
RefValue = value;
}
bool Root(); //Öøù½áµãΪµ±Ç°½áµã
TreeNode<T> *getRoot(){
return root;
}
void setRoot(TreeNode<T> *rt){
root = rt;
}
bool IsEmpty(){
return root == NULL;
}
bool FirstChild(); //½«µ±Ç°½áµãµÄµÚÒ»¸ö×ÓÅ®ÖÃΪµ±Ç°½áµã
bool NextSibling(); //½«µ±Ç°½áµãµÄÏÂÒ»¸öÐÖµÜÖÃΪµ±Ç°½áµã
bool Parent(); //½«µ±Ç°½áµãµÄË«Ç×ÖÃΪµ±Ç°½áµã
bool Find(T value); //ËÑË÷º¬valueµÄ½áµã, ʹ֮³ÉΪµ±Ç°½áµã
void PreOrder(void (*visit)(TreeNode<T> *t)){//Ç°Ðò
TreeNode<T> *p = root;
while (p){
PreOrder(p, visit);
p = p->nextSibling;
}
}
void PostOrder(void (*visit)(TreeNode<T> *t)){//ºóÐò
TreeNode<T> *p = root;
while (p){
PostOrder(p, visit);
p = p->nextSibling;
}
}
void LevelOrder(void (*visit)(TreeNode<T> *t)){//²ã´Î
LevelOrder(root, visit);
}
//ÒÔÏȸù´ÎÐòÊäÈëÊ÷;ÒÔRefValue±íʾij½ÚµãûÓÐ×ÓÅ®»ò²»ÔÙÓÐÐÖµÜ
void CreateTree(istream &in = cin){
CreateTree(in, root);
}
void Output(ostream &out = cout){ //Ê÷×´¸ñʽÊä³ö
Output(root, string(), out);
}
void IntendedText(ostream &out = cout){ //½«Ê÷ÓÃËõ¸ñÎı¾ÐÎʽÊä³ö
IntendedText(root, string(), out);//string()Êǹ¹Ô캯Êý
}
void ShowTree(ostream &out = cout){
ShowTree(root, out);
}
void reSetCurrent(){ //½«currentÖØÐÂÖ¸Ïò¸ù½Úµã
current = root;
}
friend istream& operator >> (istream &in, Tree<T> &tree)
{ tree.CreateTree(in,tree.root);
return in;
}; //tree²»¿ÉÎó×÷Tree
friend ostream& operator << (ostream &out, Tree<T> &tree)
{ tree.IntendedText(out);
return out;
};//ÒòΪÀàÄ£°åµÄÓÑÔªº¯ÊýÊǺ¯ÊýÄ£°å£¬±ØÐëÔÚ´ËÉùÃ÷£¬ÔÚÀàÍⶨÒå
private:
TreeNode<T> *root, *current;
bool Find(TreeNode<T> *p, T value); //ÔÚÒÔpΪ¸ùµÄÊ÷ÖÐËÑË÷value
void RemovesubTree(TreeNode<T> *subTree); //ɾ³ýÒÔpΪ¸ùµÄ×ÓÊ÷
bool FindParent(TreeNode<T> *t, TreeNode<T> *p);
void PreOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t));
void PostOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t));
void LevelOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t));
void Output(TreeNode<T> *subTree, string str, ostream &out);
void IntendedText(TreeNode<T> *subTree, string str, ostream &out);
void ShowTree(TreeNode<T> *t, ostream &out);
void CreateTree(istream& in, TreeNode<T> *& subTree);//ÒÔÏȸù´ÎÐòÊäÈëÊ÷;ÒÔRefValue±íʾij½ÚµãûÓÐ×ÓÅ®»ò²»ÔÙÓÐÐÖµÜ
T RefValue; //Êý¾ÝÊäÈëÍ£Ö¹±êÖ¾
};
template <typename T> bool Tree<T>::Root(){ //ÈÃÊ÷µÄ¸ù½áµã³ÉΪÊ÷µÄµ±Ç°½áµã
if (root == NULL){
current = NULL;
return false;
}
else{
current = root;
return true;
}
}
template <typename T>bool Tree<T>::Parent(){ //Öõ±Ç°½áµãµÄË«Ç×½áµãΪµ±Ç°½áµã
TreeNode<T> *p = current;
if (current == NULL || current == root){ // ¿ÕÊ÷»ò¸ùÎÞË«Ç×
current = NULL;
return false;
}
return FindParent (root, p); //´Ó¸ù¿ªÊ¼ÕÒ*pµÄË«Ç×½áµã
}
template <typename T>bool Tree<T>::FindParent(TreeNode<T> *t, TreeNode<T> *p){ //ÔÚ¸ùΪ*tµÄÊ÷ÖÐÕÒ*pµÄË«Ç×, ²¢ÖÃΪµ±Ç°½áµã
TreeNode<T> *q = t->firstChild; //*qÊÇ*t³¤×Ó
while (q != NULL && q != p){ //ɨÃèÐÖµÜÁ´
if (FindParent(q, p)){
return true;
}
q = q->nextSibling;
}
if (q != NULL && q == p){
current = t;
return true;
}
else{
current = NULL;
return false;
}
}
template <typename T>bool Tree<T>::FirstChild(){ //ÔÚÊ÷ÖÐÕÒµ±Ç°½áµãµÄ³¤×Ó, ²¢ÖÃΪµ±Ç°½áµã
if (current && current->firstChild){
current = current->firstChild;
return true;
}
current = NULL;
return false;
}
template <typename T> bool Tree<T>::NextSibling(){ //ÔÚÊ÷ÖÐÕÒµ±Ç°½áµãµÄÐÖµÜ, ²¢ÖÃΪµ±Ç°½áµã
if (current && current->nextSibling){
current = current->nextSibling;
return true;
}
current = NULL;
return false;
}
template <typename T> void Tree<T>::PreOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t)){
if (subTree){
visit(subTree);
subTree = subTree->firstChild;
while (subTree){
PreOrder(subTree, visit);
subTree = subTree->nextSibling;
}
}
}
template <typename T>void Tree<T>::PostOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t)){
if (subTree){
TreeNode<T> *p = subTree;
p = p->firstChild;
while (p){
PostOrder(p, visit);
p = p->nextSibling;
}
visit(subTree);
}
}
template <typename T>void Tree<T>::LevelOrder(TreeNode<T> *subTree, void (*visit)(TreeNode<T> *t)){ //°´¹ã¶ÈÓÅÏÈ´ÎÐò·Ö²ã±éÀúÊ÷, Ê÷µÄ¸ù½áµãÊǵ±Ç°Ö¸Õëcurrent¡£
SeqQueue<TreeNode<T>*> Q;
if (subTree){
while (subTree){
Q.EnQueue(subTree);
subTree = subTree->nextSibling;
}
while (!Q.IsEmpty()){
Q.DeQueue(subTree);
visit(subTree);
subTree = subTree->firstChild;
while (subTree){
Q.EnQueue(subTree);
subTree = subTree->nextSibling;
}
}
}
}
template <typename T>bool Tree<T>::Find(T value){
if (IsEmpty()){
return false;
}
return Find(root, value);
}
template <typename T>bool Tree<T>::Find(TreeNode <T> *p, T value){
bool result = false;
if (p->data == value){
result = true;
current = p;
}
else{
TreeNode<T> *q = p->firstChild;
while (q != NULL && !(result = Find(q, value))){
q = q->nextSibling;
}
}
return result;
}
template<typename T>void Tree<T>::RemovesubTree(TreeNode<T> *subTree){ //˽Óк¯Êý: ÈôÖ¸ÕësubTree²»Îª¿Õ, Ôòɾ³ý¸ùΪsubTreeµÄ×ÓÊ÷
if (subTree){
RemovesubTree(subTree->firstChild);
RemovesubTree(subTree->nextSibling);
delete subTree;
}
}
template <typename T>void Tree<T>::IntendedText(TreeNode<T> *subTree, string str, ostream &out){
TreeNode<T> *p = subTree;
while (p){//Éî¶ÈÓÅÏÈ
cout << str << p->data << endl;
string temp = str + string("\t");//×¢Òâ±í´ïʽ×îºóÒ»Ïî¹¹ÔìÎÞÃû±ê×¼´®
if (p->firstChild){
IntendedText(p->firstChild, temp, out);//Éî¶ÈµÝ¹é
}
p = p->nextSibling;//¹ã¶ÈÑ»·
}
}
template <typename T>void Tree<T>::Output(TreeNode<T> *subTree, string str, ostream &out){
if (subTree == root){
current = root;
}
string temp;
TreeNode<T> *p = subTree;
while (p){//Éî¶ÈÓÅÏÈ
out << str << p->data << endl;//str¿ªÊ¼ÊÇ¿Õ´®
if (p == current && p->firstChild){
// str = str + "©¸©¤©¤";
// temp = str;
temp= str + "©¸©¤©¤";
}
else if (p == current && p->nextSibling){
current = current->nextSibling;
}
else if (p->firstChild && p->firstChild->nextSibling){
temp = string("©¦¡¡¡¡") + str;
}
else{
temp = string("¡¡¡¡¡¡") + str;
}
Output(p->firstChild, temp, out);//Éî¶ÈµÝ¹é
p = p->nextSibling;//¹ã¶ÈÑ»·
}
}
template <typename T>void Tree<T>::ShowTree(TreeNode<T> *t, ostream &out){
if (!t){
return;
}
out << '(';
out << t->data;
for (TreeNode<T> *p = t->firstChild; p; p = p->nextSibling){
ShowTree(p, out);
}
out << ')';
}
template <typename T>void Tree<T>::CreateTree(istream& in, TreeNode<T> *& subTree){
T item;
if (in >> item){ //Á÷Õý³£Ö´ÐÐÒÔϳÌÐò
if (item != RefValue){
subTree = new TreeNode<T>(item); //Create Root
assert(subTree);
CreateTree(in, subTree->firstChild); // Create first child tree
CreateTree(in, subTree->nextSibling); // Create nextSibling tree
}
else{
subTree = NULL;
}
}
}
#endif