北邮22信通:二叉树层序遍历的非递归算法:A Story Between Two Templates

北邮22信通一枚~   

跟随课程进度每周更新数据结构与算法的代码和文章 

持续关注作者  解锁更多邮苑信通专属代码~

获取更多文章  请访问专栏~

北邮22信通_青山如墨雨如画的博客-CSDN博客

目录

一.总纲

二.用队列存储

2.1用模板类实现队列

2.1.1核心思路:

2.1.2一个错误 

2.1.3完整代码

2.1.4运行结果

2.1.5补充:链队列实现

 2.2使用STL中的队列

2.2.1核心代码

2.2.2完整代码

2.2.3运行结果

三.用数组存储

3.1核心代码:

3.2完整代码

3.3运行结果:

 四.完整代码


一.总纲

***说明***

1.本篇文章将为你介绍二叉树层序遍历的两类常见方法。根据数据存储结构的不同,我们可以将方法大致分为以下两类:使用数组储存和使用队列储存。使用数组储存的实现方法就是函数的递归调用,之前的文章中有介绍过;本篇文章重点讲解使用队列存储的方法。

2.队列的层序遍历:在进行层序遍历时,对某一层节点访问完毕之后,在按照他们的访问顺序一次对各个节点的左孩子和右孩子顺序访问,这样一层一层的进行,先访问的节点其左孩子也要先访问,这与队列的特性比较吻合。因此,我们可以利用队列来实现二叉树的层序遍历。

用队列实现层序遍历的方法:先让根节点入队;根节点出队的同时根节点的左右孩子依次入队;每次出队一个,出队那个节点的左孩子和右孩子再从队尾依次入队,以此类推。

基本思想:

   根结点非空,入队。

   如果队列不空  

   {

       队头元素出队

       访问该元素

       若该结点的左孩子非空,则左孩子入队;

       若该结点的右孩子非空,则右孩子入队;

   }

3.A Story Between Two Templates 一提到队列,我们会不约而同的想到第三章扩展线性表中,我们通过模板类实现了队列。那么在这里如果使用队列存储,可不可以实现队列的模板类和二叉树的模板类之间的交互呢?具体实现过程怎样?

4.第四章的主要任务是实现树,队列的要求并不高。所以,我们不仅可以通过模板类来实现队列,我们也可以调用STL中的队列。

5.有问题随时补充~欢迎评论区留言~

***说明完毕***

二.用队列存储

2.1用模板类实现队列

2.1.1核心思路:

        首先,在已经构建bintree二叉树的基础上,我们要向代码中添加队列模板类的代码。这种感觉有点像拼积木。有一块积木可以实现二叉树,有一块积木可以实现队列,我们唯一要做的就是找到这两个木块之间的接口,然后把他们“拼起来”。 

        队列实现模板类的代码请参考博客北邮22信通:(11)第三章 3.3队列的实现_青山如墨雨如画的博客-CSDN博客

       下面也贴一份循环队列的。

template<class temp>
class circlequeue
{
private:
	temp data[queuesize];
	int front;
	int rear;
public:
	circlequeue() { this->front = this->rear = 0; }
	void enqueue(temp x);
	temp dequeue();
	temp getfront();
	int getlength();
	bool empty()
	{
		return this->front == this->rear ? true : false;
	}
};
 
template<class temp>
void circlequeue<temp>::enqueue(temp x)
{
	if ((this->rear + 1) % queuesize == this->front) throw "overflow";
	this->rear = (this->rear + 1) % queuesize;
	this->data[this->rear] = x;
}
 
template<class temp>
temp circlequeue<temp>::dequeue()
{
	if (this->rear == this->front)throw"underflow";
	this->front = (this->front + 1) % queuesize;
	return this->data[this->front];
}
 
template<class temp>
temp circlequeue<temp>::getfront()
{
	if (this->rear == this->front)throw"underflow";
	return this->data[(this->front + 1) % queuesize];
}
 
template<class temp>
int circlequeue<temp>::getlength()
{
	return (this->rear - this->front + queuesize);
}

有了队列的“积木”,我们现在考虑在bintree中调用队列的积木,来实现队列方式的层序遍历。

