北邮22信通一枚~
跟随课程进度每周更新数据结构与算法的代码和文章
持续关注作者 解锁更多邮苑信通专属代码~
获取更多文章 请访问专栏~
目录
一.总纲
***说明***
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;
}
运行效果: