先序遍历
void preorder(){
if(root == NULL){
return ;
}
printf("%d\n",root->data);//访问根结点
preorder(root->lchild); //访问左子树
preorder(root->rchild); //访问右子树
}
先序遍历的性质:
对一棵二叉树的先序遍历序列而言,序列的第一个结点必定是根结点。
中序遍历
void inorder(node * root){
if(root == NULL){
return ;
}
inorder(root->lchild);//访问左子树
printf("%d\n",root->data);//访问根结点
inorder(root->rchild);//访问右子树
}
中序遍历序列的性质:
可以通过判断根结点在中序遍历序列中的位置来区分出左右子树。
后序遍历
void postorder(node * root){
if(root == NULL){
return ;
}
postorder(root->lchild);//访问左子树
postorder(root->rchild);//访问右子树
printf("%d\n",root->data);//访问根结点
}
后序遍历的性质:
对于后序遍历序列而言,最后一个结点必定是根结点。
层序遍历
void LayerOrder(node * root){
queue<node*> q;//注意队列里存地址
q.push(root); //将根结点地址入队
while(!q.empty()){
node* now = q.front();//取出队首元素
q.pop();
printf("%d",now->data);//访问队首元素
if(now->lchild != NULL) q.push(now->lchild);//左子树非空
if(now->rchild != NULL) q.push(now->rchild);//右子树非空
}
}
当题目种需要求出结点所在层次时,则需要添加表示层次的变量layer :
struct node {
int data;
int layer;
node* lchild;
node* rchild;
};
//层序遍历
void LayerOrder(node* root){
queue<node*> q;//注意队里存放地址
root->layer = 1; //根结点层号为 1
q.push(root);//将根结点地址入队
while(!q.empty()){
node* now = q.front();
q.pop();
printf("%d ",now->data);
if(now->lchild != NULL){//左子树非空
now->lchild->layer = now->layer + 1;
q.push(now->lchild);
}
if(now->rchild!=NULL){//右子树非空
now->rchild->layer = now->layer + 1;
q.push(now->rchild);
}
}
}
给定先序序列与中序序列得出这棵二叉树
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;k <= inR;k++){
if(in[k]==pre[preL]){
break;
}
}
//左子树结点个数
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;
}
后序序列与中序序列得出二叉树的做法类同。
二叉树的静态实现
具体实现如下:
//二叉链表实现
struct node {
typename data;
node* lchild;
node* rchild;
};
//静态二叉链表实现
struct node {
typename data;
int lchild;
int rchild;
}Node[maxn];
静态链表定义下,实现结点的动态生成:
int index = 0;
int newNode(int v){
Node[index].data = v;//数据域
Node[index].lchild = -1;//以-1或maxn表示空,因为数组范围为0 ~ maxn-1
Node[index].rchild = -1;
return index++;
}
二叉树插入、查找、建立:
void search(int root,int x,int newdata){
if(root == -1){
return ;
}
if(Node[root].data == x){
Node[root].data = newdata;
}
search(Node[root].lchild,x,newdata);
search(Node[root].rchild,x,newdata);
}
//插入
void insert(int &root,int x){
if(root == -1){
root = newNode(x);
return ;
}
if(由二叉树性质x应该插在左子树){
insert(Node[root].lchild,x);
}else{
insert(Node[root].rchild,x);
}
}
//建立
void create(int data[],int n){
int root = -1;
for(itn i=0;i< n;i++){
insert(root,data[i]);
}
return root;
}
二叉树遍历:
//先序遍历
void preorder(int root){
if(root == -1){
return;
}
printf("%d\n",Node[root].data);
preorder(Node[root].lchild);
preorder(Node[root].rchild);
}
//中序遍历
void inorder(int root){
if(root == -1){
return;
}
inorder(Node[root].lchild);
printf("%d\n",Node[root].data);
inorder(Node[root].rchild);
}
//后序遍历
void postorder(int root){
if(root == -1){
return;
}
postorder(Node[root].lchild);
postorder(Node[root].rchild);
printf("%d\n",Node[root].data);
}
//层序遍历
void LayerOrder(int root){
queue<int> q;
q.push(root);
while(!q.empty()){
int now = q.front();
q.pop();
printf("%d ",Node[now].data);
if(Node[now].lchild != -1) q.push(Node[now].lchild);
if(Node[now].rchild != -1) q.push(Node[now].rchild);
}
}