template<class temp>
void bintree<temp>::queuelevelorder(binnode<temp>* r)
{
	circlequeue<binnode<temp>*>q;
	if (r != NULL)q.enqueue(r);//根节点入队
	while (!q.empty())//如果队列非空
	{
		binnode<temp>* p = q.dequeue();//队首元素出队
		cout << p->data;//访问该元素
		if (p->leftchild != NULL)q.enqueue(p->leftchild);
        //若该节点的左孩子非空,则左孩子入队
		if (p->rightchild != NULL)q.enqueue(p->rightchild);
        //若该节点的右孩子非空,则右孩子入队
	}
}

2.1.2一个错误 

需要注意的是:circlequeue的<>中传入的参数一定是binnode<temp>*而不是binnode<temp>

        实际上这里传入的参数决定着队列中每一个元素的数据类型。实际上,访问二叉树时,对每个节点的引用都是通过指针来实现的,换句话说,虽然二叉树中每个节点的存储类型确实是binnode<temp>,但是我们想要访问二叉树的某个节点,还是通过每个节点内嵌指针来实现的,所以对节点的引用,注意,是对节点的“引用”,是通过binnode<temp>*指针来实现的。所以我们构建队列的时候,不妨直接让队列中每个元素的数据类型都是binnode<temp>*指针类型,从而构建了一个指针队列。        说明:如果队列circlequeue中传入的数据类型我就叛逆我就不写binnode<temp>*写成binnode<temp>,

  那么你将会收获一份报错:

         这个报错是什么意思呢?

       想想看,我们queuelevelorder这个层序遍历的函数传入的形参,必然是binnode<temp>*root但是,我队列定义的是binnode<temp>类型的,那所有队列中的成员函数传入的参数就都得是binnode<temp>类型的。我现在在enqueue函数中传入了一个binnode<temp>*,程序就蒙了:这是几个意思啊?不是应该给我一个binnode<temp>么?怎么给我binnode<temp>*这个指针啊??所以程序就报错了。

        这个问题我改了好久问了好几次助教 直接导致好多文章发不出来(找到合适借口(bushi

2.1.3完整代码

核心代码实现咯,我们来看完整代码

#include<iostream>
#define MAXSIZE 100000
using namespace std;
const int queuesize = 10000;
class student
{
private:
	int ID;
	string name;
public:
	int existence;
	student()
	{
		this->ID = 0;
		this->name = "unknown name";
		this->existence = 0;
	}
	student(int ID, string name)
	{
		this->ID = ID;
		this->name = name;
		this->existence = 1;
	}
	friend ostream& operator<<(ostream& output, student& s)
	{
		output << s.ID << " " << s.name << endl;
		return output;
	}
};

//队列
template<class temp>
class circlequeue
{
private:
	temp data[queuesize];
	int front;
	int rear;
public:
	circlequeue() { this->front = this->rear = 0; }
	void enqueue(temp x);
	temp dequeue();
	temp getfront();
	int getlength();
	bool empty()
	{
		return this->front == this->rear ? true : false;
	}
};

template<class temp>
void circlequeue<temp>::enqueue(temp x)
{
	if ((this->rear + 1) % queuesize == this->front) throw "overflow";
	this->rear = (this->rear + 1) % queuesize;
	this->data[this->rear] = x;
}

template<class temp>
temp circlequeue<temp>::dequeue()
{
	if (this->rear == this->front)throw"underflow";
	this->front = (this->front + 1) % queuesize;
	return this->data[this->front];
}

template<class temp>
temp circlequeue<temp>::getfront()
{
	if (this->rear == this->front)throw"underflow";
	return this->data[(this->front + 1) % queuesize];
}

template<class temp>
int circlequeue<temp>::getlength()
{
	return (this->rear - this->front + queuesize);
}

//二叉树
template<class temp>
struct binnode
{
	temp data;
	binnode<temp>* leftchild;
	binnode<temp>* rightchild;
};

template<class temp>
class bintree
{
private:
	void create(binnode<temp>*& r, temp data[], int i, int n);
	void release(binnode<temp>* r);
public:
	binnode<temp>* root;
	bintree(temp data[], int n);
	void preorder(binnode<temp>* r);
	void inorder(binnode<temp>* r);
	void postorder(binnode<temp>* r);
	void levelorder(binnode<temp>* r);
	void queuelevelorder(binnode<temp>* r);
	~bintree();
};

template<class temp>
void bintree<temp>::create(binnode<temp>*& r, temp data[], int i, int n)
{
	if (i <= n && data[i - 1].existence != 0)
	{
		r = new binnode<temp>;
		r->data = data[i - 1];
		r->leftchild = r->rightchild = NULL;
		create(r->leftchild, data, 2 * i, n);/*书上代码错误1:向函数传入实参时少传入一个n*/
		create(r->rightchild, data, 2 * i + 1, n);/*书上代码错误同上*/
	}
}

template<class temp>
bintree<temp>::bintree(temp data[], int n)
{
	create(this->root, data, 1, n);
}

template<class temp>
void bintree<temp>::preorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		cout << r->data;
		preorder(r->leftchild);
		preorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::inorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		inorder(r->leftchild);
		cout << r->data;
		inorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::postorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		postorder(r->leftchild);
		postorder(r->rightchild);
		cout << r->data;
	}
}

