难点在于:如何将新插入的结点插到树内结点的左边和右边?借助于辅助队列
#include <iostream>
#include <queue>
using namespace std;
//层次建树
//元素 -> 创一个结点
//队列的结点含义:新加入结点的位置 每创一个结点左右孩子入队
//步骤:遍历字符串
//root 队列结点设计
//结点 左右孩子入队
//root为空 改变root指向
//root非空 访问队列 改变左右孩子指向 出队
//结点
struct TreeNode{
//数据域
char data;
//指针域 左子树 右子树
TreeNode * leftchild;
TreeNode * rigtchild;
};
//队列设计 队列结点含义:结点地址 左还是右
struct QueueNode{
TreeNode *parent;//新节点的父亲地址
bool isleft;//左边是否插入过
};
//插入元素层次建树 修改root的指向
void inserTreeNode(TreeNode * &root, queue<QueueNode *> &myqueue,char data){
if(data !='#'){
//创建结点 申请在堆空间
TreeNode * pTreeNode=new TreeNode;//pTreeNode
pTreeNode->data=data;
//入队 队列里的结点 将刚创好的结点信息放入队列里的结点
QueueNode * pQueueNode=new QueueNode;//pQueueNode
pQueueNode->parent=pTreeNode;
pQueueNode->isleft= false;
myqueue.push(pQueueNode);
//插入
if(root==NULL){
//插入的是第一个结点
root=pTreeNode;
} else{
//插入不是根
//pParent 用来定位父亲结点的位置
QueueNode *pParent =myqueue.front();
if(pParent->isleft == false){
pParent->parent->leftchild=pTreeNode;//队列结点里元素结点左孩子地址
pParent->isleft= true;
} else{
pParent->parent->rigtchild=pTreeNode;
myqueue.pop();//出队
delete pParent;//队首无用
}
}
} else{
//是# 插入空
if(root !=NULL){
QueueNode *pParent =myqueue.front();
if(pParent->isleft== false){
pParent->parent->leftchild=NULL;
pParent->isleft= true;
} else{
pParent->parent->rigtchild=NULL;
myqueue.pop();
delete pParent;
}
}
}
}
//层次遍历 访问结点 左右孩子加入队列
void LevelOrder(TreeNode *root){
queue<TreeNode *> pos;//二叉树结点的位置
pos.push(root);//根入队
while (pos.empty()== false){
TreeNode *pur=pos.front();//访问队首
pos.pop();//出队
printf("%c",pur->data);
//队首邻居
if(pur->leftchild!=NULL){
pos.push(pur->leftchild);
}if(pur->rigtchild!=NULL){
pos.push(pur->rigtchild);
}
}
printf("\n");
}
int main() {
TreeNode *root=NULL;//指向根结点
//新加入的结点应该放在哪个位置?放完第一个结点左右孩子 再放第二个 由结点放入的顺序决定——队列
char charList[]="abc##de#g##f###";
queue<QueueNode *> myqueue;
for(int i=0;charList[i]!='\0';++i){
inserTreeNode(root,myqueue,charList[i]);
}
LevelOrder(root);
return 0;
}