遍历树和遍历显示树,以及自己犯傻的经历

今天学到树的遍历和树的创建,主要是二叉树的创建和遍历,主要是前序遍历、中序遍历、后续遍历,然后我把他们实现了一遍,然后再实现后发现一些问题。
1.我是用一个类来存放树的,这个类我就成为树类,但是树类实例的对象却不是我要操作的对象,我要操作的对象是树对象中得到那个被维护的树,而不是操作这个对象,这个对象整体来看就是一个单一的对象,但是它里面的那个树确是多元的东西,而我是要操作那个树的,这也是我一开始犯的错误,我把树类对象当做参数了,妄图使用递归来遍历,但是一个单一的树类对象又怎么会有左子树和右子树,他们是在里面的节点的。
所以总结,编写成员函数时一定要记得,你是要使用的时这个类里面的那个被维护的东西还是这个类实例的对象。
再者打个比方,之前实现链表类时也是这样的情况,那个链表类里面有一个头指针,那个头指针标识的链表才是我们要操作的对象,而不是有那个链表类实例化的对象,要操作的是对象里面的链表,所以写在链表类里面的成员函数都是对类里的那个头指针进行着操作,而不是对外层的那个对象进行操作。这一点要注意!!!
2.就是递归实现遍历和遍历显示的问题,由于递归实现遍历,需要传入的是头指针,因此成员函数定义的时候参数是要有的,参数就是头指针的指针(头指针的引用也可以),等会调用的时候,不是要你输入,记着,不是所有的成员函数都是需要你来输入东西的,着实是遇到的太少了,还是因为我太年轻了,遇到的那种调用有参数的成员函数都是我自己去输入的函数,因此有点思维固化了,难道这种有参数的成员函数一定要我们自己手动输入吗?其实不然。
比如下面这个成员函数(我没有全部写出来,他是有参数的,而且很明显,这个参数我们也无法手动打进去),那么我们调用时,在后面加上T->Birtreenode* head 即可,我又不用手动打进去。
(啊啊啊啊啊,真的烦,思维固化真的烦,明明这么简单的问题,想了我好长时间,接下来你们就会看到我的代码,你们就会想,这个人好笨啊,这么简单方法都想不到,既然要参数,我编写的时候加进去不就得了,又不用你去手输,我还傻不愣登去总结,加一个中介函数什么的,真傻!!!)

	void create1(Bitreenode* &T)//这里我传引用,没人会有疑问吧,说一下吧,本来不用引用,要传二级指针,传入应用,相当于传进小名,改变会带出来的
	{
		int temp=0;
		cout << "请输入此节点的值" << endl;
		cin >> temp;
		if (temp < 0)
		{
			T = NULL;
		}
		else
		{
			T = new Bitreenode;//申请一个空间出来,并返回指针出来,由指针的引用T接受,T是小名。也是BitreeNode*型
			if (!T)
			{
				exit(OVERFLOW);
			}
			T->data = temp;
			create1(T->Ltree);
			create1(T->Rtree);
		}

	}

代码如下:

#include<iostream>
using namespace std;
class Bitreenode
{
public:
	~Bitreenode()
	{
		delete this->Ltree;
		delete this->Rtree;
		this->Ltree = NULL;
		this->Rtree = NULL;
	}
	int data;
	Bitreenode* Ltree;
	Bitreenode* Rtree;
};
//定义一个树类,但是实例化的对象是一个整体,对象里面维护着一个树,由头节点指针标识
class Bitree
{
public:
	Bitree()
	{
		this->num = 0;
		this->Treehead = NULL;
	}
	~Bitree()
	{
		this->num = 0;
		delete this->Treehead;
		this->Treehead = NULL;
	}
	//前向创建一个树出来,由于采用递归方式进行创建,所以需要传入参数,参数时当前树对象中的那个头节点指针,但是默认参数不能是成员属性,加上一个中介函数,也可以不加,在调用时传入对象中的头指针
	void Creattree1()
	{
		this->create1(this->Treehead);
	}
	void create1(Bitreenode* &T)//这里我传引用,没人会有疑问吧,说一下吧,本来不用引用,要传二级指针,传入应用,相当于传进小名,改变会带出来的
	{
		int temp=0;
		cout << "请输入此节点的值" << endl;
		cin >> temp;
		if (temp < 0)
		{
			T = NULL;
		}
		else
		{
			T = new Bitreenode;//申请一个空间出来,并返回指针出来,由指针的引用T接受,T是小名。也是BitreeNode*型
			if (!T)
			{
				exit(OVERFLOW);
			}
			T->data = temp;
			create1(T->Ltree);
			create1(T->Rtree);
		}

	}
	void Creattree2()
	{
		create2(this->Treehead);
	}
	void create2(Bitreenode*& T)
	{
		int temp;
		cout << "请输入此节点的值" << endl;
		cin >> temp;
		if (temp < 0)
		{
			T = NULL;
		}
		else
		{
			T = new Bitreenode;
			create2(T->Rtree);
			T->data = temp;
			create2(T->Ltree);
		}
	}
	void print2(Bitreenode*& T)
	{
		if (T == NULL)
		{
			return;
		}
		else
		{
			print2(T->Ltree);
			cout << T->data << endl;
			print2(T->Rtree);
		}
	}
	void Printtree2()//同样适用递归,鼻血默认参数是成员函数,因此来一个中介函数
	{
		this->print2(this->Treehead);
	}
	void print1(Bitreenode* &T)//前序遍历
	{
		if (T == NULL)
		{
			return;
		}
		else
		{
			cout << T->data << endl;
			print1(T->Ltree);
			print1(T->Rtree);
		}
	}
	void Printtree1()//同样适用递归,鼻血默认参数是成员函数,因此来一个中介函数
	{
		this->print1(this->Treehead);
	}
	Bitreenode* Treehead;//维护这一个树
	int num;//当前有几个节点
};
void test02()//写一个中序遍历的,包括中序写入,中序遍历读取
{
	Bitree t1;
	t1.Creattree2();
	t1.Printtree2();
}
void test01()
{
	Bitree t1;
	t1.create1(t1.Treehead);//这里就是了,我直接把这个参数输进去不就得了,又不用想初始化那样手动输,收到还是做了太多的那种手动初始化的题造成思维定式,这是极为麻烦的,根本就不要什么中介函数,草。
	t1.Printtree1();
}
int main()
{
	test01();
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值