template<class temp>
void bintree<temp>::levelorder(binnode<temp>* R)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (R != NULL)
		queue[++r] = R;
	while (f != r)
	{
		binnode<temp>* p = queue[++f];
		cout << p->data;//出队打印
		if (p->leftchild != NULL)
			queue[++r] = p->leftchild;
		if (p->rightchild != NULL)
			queue[++r] = p->rightchild;
	}
}

template<class temp>
void bintree<temp>::queuelevelorder(binnode<temp>* r)
{
	circlequeue<binnode<temp>*>q;
	if (r != NULL)q.enqueue(r);
	while (!q.empty())
	{
		binnode<temp>* p = q.dequeue();
		cout << p->data;
		if (p->leftchild != NULL)q.enqueue(p->leftchild);
		if (p->rightchild != NULL)q.enqueue(p->rightchild);
	}
}

template <class temp>
void bintree<temp>::release(binnode<temp>* r)
{
	if (r != NULL)
	{
		release(r->leftchild);
		release(r->rightchild);
		delete r;
	}
}

template<class temp>
bintree<temp>::~bintree()
{
	release(this->root);
}

int main()
{
	system("color 0A");
	student stu[5] = { {1,"zhang"},{2,"wang"},{3,"li"},{4,"zhao"},{5,"liu"} };
	bintree<student>bintreee(stu, 5);
	cout << "前序遍历:" << endl;
	bintreee.preorder(bintreee.root);
	cout << endl << "中序遍历:" << endl;
	bintreee.inorder(bintreee.root);
	cout << endl << "后序遍历:" << endl;
	bintreee.postorder(bintreee.root);
	cout << endl << "层序遍历:" << endl;
	bintreee.levelorder(bintreee.root);
	cout << endl << "队列层序遍历" << endl;
	bintreee.queuelevelorder(bintreee.root);
	return 0;
}

2.1.4运行结果

代码效果图:

程序运行结果:

 

2.1.5补充:链队列实现

        本篇文章主要用循环队列实现的,其实也可以用链队列实现,下面扔一个链队列实现的代码,uu们可以拿去玩玩~

#include<iostream>
#include<queue>
#define MAXSIZE 100000
using namespace std;
const int queuesize = 10000;
class student
{
private:
	int ID;
	string name;
public:
	int existence;
	student()
	{
		this->ID = 0;
		this->name = "unknown name";
		this->existence = 0;
	}
	student(int ID, string name)
	{
		this->ID = ID;
		this->name = name;
		this->existence = 1;
	}
	friend ostream& operator<<(ostream& output, student& s)
	{
		output << s.ID << " " << s.name << endl;
		return output;
	}
};

//链队列
template<class temp>
struct node
{
	temp data;
	node<temp>* next;
};

template <class temp>
class linkqueue
{
private:
	node<temp>* front;
	node<temp>* rear;
public:
	linkqueue();
	~linkqueue();
	void enqueue(temp x);
	temp dequeue();
	temp getfront();
	int getlength();
	bool empty()
	{
		return (this->front == this->rear) ? true : false;
	}
};

template<class temp>
linkqueue<temp>::linkqueue()
{
	this->front = this->rear = new node <temp>;
	this->front->next = NULL;
}

