#include <cstdio>
#incldue <queue>
#include <stack>
using namespace std;
//二叉树
struct node{
typename data;
node* lchild;
node* rchild;
};
node *root=NULL;
//1建立新结点,v为结点权值
node * newnode(int v)
{
node *Node =new node; //申请一个node型变量的地址空间
Node ->data=v; //结点权值为v
Node->lchild=Node->rchild=NULL; //初始状态下没有左右孩子
return Node; //返回新建结点的地址
}
//2查找、修改算法
void search(node* root,int x,int newdata)
{
if(root==NULL)
{
return ;//空树,死胡同
}
if(root->data==x) //找到数据域为x的结点,修改为newdata
root->data=newdata;
search(root->lchild,x,newdata); //往左子树搜索,递归式
search(root->rchild,x,newdata); // 往右子树搜索,递归式
}
//3.插入一个数据域为x的结点
void insert(node* &root,int x)//注意根结点指针root要用引用,否则插入不会成功
{
if(root==NULL)//空树,查找失败,也即插入位置(递归边界)
{
root=newnode(x);
return;
}
if(由二叉树的性质,x应该插在左子树)
{
insert(root->lchild,x);//往左子树搜索(递归式)
}
else
{
insert(root->rchild,x);//往右子树搜素(递归式)
}
}
//4.二叉树的建立
void create(int data[],int n)
{
node* root=NULL; //新建空根结点root
for(int i=0;i<n;++i)
{
insert(root,data[i]);
}
return root;
}
//9.2二叉树的遍历
//1.先(根)序遍历
void preorder(node *root)
{
if(root==NULL) //空树,返回,递归边界
return ;
//访问根节点,例如将其数据域输出
printf("%d\n",root->data);
preorder(root->lchild);//递归式,访问左子树
preorder(root->rchild);
}
//2.中序遍历
void inorder(node *root)
{
if(root==NULL)
return ;
inorder(root->lchild);
printf("%d\n",root->data);//访问根节点root,例如将其数据域输出
inorder(root->rchild);
}
//3.后续遍历
void postorder(node* root)
{
if(root==NULL)
return;
postorder(root->lchild);
postorder(root->rchild);
printf("%d\n",root->data);
}
//4.层次遍历
void layerorder(node *root)
{
queue<node*> Q;//注意队列里是存地址!(队列中存放的是原来元素的一个副本,固需要修改队列中元素时
//若为queue<node> q,则修改的说副本中的元素,无法修改原来元素的值,故此处宜用指针!
Q.push(root);
while(!Q.empty())
{
node* p=Q.front();
printf("%d\n",p->data);
Q.pop();
if(p->lchild!=NULL)
Q.push(p->lchild);
if(p->rchild!=NULL)
Q.push(p->rchild);
}
}
//注:有些题目需要计算结点的层数,固需在结构体中添加layer域
struct node{
typename data;
node* lchild;
node* rchild;
int layer;
}Node;
//层次遍历记录层次
void layerOrder(Node*root)
{
queue<node*>q;//注意这里存储的是地址
root->layer=1; //根节点的层次为1
q.push(root);
while(!q.empty())
{
node *p=q.front();
q.pop();
printf("%d ",p->data);
if(p->layer!=NULL)
{
p->lchild->layer=p->layer+1;
q.push(p->lchild);
}
if(p->rchild!=NULL)
{
p->rchild->layer=p->layer+1;
q.push(p->rchild);
}
}
}
//给定一棵二叉树的先序遍历和中序遍历序列,插件这棵树
//当前先序序列区间为[preL,preR],中序序列区间为[intL,intR],返回根节点地址
node * create(int preL,int preR,int inL,int inR)
{
if(preL>preR)
return NULL;
node* root=new node;//创建根结点
root->data=pre[preL];
int k;
for(k=inL;in[k]!=pre[preL];k++) //在中序序列中找到in[k]==pre[L]的结点
;
int numleft=k-inL; //左子树的结点个数
//左子树的先序区间为[preL+1,preL+numleft],中序区间为[inL,k-1];
//返回左子树的根节点地址,赋值给根节点的左指针
root->lchild=create(preL+1,preL+numleft,inL,k-1);
//右子树的先序区间为[preL+numleft+1,preR],中序区间为[k+1,inR];
//返回右子树的根节点地址,赋值给根节点的右指针
root->rchild=create(preL+numleft+1,preR,k+1,inR);
return root;
}