【数据结构X.2】二叉树基础算法层次遍历,求解二叉树的高度,先序和中序建立二叉树链表,判定二叉树是否是完全二叉树,交换全部左右子树

二叉树算法习题:

1.二叉树自下而上,自左到右的层次遍历算法

void ReverseVisitTreeLevel(BiTree tr)

2.非递归算法求解二叉树的高度

int GetHeight(BiTree tr)

3.递归算法求解二叉树的高度

int GetHeightCircle(BiTree tr)

4.二叉树各个值不同,先序和中序遍历序列分别存于数组A[1…n],B[1…n]中, 算法建立该二叉树链表

BiTree BuildTreeBeforeAndIn(int A[], int B[], int h1, int t1, int h2, int t2)

5.二叉树用二叉链表形式存储,写一个判定二叉树是否是完全二叉树的算法, 思路:层次遍历,遇到空节点,检查队列是否有节点

bool isCompleteTree(BiTree tr)

6.二叉树采用二叉链表存储,尝试设计一个算法, 计算一颗给定二叉树的所有双分支节点数

int DoubleNodeNumber(BiTree tr)

7.把二叉树中,所有节点的左右子树交换

void ExchangeLeftAndRight(BiTree tr)

函数定义:

BiTree.h
#include <stack>
#include <iostream>
#include <malloc.h>
#include <queue>
typedef struct BiNode
{
    int data;
    struct BiNode *lchild, *rchild;
} BiNode, *BiTree;

/**
 * 前序遍历,递归
 */
void VisitTreeHead(BiTree tr)
{
    if (tr)
    {
        std::cout << char(tr->data) << " ";
        VisitTreeHead(tr->lchild);
        VisitTreeHead(tr->rchild);
    }
}

/**
 * 前序遍历,非递归
 */
void TreeNodeHead(BiTree tr)
{
    std::stack<BiNode *> s;
    BiNode *p = tr;
    while (!s.empty() || p)
    {
        if (p)
        {
            std::cout << char(p->data) << " ";
            s.push(p);
            p = p->lchild;
        }
        else
        {
            p = s.top();
            s.pop();
            p = p->rchild;
        }
    }
}

/**
 * 后序递归遍历二叉树
 */
void VisitTreeAfter(BiTree tr)
{
    if (tr)
    {
        VisitTreeAfter(tr->lchild);
        VisitTreeAfter(tr->rchild);
        std::cout << tr->data << " ";
    }
}

/**
 * 后序非递归遍历二叉树
 */
void TreeNodeAfter(BiTree tr)
{
    std::stack<BiNode *> s;
    BiNode *p = tr, *r = NULL;
    while (!s.empty() || p)
    {
        if (p)
        {
            s.push(p);
            p = p->lchild;
        }
        else
        {
            p = s.top();
            if (p->rchild && p->rchild != r)
            { //p有右孩子,且没有被访问过
                p = p->rchild;
                s.push(p);
                p = p->lchild;
            }
            else
            {
                s.pop();
                std::cout << char(p->data) << " ";
                r = p;
                p = NULL;
            }
        }
    }
}

/**
 * 创建一颗树
 */
BiTree CreateBTree(BiTree bt, bool isRoot)
{
    char ch;
    if (isRoot)
        std::cout << "Root:";

    std::cin >> ch;
    if (ch != '#')
    {
        isRoot = false;
        bt = (BiNode *)malloc(sizeof(BiNode));
        bt->data = ch;
        bt->lchild = NULL;
        bt->rchild = NULL;
        std::cout << "请输入" << ch << "的左孩子" << std::endl;
        bt->lchild = CreateBTree(bt->lchild, isRoot);
        std::cout << "请输入" << ch << "的右孩子" << std::endl;
        bt->rchild = CreateBTree(bt->rchild, isRoot);
    }
    return bt;
}

/**
 * 中序遍历二叉树:非递归
 */
void TreeNodeIn(BiTree tr)
{
    std::stack<BiNode *> s;
    BiNode *p = tr;
    while (!s.empty() || p)
    {
        if (p)
        {
            s.push(p);
            p = p->lchild;
        }
        else
        {
            p = s.top();
            s.pop();
            std::cout << char(p->data) << " ";
            p = p->rchild;
        }
    }
}

/**
 * 中序遍历二叉树:递归
 */
void VisitTreeIn(BiTree tr)
{
    if (tr != NULL)
    {
        VisitTreeIn(tr->lchild);
        std::cout << char(tr->data) << " ";
        VisitTreeIn(tr->rchild);
    }
}

/**
 * 层次遍历二叉树,
 */
void VisitTreeLevel(BiTree tr)
{
    std::queue<BiNode *> q;
    BiNode *p = tr;
    q.push(p);
    while (!q.empty())
    {
        p = q.front();
        q.pop();
        if (p)
        {
            std::cout << char(p->data) << " ";
            q.push(p->lchild);
            q.push(p->rchild);
        }
    }
}

/***
 * 二叉树自下而上,自左到右的层次遍历算法
 */