template<class temp>
void linkqueue<temp>::enqueue(temp x)
{
	this->rear->next = new node<temp>;
	this->rear = this->rear->next;
	this->rear->data = x;
	this->rear->next = NULL;
}

template<class temp>
temp linkqueue<temp>::dequeue()
{
	node<temp>* p = this->front->next;
	if (!p)throw"underflow";/*如果为空队列,抛出异常*/
	this->front->next = p->next;
	temp x = p->data;
	delete p;
	if (!(this->front->next))
		this->rear = this->front;
	return x;
}

template<class temp>
temp linkqueue<temp>::getfront()
{
	if (!this->front->next)throw"overflow";
	return this->front->next->data;
}

template<class temp>
linkqueue<temp>::~linkqueue()
{
	while (this->front != NULL)
	{
		this->rear = this->front->next;
		delete this->front;
		this->front = this->rear;
	}
}

template<class temp>
int linkqueue<temp>::getlength()
{
	node<temp>* p = this->front;
	int cnt = 0;
	while (p != this->rear)
	{
		cnt++;
		p = p->next;
	}
	return cnt;
}

//二叉树
template<class temp>
struct binnode
{
	temp data;
	binnode<temp>* leftchild;
	binnode<temp>* rightchild;
};

template<class temp>
class bintree
{
private:
	void create(binnode<temp>*& r, temp data[], int i, int n);
	void release(binnode<temp>* r);
public:
	binnode<temp>* root;
	bintree(temp data[], int n);
	void preorder(binnode<temp>* r);
	void inorder(binnode<temp>* r);
	void postorder(binnode<temp>* r);
	void levelorder(binnode<temp>* r);
	void arraylevelorder(binnode<temp>* r);
	void queuelevelorder(binnode<temp>* r);
	void STLlevelorder(binnode<temp>* r);
	~bintree();
};

template<class temp>
void bintree<temp>::create(binnode<temp>*& r, temp data[], int i, int n)
{
	if (i <= n && data[i - 1].existence != 0)
	{
		r = new binnode<temp>;
		r->data = data[i - 1];
		r->leftchild = r->rightchild = NULL;
		create(r->leftchild, data, 2 * i, n);/*书上代码错误1:向函数传入实参时少传入一个n*/
		create(r->rightchild, data, 2 * i + 1, n);/*书上代码错误同上*/
	}
}

template<class temp>
bintree<temp>::bintree(temp data[], int n)
{
	create(this->root, data, 1, n);
}

template<class temp>
void bintree<temp>::preorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		cout << r->data;
		preorder(r->leftchild);
		preorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::inorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		inorder(r->leftchild);
		cout << r->data;
		inorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::postorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		postorder(r->leftchild);
		postorder(r->rightchild);
		cout << r->data;
	}
}

template<class temp>
void bintree<temp>::levelorder(binnode<temp>* R)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (R != NULL)
		queue[++r] = R;
	while (f != r)
	{
		binnode<temp>* p = queue[++f];
		cout << p->data;//出队打印
		if (p->leftchild != NULL)
			queue[++r] = p->leftchild;
		if (p->rightchild != NULL)
			queue[++r] = p->rightchild;
	}
}

template<class temp>
void bintree<temp>::arraylevelorder(binnode<temp>* root)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (root != NULL)queue[++r] = root;
	while (f != r)
	{
		binnode<temp>* p = queue[++f];
		cout << p->data;
		if (p->leftchild != NULL)queue[++r] = p->leftchild;
		if (p->rightchild != NULL)queue[++r] = p->rightchild;
	}
}

template<class temp>
void bintree<temp>::queuelevelorder(binnode<temp>* r)
{
	linkqueue<binnode<temp>*>q;
	if (r != NULL)q.enqueue(r);
	while (!q.empty())
	{
		binnode<temp>* p = q.dequeue();
		cout << p->data;
		if (p->leftchild != NULL)q.enqueue(p->leftchild);
		if (p->rightchild != NULL)q.enqueue(p->rightchild);
	}
}

template<class temp>
void bintree<temp>::STLlevelorder(binnode<temp>* r)
{
	queue<binnode<temp>*>q;
	if (r != NULL)q.push(r);
	while (!q.empty())
	{
		binnode<temp>* p = q.front();
		q.pop();
		cout << p->data;
		if (p->leftchild != NULL) q.push(p->leftchild);
		if (p->rightchild != NULL)q.push(p->rightchild);
	}
}

