将一棵以二叉链表存储的二叉树按顺序方式存储到一维数组中
【题目要求】
给定扩展二叉树的前序序列,构建二叉树(以二叉链表方式存储),然后将这个二叉链表存储为一维数组,其编号采用满二叉树的编号模式。
要求输入扩展二叉树的前序序列,输出以一维数组存储的方式。示例见下图:
【测试数据】
【输入数据】
AB#DE###CF#G###
【输出数据】
ABC^DF^^^E^^G
【题解代码】
#include<iostream>
#include<stdio.h>
using namespace std;
const int QS=100;
struct BiNode
{
char data;//数据域
BiNode *lchild, *rchild;//左右儿子指针
};
//定义能存放树的结点和编号的结构体
struct NodeNum
{
BiNode *node;
int number;
};
class BiTree
{
private:
BiNode *root; //指向根结点的头指针
public:
BiTree()
{
root = creat(root);//调函数构建二叉树
}
~BiTree()
{
}
BiNode * getRoot()
{
return root;
}
BiNode *creat(BiNode *bt); //构造函数调用
void release(BiNode *bt); //析构函数调用,释放树的存储空间
void toArray(char biTreeArray[],int length,int *count);//后序遍历函数调用
};
//前序构建二叉树
BiNode *BiTree::creat(BiNode *bt)
{
char ch;
cin>>ch;
if(ch=='#')
bt=NULL;
else
{
bt=new BiNode;
bt->data=ch;
bt->lchild=creat(bt->lchild);
bt->rchild=creat(bt->rchild);
}
return bt;
}
//析构函数
void BiTree::release(BiNode *bt)
{
if(bt!=NULL)
{
release(bt->lchild);
release(bt->rchild);
delete bt;
}
}
//将二叉树存储到一维数组中
void BiTree::toArray(char biTreeArray[],int length,int *count)
{
int front=-1,rear=-1; //采用顺序队列,并假定不会溢出
int num; //用来控制二叉数组的下标
NodeNum Q[QS]; //定义队列
NodeNum nodenum; //临时变量
BiNode *p; //指向当前处理的树结点
//数组的初始化
for(int i=0; i<length; i++)
{
biTreeArray[i]=0;
}
if(root==NULL) //二叉树为空,算法结束
{
return;
}
nodenum.node=root;
nodenum.number=1; //根结点编号为1,存入数组时,需在编号基础上减1
Q[++rear]=nodenum;
//当队列非空时,进行层序遍历
while(front!=rear)
{
nodenum=Q[++front]; //出队
//当前结点值存入临时变量,并将出队的结点存入二叉树组
p=nodenum.node; //p指向当前结点
num=nodenum.number; //获取树结点编号
biTreeArray[num-1]=nodenum.node->data; //存入数组
//如果有左孩子,则左孩子入队
if(p->lchild!=NULL)
{
nodenum.node=p->lchild;
nodenum.number=2*num; //计算编号
Q[++rear]=nodenum; //左孩子入队
*count=nodenum.number; //count记录字符串最大的存储序号
}
//如果有右孩子,则右孩子入队
if(p->rchild!=NULL)
{
nodenum.node=p->rchild;
nodenum.number=2*num+1;//根结点为n=1,存入数组时,在编号基础上减1
Q[++rear]=nodenum; //右孩子入队
*count=nodenum.number; //count记录字符串最大的存储序号
}
}
}
//输出一维数组
void print(char BiTreeArray[],int length)
{
for(int i=0; i<length; i++)
{
if(BiTreeArray[i])
cout<<BiTreeArray[i];
else
cout<<"^";
}
}
int main()
{
int count=0; //记录字符串最大存储序号
cout<<"输入前序字符串:";
BiTree tree;
char biTreeArray[1000]= {0};
tree.toArray(biTreeArray,1000,&count);
print(biTreeArray,count);
return 0;
}
【运行结果】
将一棵用层序输入存储到一维数组的二叉树以前序遍历的方式输出
【题目要求】
一棵二叉树可以利用完全二叉树的编号方式采用顺序表存储,如下图所示。要求按照数组按照下图层序遍历序列存储二叉树,然后输出这棵二叉树的前序遍历序列。
【测试数据】
【样例输入】 ABC^DF^^^E^^G
【样例输出】 ABDECFG
【提示】定义字符数组(顺序表)时,应将数组初始化为0(0代表NULL的含义),那么在处理顺序表时,如果遇到
'^'
字符时,你可以判断为NULL,遇到0
时,你也可以判断为NULL。这样就不会引起歧义。
【题解代码】
#include<iostream>
using namespace std;
const int SIZE = 10000;
struct BiNode {
char data;
BiNode* lchild, * rchild;
};
class BiTree
{
private:
char biTreeArray[SIZE];
void preOrder(int bt);
public:
BiTree();
~BiTree() {
}
void preOrder() {
preOrder(1); //从根节点开始进行前序遍历
}
void release(BiNode* bt); //析构函数调用,释放树的存储空间
};
BiTree::BiTree()
{
//用层序遍历法创建二叉树,输入字符串
int i;
for (i = 0; i < SIZE; i++) //初始化
{
biTreeArray[i] = 0;
}
cin >> biTreeArray;
}
void BiTree::release(BiNode* bt)
{
if (bt != NULL)
{
release(bt->lchild);
release(bt->rchild);
delete bt;
}
}
void BiTree::preOrder(int bt) //bt表示当前节点在数组中的索引位置(从1开始)
{
//如果为^或0,说明遇到空指针
if (biTreeArray[bt - 1] == '^' || biTreeArray[bt - 1] == 0) //数组是从0开始的,所以需要bt-1
return;
else
{
cout << biTreeArray[bt - 1];
preOrder(bt * 2); //递归查找左子树
preOrder(bt * 2 + 1); //递归查找右子树
//对于一棵具有n个结点的完全二叉树的结点从1开始层序编号,则对于任意的编号为i的结点,其左孩子编号为2i,右孩子编号为2i+1
}
}
int main() {
BiTree tree;
tree.preOrder();
return 0;
}