void ReverseVisitTreeLevel(BiTree tr)
{
    std::stack<BiNode *> s;
    std::queue<BiNode *> q;
    BiNode *p = tr;
    q.push(p);
    while (!q.empty())
    {
        p = q.front();
        q.pop();
        if (p)
        {
            s.push(p);
            q.push(p->lchild);
            q.push(p->rchild);
        }
    }
    while (!s.empty())
    {
        p = s.top();
        s.pop();
        std::cout << char(p->data) << " ";
    }
}

/**
 * 非递归算法求解二叉树的高度
 */
int GetHeight(BiTree tr)
{
    if (!tr)
        return 0;
    std::queue<BiNode *> q;
    BiNode *p = tr, *r = tr;
    int height = 0;
    q.push(p);
    while (!q.empty())
    {
        p = q.front();
        q.pop();
        if (p->lchild)
            q.push(p->lchild);
        if (p->rchild)
            q.push(p->rchild);
        if (p == r)
        {
            height += 1;
            r = q.back();
        }
    }
    return height;
}

/**
 * 递归算法求解二叉树的高度
 */
int GetHeightCircle(BiTree tr)
{
    if (tr)
    {
        int hleft = GetHeight(tr->lchild) + 1;
        int hright = GetHeight(tr->rchild) + 1;
        return hleft > hright ? hleft : hright;
    }
    else
    {
        return 0;
    }
}

/***
 * 二叉树各个值不同,先序和中序遍历序列分别存于数组A[1..n],B[1....n]中,
 * 算法建立该二叉树链表
 */
BiTree BuildTreeBeforeAndIn(int A[], int B[], int h1, int t1, int h2, int t2)
{
    BiNode *root = (BiNode *)malloc(sizeof(BiNode));
    root->data = A[h1]; //找到根节点
    //std::cout << root->data << " ";
    int i;
    for (i = h2; B[i] != A[h1]; i++)
        ;
    int llen = i - h2; //以根为中间节点,划分左右
    int rlen = t2 - i;
    //std::cout << llen << " " << rlen << " " << std::endl;
    if (llen != 0)
        root->lchild = BuildTreeBeforeAndIn(A, B, h1 + 1, h1 + llen, h2, h2 + llen - 1);
    else
        root->lchild = NULL;
    if (rlen != 0)
        root->rchild = BuildTreeBeforeAndIn(A, B, h1 + llen + 1, t1, h2 + llen + 1, t2);
    else
        root->rchild = NULL;
    return root;
}

/***
 * 二叉树用二叉链表形式存储,
 * 写一个判定二叉树是否是完全二叉树的算法
 * 
 * 思路:层次遍历,遇到空节点,检查队列是否有节点
 */
bool isCompleteTree(BiTree tr)
{
    std::queue<BiNode *> q;
    BiNode *p = tr;
    q.push(p);
    int id = tr->data;
    while (!q.empty())
    {
        p = q.front();
        q.pop();
        if (p)
        {
            q.push(p->lchild);
            q.push(p->rchild);
        }
        else
        {
            while (!q.empty())
            {
                p = q.front();
                q.pop();
                if (p)
                    return false;
            }
        }
    }
    return true;
}

/**
 * 二叉树采用二叉链表存储,尝试设计一个算法,
 * 计算一颗给定二叉树的所有双分支节点数
 */
int DoubleNodeNumber(BiTree tr)
{
    int num = 0;
    std::queue<BiNode *> q;
    BiNode *p = tr;
    q.push(p);
    while (!q.empty())
    {
        p = q.front();
        q.pop();

        if (p)
        {
            q.push(p->rchild);
            q.push(p->lchild);
        }
        if (p && p->lchild && p->rchild)
        {
            num += 1;
        }
    }
    return num;
}

/***
 * 把二叉树中,所有节点的左右子树交换
 */
void ExchangeLeftAndRight(BiTree tr)
{
    if (tr)
    {
        ExchangeLeftAndRight(tr->lchild);
        ExchangeLeftAndRight(tr->rchild);
        BiNode *tmp = tr->lchild;
        tr->lchild = tr->rchild;
        tr->rchild = tmp;
    }
}

调用:

BiTree_use.cpp
#include "BiTree.h"
int main()
{
    int A[9] = {'1', '2', '3', '4', '5', '6', '7', '8'};
    int B[9] = {
        '4',
        '3',
        '2',
        '5',
        '1',
        '7',
        '6',
        '8',
    };
    BiTree tr2 = BuildTreeBeforeAndIn(A, B, 0, 7, 0, 7);
    VisitTreeLevel(tr2);
    std::cout << std::endl;
    if (isCompleteTree(tr2))
        std::cout << "二叉树是完全二叉树" << std::endl;
    else
        std::cout << "二叉树不是完全二叉树" << std::endl;
    std::cout << "二叉树双分支节点个数:" << DoubleNodeNumber(tr2) << std::endl;
    ExchangeLeftAndRight(tr2);
    VisitTreeLevel(tr2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值