二叉树整合

本文详细介绍了二叉树的各种操作,包括创建、前序、中序、后序递归与非递归遍历,计算高度,找到最后一个/第一个元素,层序遍历,交换左右子树,计算双分支结点和总节点数,以及叶子结点个数。同时,还涉及了判断两棵二叉树是否等价以及查找特定节点的算法。
摘要由CSDN通过智能技术生成

二叉树

#include <iostream>
#define MaxSize 10

结构体

typedef struct treenode{
	struct treenode * lchild,* rchild;
	int info;
	int tag;
}*tree;

1.二叉树的创建

/**
 * 测试数据:
 * ABD##E##CF##G##
 * 123##4##56##7##
 */
tree buildtree()
{
	char ch;
    tree t;
	ch=getchar();
	if(ch=='#')
        t=NULL;
	else{
		t=(tree)malloc(sizeof(treenode));
		t->info=ch;
        t->tag=0;
        t->lchild=buildtree();
        t->rchild=buildtree();
	}
    return t;
}

2.递归遍历二叉树

/**
 * 前序
 * @param t
 */
void DGpreOrder(tree t)
{
    if (t){
        printf("%c",t->info);
        DGpreOrder(t->lchild);
        DGpreOrder(t->rchild);
    }
}
/**
 * 中序
 * @param t
 */
void DGmidOrder(tree t)
{
    if (t){
        DGmidOrder(t->lchild);
        printf("%c",t->info);
        DGmidOrder(t->rchild);
    }
}
/**
 * 后序
 * @param t
 */
void DGlastOrder(tree t)
{
    if (t){
        DGlastOrder(t->lchild);
        DGlastOrder(t->rchild);
        printf("%c",t->info);
    }
}

3.非递归遍历二叉树

/**
 * 前序
 * @param t
 */
void preOrder(tree t){
    treenode *stack[10];
    treenode *p;
    p=t;
    int top=-1;
    while (p || top!=-1)
    {
        if (p)
        {
            top++;
            stack[top]=p;
            printf("%c",p->info);
            p=p->lchild;
        } else{
            p=stack[top];
            top--;
            p->rchild;
        }
    }
}
/**
 * 中序
 * @param t
 */
void midOrder(tree t){
    treenode *stack[10];
    treenode *p;
    p=t;
    int top=-1;
    while (p || top!=-1)
    {
        if (p)
        {
            top++;
            stack[top]=p;
            p=p->lchild;
        } else{
            p=stack[top];
            top--;
            printf("%c",p->info);
            p->rchild;
        }
    }
}
/**
 * 后序
 * @param t
 */
void lastOrder(tree t){
    treenode *stack[10];
    treenode *p;
    p=t;
    int top=-1;
    while (p || top!=-1)
    {
        if(p)
        {
            top++;
            stack[top]=p;
            p=p->lchild;
        } else{
            p=stack[top];
            if (p->rchild && p->rchild->tag==0){
                p=p->rchild;
            }
            else{
                p=stack[top];
                top--;
                printf("%c",p->info);
                //tag=1表示这个结点已经被访问过了
                p->tag=1;
                p=NULL;
            }
        }
    }
}

4.二叉树高

/**
 * 递归
 * @return
 */
int DGdepth(tree t){
    int lh,rh,h;
    if (t==NULL)
        return 0;
    else{
        lh= DGdepth(t->lchild);
        rh= DGdepth(t->rchild);
        if (lh>=rh)
            h=lh+1;
        else
            h=rh+1;
    }
    return h;
}
/**
 * 非递归--利用队列
 * @return
 */
int depth(tree t){
    if (t==NULL) return 0;
    treenode *s[10];
    treenode *p;
    int front =-1,rear=-1;
    int h=0,L=0;
    s[++rear]=t;
    while (front<rear){
        p=s[++front];  //元素出队
        if (p->lchild)
            s[++rear]=p->lchild;
        if (p->rchild)
            s[++rear]=p->rchild;
        //front==0 说明第一层结点计算完
        if (front==L){
            printf("HIGH++");
            printf("\n");
            printf("rear:%d",rear);
            printf("\n");
            printf("front:%d",front);
            printf("\n");
            printf("L:%d",L);
            printf("\n");
            L=rear;
            h++;
        }
    }
    return h;
}

5.遍历最后/第一个元素

/**
 * 前序最后
 * @return
 */
 treenode* preOrderLast(tree t){
    if (t->rchild)
        t= preOrderLast(t->rchild);
    else
        t= preOrderLast(t->lchild);
    return t;
 }
/**
* 中序最后
* @return
*/
treenode* midOrderLast(tree t){
    if (t->rchild)
        t= midOrderLast(t->rchild);
    return t;
 }

6.遍历第一个元素

/**
* 中序
* @return
*/
treenode* midOrderFrist(tree t){
    if (t->lchild)
        t= midOrderLast(t->lchild);
    return t;
}
/**
* 后序第一
* @return
*/
treenode* lastOrderFrist(tree t){
    if (t->lchild)
        t= lastOrderFrist(t->lchild);
    else
        t= lastOrderFrist(t->lchild);
    return t;
}

