二叉树的相关算法

计算二叉树的叶子结点个数

思想:递归方式遍历树,若当前结点是叶子结点(无左右孩子),则返回1,否则返回左右子树叶子结点数量的和
int countLeaves(BiTree T)
{
    if(T == NULL)
        return 0;
    if(T->lchild == NULL&&T->rchild == NULL)
    {
        return 1;
    }
    else{
        return countLeaves(T->lchild) + countLeaves(T->rchild);
    }
}

计算二叉树结点个数

//简单方法,使用全局变量n来计数
int n;
void countNodes(BiTree T)
{
    if(T == NULL)
        return;
    n++;
    countNodes(T->lchild);
    countNodes(T->rchild);
}

//递归法
int countNodes(BiTree T) {
    if (T == NULL)
    {
        return 0;
    } else {
        return 1 + countNodes(T->lchild) + countNodes(T->rchild);
    }
}

层序遍历计算结点数层序遍历计算结点数

int countNodes(BiTree T) {
    if (T == NULL) {
        return 0;
    }
    
    int count = 0; // 节点数量
    Queue Q; // 定义队列
    initQueue(&Q); // 初始化队列
    enQueue(&Q, T); // 根节点入队
    
    while (!isEmpty(Q)) { // 队列不为空时循环
        BiTree node = deQueue(&Q); // 出队一个节点
        count++; // 节点数量加1
        
        if (node->lchild != NULL) { // 如果左孩子不为空,入队
            enQueue(&Q, node->lchild);
        }
        
        if (node->rchild != NULL) { // 如果右孩子不为空,入队
            enQueue(&Q, node->rchild);
        }
    }
    
    return count; // 返回节点数量
}

求树高(求二叉树的最大深度)

int getTreeHight(BiTree T)
{
    if(T==NULL)
        return 0;
    
    int lheight = getTreeHight(T->lchild);//左子树高度
    int rheight = getTreeHight(T->rchild);//右子树高度
    
    return lheight > rheight ? lheight+1 : rheight+1;// 返回较大的子树高度加1
}

求树高非递归(利用层次遍历)

int treeHeight(BiTree T)
{
    if(T==NULL)
        return 0;
    
    IniteQueue(&Q);//初始化队列
    EnQueue(&Q,T);
    int height = 0;

    while(!(IsEmpty(Q)))//队列不空则循环
    {
        int levelsize = Q.rear - Q.front;//这一层有几个结点
        for(int i = 0;i<levelsize;i++)
        {
            BiTree node = DeQueue(&Q);
            if(node->lchild)//左子树不空则入队
            {
                EnQueue(&Q,node->lchild);
            }
            if(node->rchild)//右子树不空则入队
            {
                EnQueue(&Q,node->rchild);
            }
        }//for-end

        height ++;//这一层遍历结束,高度++
    }//while-end

    return height;
}

二叉树的先序和中序遍历序列分别存放在A[],B[]中,建立该二叉树


1.根据先序确定树的根结点。
2.根据根结点在中序遍历中的位置划分出二叉树的左右子树包含的结点,根据左右子树结点在先序中的次序确定子树的根结点(返回1// 递归建立二叉树的函数
//aStart为先序第一个结点,aEnd为先序最后一个结点,b同
BiTree buildTree(int A[], int B[], int aStart, int aEnd, int bStart, int bEnd)
{
    if (aStart > aEnd || bStart > bEnd)
    {
        return NULL;
    }
    // 创建根节点
    BiTree root = (BiTNode*)malloc(sizeof(BiTree));
    // 在中序遍历序列中找到根节点的位置
    int rootIndex;
    for (int i = bStart; i <= bEnd; i++)
    {
        if (B[i] == A[aStart])
        {
            rootIndex = i;
            break;
        }
    }
    // 计算左子树的大小
    int leftSize = rootIndex - bStart;

    // 递归建立左子树和右子树
    root->lchild = buildTree(A, B, aStart + 1, aStart + leftSize, bStart, rootIndex - 1);
    root->rchild = buildTree(A, B, aStart + leftSize + 1, aEnd, rootIndex + 1, bEnd);
    return root;
}

// 调用buildTree函数建立二叉树
BiTree buildTreeFromTraversal(int A[], int B[], int n) {
    return buildTree(A, B, 0, n - 1, 0, n - 1);
}

完全二叉树的判断

//采用层序遍历,将所有结点入队,包括空结点,遇到空结点时,查看其后面是否还有非空节点,若有则不是
bool IsComplete(BiTree T)
{
    if(T==NULL)
        return 1;
    InitQueue(&Q);//初始化队列
    EnQueue(&Q,T);

    while(!IsEmpty(&Q))
    {
        BiTree node = DeQueue(&Q);
        if(node)//结点非空,左右子树入队
        {
            EnQueue(node->lchild);
            EnQueue(node->rchild);
        }
        else  //空结点
        {
            while (!IsEmpty(&Q))
            {
                BiTree node = DeQueue(&Q);
                if(node)//结点非空,不是完全二叉树
                    return 0;
            }
            
        }
    }
    return 1;
}

验证是否为二叉排序树(二叉搜索树)

//min max初始为null
bool isBST(BiTree T,BiTree min,BiTree max)
{
    if(T==NULL)
    {
        return true;
    }
    if(min!=NULL&&T->data <= min->data)
    {
        return false;
    }
    if(max!=NULL&&T->data >= max->data)
    {
        return false;
    }

    return isBST(T->lchild,min,T)&&isBST(T->rchild,T,max);
}

交换二叉树的左右子树

void swap(BiTree T)
{
    if(T)
    {
        swap(T->lchild);
        swap(T->rchild);
        //交换左右孩子
        BiTree temp = T->lchild;
        T->lchild = T->rchild;
        T->rchild = temp;
    }
}

求二叉树先序遍历序列中第k个结点的值

int i = 1;
int PreOrder(BiTree T,int k)
{
    if(T==NULL)//空结点则返回特殊字符
        return '#';
    if(i = k)//相等则当前结点为第k个结点
        return T->data;

    i++;//下一个结点
    char ch = PreOrder(T->lchild,k);//左子树中寻找
    if(ch !='#')//在左子树中则返回该值
        return ch;
    ch = PreOrder(T->rchild,k);//在右子树中寻找
        return ch;
}

求二叉树的WPL

全局变量wpl,把每个结点的深度作为递归函数的参数传递
基于先序遍历的思想:
1.若是叶子结点,则wpl加上该节点的深度与权值之积
2.若是非叶子结点,则左子树不空时,对左子树调用递归;右子树同理。深度均为本节点深度+1
3.最后返回计算出wpl即可

int wpl = 0;

int wpl_PreOrder(BiTree T,int deep)
{
    if(T->lchild == NULL&&T->rchild == NULL)//叶子结点
        wpl += deep*T->data;
    if(T->lchild != NULL)   //左子树不空,对左子树遍历
        wpl_PreOrder(T->lchild,deep+1);
    if(T->rchild != NULL)   //右子树不空,对右子树遍历
        wpl_PreOrder(T->rchild,deep+1);
    return wpl;
}

int WPL(BiTree T)
{
    return wpl_PreOrder(T,0);
}

求从根节点到指定节点的路径

int printPath(BiTree T,BiTree node)
{
    if(T==NULL)
        return false;
    if(T == node||printPath(T->lchild,node)||printPath(T->rchild,node))
    {
        printf("%d",T->data);
        return true;
    }
    return false;
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wu丶ying

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值