层序遍历时顺序为A->B->C->D->E->F->G,先被访问的结点,他的孩子也是先被访问的,层序创建二叉树时,先创建的结点他的孩子也先创建,符合先进先出原则,因此可以用队列来实现。
层序创建和层序遍历的思路大体一致,首先得明白层序遍历。
1.层序遍历
思路:建立一个树节点的队列。
第一步,若根节点不为空我们先让根节点入队,判断他的左右孩子是否为空,若不为空打印根节点并让他的孩子入队。
第二步,取出队列头结点,判断他是否有左右孩子,若有让其孩子入队。
重复第二步直到队列为空。
#include <iostream>
using namespace std;
typedef char DataType;
//二叉树数据结构
struct node
{
DataType info; //存放结点数据
struct node* lchild, * rchild; //指向左右孩子的指针
};
typedef struct node* BiTree;
void visit(BiTree T) //输出结点T的数据
{
cout << T->info;
}
void Order(BiTree root)//层序遍历
{
BiTree q[100],p;
int front = -1, rear = -1;//队列,并初始化;
q[++rear] = root;//把根节点入队
while (front != rear)//如果队列不为空就循环
{
p = q[++front];//出队头
visit(p);//打印队头的数据
if (p->lchild != NULL) {//若有左孩子左孩子入队
q[++rear] = p->lchild;
}
if (p->rchild != NULL) {//若有右孩子右孩子入队
q[++rear] = p->rchild;
}
}
}
2.层序创建二叉树
层序创建其实和层序遍历差不多都是一个思想,先创建的他的孩子也先创建。
思路:
建立一个树节点的队列。
第一步,输入的第一个数为根节点,判断是否为空。若根节点不为空我们先让根节点入队。
第二步,开始循环,先出队头结点,之后的两个输入,一个为他的左孩子,一个为右孩子,判断是否为空,不为空则孩子入队
重复第二步直到队列为空。
测试案例:1 2 3 4 5 6 # # # # # # #
/*层序创建二叉树
函数名:createBiTree
参数:无
返回值:二叉树根结点指针
*/
BiTree createBiTree(void)
{
char ch;
BiTree root,p;
BiTree q[100]; int front = -1, rear = -1;//队列,并初始化;
cout << "输入你的数据,如果为空则输入#," << endl;
cin >> ch;
root = new struct node;
root->info = ch;
q[++rear] = root;//把根节点入队
while (front != rear)//如果队列不为空就循环
{
p = q[++front];//出队头
cin >> ch;
if (ch != '#') {//不为空,说明有左孩子,就入队
p->lchild= new struct node;
p->lchild->info = ch;
q[++rear] = p->lchild;
}
else {
p->lchild = NULL;//为空就不入队
}
cin >> ch;
if (ch != '#') {//同理右孩子
p->rchild = new struct node;
p->rchild->info = ch;
q[++rear] = p->rchild;
}
else {
p->rchild = NULL;
}
}
return root;
}
这里给出一个无需输#的方式,就是通过数组,先将数组全部赋值为#,之后将输入数据传到数组,循环时直接从数组中拿数据就行,思路与上面的完全一样,但多开辟了空间,也多花了时间。
BiTree createBiTree(void)
{
char ch,string[100];
for (int j = 0; j < 100; j++)
{
string[j] = '#';
}//先让数组全是#,为下面出队做准备
int t=0;
BiTree root,p;
BiTree q[100]; int front = -1, rear = -1;//队列,并初始化;
cout << "输入你的数据,如果为空则输入#,输入&终止" << endl;
cin >> ch;
string[t] = ch;
getchar();
while (ch != '&') {
cin >> ch;
string[++t] = ch;
getchar();
}
string[t] = '#';
t=0;
root = new struct node;
root->info = string[t];
q[++rear] = root;//把根节点入队
while (front != rear)//如果队列不为空就循环
{
p = q[++front];//出队头
ch=string[++t];
if (ch != '#') {//不为空,说明有左孩子,就入队
p->lchild = new struct node;
p->lchild->info = ch;
q[++rear] = p->lchild;
}
else {
p->lchild = NULL;//为空就不入队
}
ch = string[++t];
if (ch != '#') {//同理右孩子
p->rchild = new struct node;
p->rchild->info = ch;
q[++rear] = p->rchild;
}
else {
p->rchild = NULL;
}
}
return root;
}
3.整体代码(这个是需要用#号清空队列的代码,如果要直接输入就用第二个层序创建的代码)
#include <iostream>
using namespace std;
typedef char DataType;
//二叉树数据结构
struct node
{
DataType info; //存放结点数据
struct node* lchild, * rchild; //指向左右孩子的指针
};
typedef struct node* BiTree;
/*层序创建二叉树
函数名:createBiTree
参数:无
返回值:二叉树根结点指针
*/
BiTree createBiTree(void)
{
char ch;
BiTree root,p;
BiTree q[100]; int front = -1, rear = -1;//队列,并初始化;
cout << "输入你的数据,如果为空则输入#," << endl;
cin >> ch;
root = new struct node;
root->info = ch;
q[++rear] = root;//把根节点入队
while (front != rear)//如果队列不为空就循环
{
p = q[++front];//出队头
cin >> ch;
if (ch != '#') {//不为空,说明有左孩子,就入队
p->lchild= new struct node;
p->lchild->info = ch;
q[++rear] = p->lchild;
}
else {
p->lchild = NULL;//为空就不入队
}
cin >> ch;
if (ch != '#') {//同理右孩子
p->rchild = new struct node;
p->rchild->info = ch;
q[++rear] = p->rchild;
}
else {
p->rchild = NULL;
}
}
return root;
}
void visit(BiTree T) //输出结点T的数据
{
cout << T->info;
}
void Order(BiTree root)//层序遍历
{
BiTree q[100],p;
int front = -1, rear = -1;//队列,并初始化;
q[++rear] = root;//把根节点入队
while (front != rear)//如果队列不为空就循环
{
p = q[++front];//出队头
visit(p);//打印队头的数据
if (p->lchild != NULL) {//若有左孩子左孩子入队
q[++rear] = p->lchild;
}
if (p->rchild != NULL) {//若有右孩子右孩子入队
q[++rear] = p->rchild;
}
}
}
int main(void)
{
BiTree root = createBiTree();
Order(root);
}