7.层序遍历

/**
 * 链式队列实现层序遍历
 * @param t
 */
void levelOrder(tree t){
    treenode *s[10];
    int front,rear,tag;
    front=rear=-1;
    tag=0;
    treenode *p;
    s[++rear]=t;
    while (front<rear && tag==0)
    {
        p=s[++front];
        printf("%c",p->info);
        if (p->lchild)
            s[++rear]=p->lchild;
        if (p->rchild)
            s[++rear]=p->rchild;
    }
}
/**
 * 顺序队列实现
 * @return
 */
struct squeue {
    struct treenode* data[MaxSize];
    int front, rear, tag;
};
//进队
bool EnQueue(squeue& s, treenode *x)
{
    if (s.front == s.rear && s.tag == 1)
    {
        printf("队满 进队失败");
        return false;
    }
    s.data[s.rear] = x;
    s.rear = (s.rear + 1) % MaxSize;
    s.tag = 1;
    return true;
}
//出队
int DeQueue(squeue& s, treenode* &x)
{
    if (s.front == s.rear && s.tag == 0)
    {
        printf("空 出队失败");
        return 0;
    }
    x = s.data[s.front];
    s.front = (s.front + 1) % MaxSize;
    s.tag = 0;
    return 1;
}
void levelOrder2(tree t)
{
    squeue q;
    int front,rear,tag;
    front=rear=tag=0;
    treenode *p;
    EnQueue(q,t);
    while(!(front==rear&&tag==0))
    {
        DeQueue(q,p);
        printf("%c",p->info);
        if(p->lchild)
            EnQueue(q,p->lchild);
        if(p->rchild)
            EnQueue(q,p->rchild);
    }
}

8.交换左右子树

void change(tree &t){
    //中间变量
    tree temp;
    //如果根节点为空
    if (t==NULL)
        return;
    //如果左右节点为空
    else if (t->lchild ==NULL && t->rchild ==NULL)
        return;
    else{
        temp=t->lchild;
        t->lchild=t->rchild;
        t->rchild=temp;
        change(t->lchild);
        change(t->rchild);
    }
}

9.双分支结点个数

int num(tree t){
    if (t==NULL)
        return 0;
    if (t->rchild && t->lchild)
        return num(t->lchild)+ num(t->rchild)+1;
    else
        return num(t->lchild)+ num(t->rchild);
}

10.总结点个数

/***
 * 递归
 * @return
 */
int sum(tree t){
    if (t==NULL) return 0;
    else
        return sum(t->lchild)+ sum(t->rchild)+1;
}

11.叶子结点个数

/***
 * 递归
 * @return
 */
int LeafCount(tree t){
    if (t==NULL)
        return 0;
    else if (t->lchild==NULL && t->rchild==NULL)
        return 1;
    else
        return LeafCount(t->rchild)+ LeafCount(t->lchild);
}
/***此代码有点问题,待解决。**********
 * 非递归:利用栈来消除递归
 * @return
 */
 int LeafCount2(tree t){
     int count=0;
     int top=-1;
     tree stack[100];
     while(t!=NULL || top!=-1){
         while(t!=NULL){
             if (t->lchild==NULL && t->rchild==NULL)
                 count++;
             stack[++top]=t;
             t=t->lchild;
         }
         if (top!=-1)
         {
             t=stack[--top];
             t=t->rchild;
         }
     }
    return count;
 }

12.第k层结点个数

/**
 * 递归:
 * (1)如果二叉树为空或者k<1返回0
 * (2)如果二叉树不为空并且k==1,返回1
 * (3)如果二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树k-1层节点个数之和
 * @return
 */
 int getCountK(tree t,int k){
    if (k<0 || t==NULL) return 0; //树不存在或者k所指的层数不存在
    else if (k==1) return 1; //第一层的结束点数
    else
        return getCountK(t->lchild,k-1)+ getCountK(t->rchild,k-1);
 }

13.判断二叉树等价

/**
 * 返回1代表等价,返回0代表不等价
 * @param t1
 * @param t2
 * @return
 */
int isequal(tree t1,tree t2){
     int t=0;
     //两个空树必然等价
    if (t1==NULL && t2==NULL)
        return 1;
    else{
        if (t1!=NULL && t2!=NULL) //如果两个数的结点都存在
            if (t1->info==t2->info) //如果两个结点的值相等
                if (isequal(t1->lchild,t2->lchild))//如果t1和t2的左子树等价
                    t= isequal(t1->rchild,t2->rchild);
    }
    return t;
 }

14.查找第x结点

tree searchX(tree t,char x){
    tree p;
    if (t==NULL) //空树
        return NULL;
    else{
        if (t->info == x) //查找的结点为根结点
            return t;
        else{
            p= searchX(t->lchild,x);
            if (p)
                return p;
            else
                return searchX(t->rchild,x);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值