【殷人昆数据结构】第五章5.3 树的子女-兄弟表示Tree代码的调试

树的子女-兄弟表示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
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值