template <class temp>
void bintree<temp>::release(binnode<temp>* r)
{
	if (r != NULL)
	{
		release(r->leftchild);
		release(r->rightchild);
		delete r;
	}
}

template<class temp>
bintree<temp>::~bintree()
{
	release(this->root);
}

int main()
{
	system("color 0A");
	student stu[5] = { {1,"zhang"},{2,"wang"},{3,"li"},{4,"zhao"},{5,"liu"} };
	bintree<student>bintreee(stu, 5);
	cout << "前序遍历:" << endl;
	bintreee.preorder(bintreee.root);
	cout << endl << "中序遍历:" << endl;
	bintreee.inorder(bintreee.root);
	cout << endl << "后序遍历:" << endl;
	bintreee.postorder(bintreee.root);
	cout << endl << "层序遍历:" << endl;
	bintreee.levelorder(bintreee.root);
	cout << endl << "数组层序遍历" << endl;
	bintreee.arraylevelorder(bintreee.root);
	cout << endl << "队列层序遍历" << endl;
	bintreee.queuelevelorder(bintreee.root);
	cout << endl << "STL层序遍历" << endl;
	bintreee.STLlevelorder(bintreee.root);
	return 0;
}

 2.2使用STL中的队列

第四章核心内容是讲解树,所以对队列的要求没那么严格(我说的)

所以还是想通过STL中的队列简化一下代码,当然了,如果你的老师不让用,那我也没办法咯(〃'▽'〃)

2.2.1核心代码

template<class temp>
void bintree<temp>::STLlevelorder(binnode<temp>* r)
{
	queue<binnode<temp>*>q;
	if (r != NULL)q.push(r);
	while (!q.empty())
	{
		binnode<temp>* p = q.front();
		q.pop();
		cout << p->data;
		if (p->leftchild != NULL) q.push(p->leftchild);
		if (p->rightchild != NULL)q.push(p->rightchild);
	}
}

2.2.2完整代码

#include<iostream>
#include<queue>
#define MAXSIZE 100000
using namespace std;
const int queuesize = 10000;
class student
{
private:
	int ID;
	string name;
public:
	int existence;
	student()
	{
		this->ID = 0;
		this->name = "unknown name";
		this->existence = 0;
	}
	student(int ID, string name)
	{
		this->ID = ID;
		this->name = name;
		this->existence = 1;
	}
	friend ostream& operator<<(ostream& output, student& s)
	{
		output << s.ID << " " << s.name << endl;
		return output;
	}
};
//二叉树
template<class temp>
struct binnode
{
	temp data;
	binnode<temp>* leftchild;
	binnode<temp>* rightchild;
};

template<class temp>
class bintree
{
private:
	void create(binnode<temp>*& r, temp data[], int i, int n);
	void release(binnode<temp>* r);
public:
	binnode<temp>* root;
	bintree(temp data[], int n);
	void preorder(binnode<temp>* r);
	void inorder(binnode<temp>* r);
	void postorder(binnode<temp>* r);
	void levelorder(binnode<temp>* r);
	void STLlevelorder(binnode<temp>* r);
	~bintree();
};

template<class temp>
void bintree<temp>::create(binnode<temp>*& r, temp data[], int i, int n)
{
	if (i <= n && data[i - 1].existence != 0)
	{
		r = new binnode<temp>;
		r->data = data[i - 1];
		r->leftchild = r->rightchild = NULL;
		create(r->leftchild, data, 2 * i, n);/*书上代码错误1:向函数传入实参时少传入一个n*/
		create(r->rightchild, data, 2 * i + 1, n);/*书上代码错误同上*/
	}
}

template<class temp>
bintree<temp>::bintree(temp data[], int n)
{
	create(this->root, data, 1, n);
}

template<class temp>
void bintree<temp>::preorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		cout << r->data;
		preorder(r->leftchild);
		preorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::inorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		inorder(r->leftchild);
		cout << r->data;
		inorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::postorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		postorder(r->leftchild);
		postorder(r->rightchild);
		cout << r->data;
	}
}

template<class temp>
void bintree<temp>::levelorder(binnode<temp>* R)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (R != NULL)
		queue[++r] = R;
	while (f != r)
	{
		binnode<temp>* p = queue[++f];
		cout << p->data;//出队打印
		if (p->leftchild != NULL)
			queue[++r] = p->leftchild;
		if (p->rightchild != NULL)
			queue[++r] = p->rightchild;
	}
} 

template<class temp>
void bintree<temp>::STLlevelorder(binnode<temp>* r)
{
	queue<binnode<temp>*>q;
	if (r != NULL)q.push(r);
	while (!q.empty())
	{
		binnode<temp>* p = q.front();
		q.pop();
		cout << p->data;
		if (p->leftchild != NULL) q.push(p->leftchild);
		if (p->rightchild != NULL)q.push(p->rightchild);
	}
}

template <class temp>
void bintree<temp>::release(binnode<temp>* r)
{
	if (r != NULL)
	{
		release(r->leftchild);
		release(r->rightchild);
		delete r;
	}
}

template<class temp>
bintree<temp>::~bintree()
{
	release(this->root);
}

int main()
{
	system("color 0A");
	student stu[5] = { {1,"zhang"},{2,"wang"},{3,"li"},{4,"zhao"},{5,"liu"} };
	bintree<student>bintreee(stu, 5);
	cout << "前序遍历:" << endl;
	bintreee.preorder(bintreee.root);
	cout << endl << "中序遍历:" << endl;
	bintreee.inorder(bintreee.root);
	cout << endl << "后序遍历:" << endl;
	bintreee.postorder(bintreee.root);
	cout << endl << "层序遍历:" << endl;
	bintreee.levelorder(bintreee.root);
	cout << endl << "STL层序遍历" << endl;
	bintreee.STLlevelorder(bintreee.root);
	return 0;
}

2.2.3运行结果

代码效果图:

 运行结果:

三.用数组存储

3.1核心代码:

template<class temp>
void bintree<temp>::arraylevelorder(binnode<temp>* root)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;//初始化空队列
	if (root != NULL)queue[++r] = root;//根节点入队
	while (f != r)
	{
		binnode<temp>* p = queue[++f];//队首元素出队
		cout << p->data;//访问根节点
		if (p->leftchild != NULL)queue[++r] = p->leftchild;//左孩子入队
		if (p->rightchild != NULL)queue[++r] = p->rightchild;//右孩子入队
	}
}

3.2完整代码

#include<iostream>
#include<queue>
#define MAXSIZE 100000
using namespace std;
const int queuesize = 10000;
class student
{
private:
	int ID;
	string name;
public:
	int existence;
	student()
	{
		this->ID = 0;
		this->name = "unknown name";
		this->existence = 0;
	}
	student(int ID, string name)
	{
		this->ID = ID;
		this->name = name;
		this->existence = 1;
	}
	friend ostream& operator<<(ostream& output, student& s)
	{
		output << s.ID << " " << s.name << endl;
		return output;
	}
};

template<class temp>
struct binnode
{
	temp data;
	binnode<temp>* leftchild;
	binnode<temp>* rightchild;
};

template<class temp>
class bintree
{
private:
	void create(binnode<temp>*& r, temp data[], int i, int n);
	void release(binnode<temp>* r);
public:
	binnode<temp>* root;
	bintree(temp data[], int n);
	void preorder(binnode<temp>* r);
	void inorder(binnode<temp>* r);
	void postorder(binnode<temp>* r);
	void levelorder(binnode<temp>* r);
	void arraylevelorder(binnode<temp>* r);
	~bintree();
};

template<class temp>
void bintree<temp>::create(binnode<temp>*& r, temp data[], int i, int n)
{
	if (i <= n && data[i - 1].existence != 0)
	{
		r = new binnode<temp>;
		r->data = data[i - 1];
		r->leftchild = r->rightchild = NULL;
		create(r->leftchild, data, 2 * i, n);/*书上代码错误1:向函数传入实参时少传入一个n*/
		create(r->rightchild, data, 2 * i + 1, n);/*书上代码错误同上*/
	}
}

template<class temp>
bintree<temp>::bintree(temp data[], int n)
{
	create(this->root, data, 1, n);
}

template<class temp>
void bintree<temp>::preorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		cout << r->data;
		preorder(r->leftchild);
		preorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::inorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		inorder(r->leftchild);
		cout << r->data;
		inorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::postorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		postorder(r->leftchild);
		postorder(r->rightchild);
		cout << r->data;
	}
}

template<class temp>
void bintree<temp>::levelorder(binnode<temp>* R)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (R != NULL)
		queue[++r] = R;
	while (f != r)
	{
		binnode<temp>* p = queue[++f];
		cout << p->data;//出队打印
		if (p->leftchild != NULL)
			queue[++r] = p->leftchild;
		if (p->rightchild != NULL)
			queue[++r] = p->rightchild;
	}
}

template<class temp>
void bintree<temp>::arraylevelorder(binnode<temp>* root)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (root != NULL)queue[++r] = root;
	while (f != r)
	{
		binnode<temp>* p = queue[++f];
		cout << p->data;
		if (p->leftchild != NULL)queue[++r] = p->leftchild;
		if (p->rightchild != NULL)queue[++r] = p->rightchild;
	}
}

template <class temp>
void bintree<temp>::release(binnode<temp>* r)
{
	if (r != NULL)
	{
		release(r->leftchild);
		release(r->rightchild);
		delete r;
	}
}

template<class temp>
bintree<temp>::~bintree()
{
	release(this->root);
}

int main()
{
	system("color 0A");
	student stu[5] = { {1,"zhang"},{2,"wang"},{3,"li"},{4,"zhao"},{5,"liu"} };
	bintree<student>bintreee(stu, 5);
	cout << "前序遍历:" << endl;
	bintreee.preorder(bintreee.root);
	cout << endl << "中序遍历:" << endl;
	bintreee.inorder(bintreee.root);
	cout << endl << "后序遍历:" << endl;
	bintreee.postorder(bintreee.root);
	cout << endl << "层序遍历:" << endl;
	bintreee.levelorder(bintreee.root);
	cout << endl << "数组层序遍历" << endl;
	bintreee.arraylevelorder(bintreee.root);
	return 0;
}

3.3运行结果:

代码效果图:

运行结果:

 四.完整代码

#include<iostream>
#include<queue>
#define MAXSIZE 100000
using namespace std;
const int queuesize = 10000;
class student
{
private:
	int ID;
	string name;
public:
	int existence;
	student()
	{
		this->ID = 0;
		this->name = "unknown name";
		this->existence = 0;
	}
	student(int ID, string name)
	{
		this->ID = ID;
		this->name = name;
		this->existence = 1;
	}
	friend ostream& operator<<(ostream& output, student& s)
	{
		output << s.ID << " " << s.name << endl;
		return output;
	}
};

//队列
template<class temp>
class circlequeue
{
private:
	temp data[queuesize];
	int front;
	int rear;
public:
	circlequeue() { this->front = this->rear = 0; }
	void enqueue(temp x);
	temp dequeue();
	temp getfront();
	int getlength();
	bool empty()
	{
		return this->front == this->rear ? true : false;
	}
};

template<class temp>
void circlequeue<temp>::enqueue(temp x)
{
	if ((this->rear + 1) % queuesize == this->front) throw "overflow";
	this->rear = (this->rear + 1) % queuesize;
	this->data[this->rear] = x;
}

template<class temp>
temp circlequeue<temp>::dequeue()
{
	if (this->rear == this->front)throw"underflow";
	this->front = (this->front + 1) % queuesize;
	return this->data[this->front];
}

template<class temp>
temp circlequeue<temp>::getfront()
{
	if (this->rear == this->front)throw"underflow";
	return this->data[(this->front + 1) % queuesize];
}

template<class temp>
int circlequeue<temp>::getlength()
{
	return (this->rear - this->front + queuesize);
}

//二叉树
template<class temp>
struct binnode
{
	temp data;
	binnode<temp>* leftchild;
	binnode<temp>* rightchild;
};

template<class temp>
class bintree
{
private:
	void create(binnode<temp>*& r, temp data[], int i, int n);
	void release(binnode<temp>* r);
public:
	binnode<temp>* root;
	bintree(temp data[], int n);
	void preorder(binnode<temp>* r);
	void inorder(binnode<temp>* r);
	void postorder(binnode<temp>* r);
	void levelorder(binnode<temp>* r);
	void arraylevelorder(binnode<temp>* r);
	void queuelevelorder(binnode<temp>* r);
	void STLlevelorder(binnode<temp>* r);
	~bintree();
};

template<class temp>
void bintree<temp>::create(binnode<temp>*& r, temp data[], int i, int n)
{
	if (i <= n && data[i - 1].existence != 0)
	{
		r = new binnode<temp>;
		r->data = data[i - 1];
		r->leftchild = r->rightchild = NULL;
		create(r->leftchild, data, 2 * i, n);/*书上代码错误1:向函数传入实参时少传入一个n*/
		create(r->rightchild, data, 2 * i + 1, n);/*书上代码错误同上*/
	}
}

template<class temp>
bintree<temp>::bintree(temp data[], int n)
{
	create(this->root, data, 1, n);
}

template<class temp>
void bintree<temp>::preorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		cout << r->data;
		preorder(r->leftchild);
		preorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::inorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		inorder(r->leftchild);
		cout << r->data;
		inorder(r->rightchild);
	}
}

template<class temp>
void bintree<temp>::postorder(binnode<temp>* r)
{
	if (r != NULL)
	{
		postorder(r->leftchild);
		postorder(r->rightchild);
		cout << r->data;
	}
}

template<class temp>
void bintree<temp>::levelorder(binnode<temp>* R)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (R != NULL)
		queue[++r] = R;
	while (f != r)
	{
		binnode<temp>* p = queue[++f];
		cout << p->data;//出队打印
		if (p->leftchild != NULL)
			queue[++r] = p->leftchild;
		if (p->rightchild != NULL)
			queue[++r] = p->rightchild;
	}
}

template<class temp>
void bintree<temp>::arraylevelorder(binnode<temp>* root)
{
	binnode<temp>* queue[MAXSIZE];
	int f = 0, r = 0;
	if (root != NULL)queue[++r] = root;
	while (f != r)
	{
		binnode<temp>* p = queue[++f];
		cout << p->data;
		if (p->leftchild != NULL)queue[++r] = p->leftchild;
		if (p->rightchild != NULL)queue[++r] = p->rightchild;
	}
}

template<class temp>
void bintree<temp>::queuelevelorder(binnode<temp>* r)
{
	circlequeue<binnode<temp>*>q;
	if (r != NULL)q.enqueue(r);
	while (!q.empty())
	{
		binnode<temp>* p = q.dequeue();
		cout << p->data;
		if (p->leftchild != NULL)q.enqueue(p->leftchild);
		if (p->rightchild != NULL)q.enqueue(p->rightchild);
	}
}

template<class temp>
void bintree<temp>::STLlevelorder(binnode<temp>* r)
{
	queue<binnode<temp>*>q;
	if (r != NULL)q.push(r);
	while (!q.empty())
	{
		binnode<temp>* p = q.front();
		q.pop();
		cout << p->data;
		if (p->leftchild != NULL) q.push(p->leftchild);
		if (p->rightchild != NULL)q.push(p->rightchild);
	}
}

template <class temp>
void bintree<temp>::release(binnode<temp>* r)
{
	if (r != NULL)
	{
		release(r->leftchild);
		release(r->rightchild);
		delete r;
	}
}

template<class temp>
bintree<temp>::~bintree()
{
	release(this->root);
}

int main()
{
	system("color 0A");
	student stu[5] = { {1,"zhang"},{2,"wang"},{3,"li"},{4,"zhao"},{5,"liu"} };
	bintree<student>bintreee(stu, 5);
	cout << "前序遍历:" << endl;
	bintreee.preorder(bintreee.root);
	cout << endl << "中序遍历:" << endl;
	bintreee.inorder(bintreee.root);
	cout << endl << "后序遍历:" << endl;
	bintreee.postorder(bintreee.root);
	cout << endl << "层序遍历:" << endl;
	bintreee.levelorder(bintreee.root);
	cout << endl << "数组层序遍历" << endl;
	bintreee.arraylevelorder(bintreee.root);
	cout << endl << "队列层序遍历" << endl;
	bintreee.queuelevelorder(bintreee.root);
	cout << endl << "STL层序遍历" << endl;
	bintreee.STLlevelorder(bintreee.root);
	return 0;
}

运行效果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山入墨雨如画

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值