数据结构之树与二叉树的基本操作的实现与应用

目录

一、二叉树的基本运算的算法

二、二叉树各种遍历算法

先序遍历

递归

非递归

中序遍历

递归

非递归

后序遍历

递归

非递归

层次遍历

三、在二叉树中查找值为x的节点,试设计打印值为x的节点的所有祖先的算法,假设值为x的节点不多于1个   

四、编程实现判别给定二叉树是否为完全二叉树   


一、二叉树的基本运算的算法

#include <iostream>
using namespace std;

#define MaxSize 100
typedef char ElemType;
typedef struct node
{
    ElemType data;       //数据元素
    struct node *lchild; //指向左孩子
    struct node *rchild; //指向右孩子
} BTNode;                //声明二叉树结点类型

void CreateBTree(BTNode *&b, char *str) //创建二叉树
{
    BTNode *St[MaxSize], *p;
    int top = -1, k, j = 0;
    char ch;
    b = NULL; //建立二叉树初始时为空
    ch = str[j];
    while (ch != '\0') //str未扫描时循环
    {
        switch (ch)
        {
        case '(': //开始处理左子树
            top++;
            St[top] = p;
            k = 1;
            break;
        case ')': //子树处理完成
            top--;
            break;
        case ',': //开始处理右子树
            k = 2;
            break;
        default:
            p = new BTNode();
            p->data = ch;
            p->lchild = p->rchild = NULL;
            if (b == NULL) //若b为空,p置为二叉树的根节点
            {
                b = p;
            }
            else //已建立二叉树的根节点
            {
                switch (k)
                {
                case 1:
                    St[top]->lchild = p;
                    break;
                case 2:
                    St[top]->rchild = p;
                    break;
                }
            }
        }
        j++;
        ch = str[j];
    }
}

void DestroyBTree(BTNode *&b) //销毁二叉树
{
    if (b == NULL)
    {
        return;
    }
    DestroyBTree(b->lchild); //递归销毁左子树
    DestroyBTree(b->rchild); //递归销毁右子树
    delete b;
    b = NULL;
}

BTNode *FindNode(BTNode *b, ElemType x) //查找值为x的结点
{
    if (b == NULL)
    {
        return NULL;
    }
    BTNode *p;
    if (b->data == x)
    {
        return b;
    }
    else
    {
        p = FindNode(b->lchild, x);
        if (p != NULL)
        {
            return p;
        }

        return FindNode(b->rchild, x);
    }
}

BTNode *LchildNode(BTNode *p) //返回p结点左孩子结点指针
{
    if (p == NULL)
    {
        return NULL;
    }

    return p->lchild;
}

BTNode *RchildNode(BTNode *p) //返回p结点右孩子结点指针
{
    if (p == NULL)
    {
        return NULL;
    }

    return p->rchild;
}

int BTHeight(BTNode *b) //求二叉树b的高度
{
    if (b == NULL)
    {
        return 0;
    }
    else
    {
        int lchildh = BTHeight(b->lchild); //求左子树的高度lchildh
        int rchildh = BTHeight(b->rchild); //求右子树的高度rchildh
        return lchildh > rchildh ? lchildh + 1 : rchildh + 1;
    }
}

void DispBTree(BTNode *b) //以括号表示法输出二叉树
{
    if (b == NULL)
    {
        return;
    }
    else
    {
        BTNode *p = b;
        cout << p->data;
        if (p->lchild != NULL || p->rchild != NULL)
        {
            cout << '(';//有孩子结点才输出(
            DispBTree(p->lchild);//递归处理左子树
            if(p->rchild!=NULL)//有右孩子结点才输出,
            {
                cout << ',';
            }
            DispBTree(p->rchild);//递归处理右子树
            cout << ')';//有孩子结点才输出)
        }
    }
}

二、二叉树各种遍历算法

先序遍历

递归

void PreOrder(BTNode *b) //先序遍历的递归算法
{
    if (b == NULL)
    {
        return;
    }
    cout << b->data << " "; //访问根节点
    PreOrder(b->lchild);    //递归访问左子树
    PreOrder(b->rchild);    //递归访问右子树
}

非递归

void PreOrder1(BTNode *b) //先序非递归遍历算法
{
    if (b == NULL)
    {
        return;
    }
    BTNode *p, *St[MaxSize];
    int top = -1;
    St[++top] = b;   //根结点进栈
    while (top > -1) //栈不为空时循环
    {
        p = St[top]; //访问该结点
        top--;       //退栈
        cout << p->data << " ";
        if (p->rchild != NULL) //有右孩子,将其进栈
        {
            St[++top] = p->rchild;
        }
        if (p->lchild != NULL) //有左孩子啊,将其进栈
        {
            St[++top] = p->lchild;
        }
    }
    cout << endl;
}

中序遍历

递归

void InOrder(BTNode *b) //中序遍历的递归算法
{
    if (b == NULL)
    {
        return;
    }
    InOrder(b->lchild);     //递归访问左子树
    cout << b->data << " "; //访问根结点
    InOrder(b->rchild);     //递归访问右子树
}

非递归

void InOrder1(BTNode *b) //中序非递归遍历算法
{
    if (b == NULL)
    {
        return;
    }
    BTNode *p, *St[MaxSize];
    int top = -1;
    p = b;
    while (p != NULL || top > -1)
    {
        while (p != NULL) //扫描结点p的所有左下结点并进栈
        {
            St[++top] = p;
            p = p->lchild;
        }
        if (top > -1) //出栈
        {
            p = St[top--]; //出栈结点p并访问
            cout << p->data << " ";
            p = p->rchild;
        }
    }
    cout << endl;
}

后序遍历

递归

void PostOrder(BTNode *b) //后序遍历的递归算法
{
    if (b == NULL)
    {
        return;
    }
    PostOrder(b->lchild);   //递归访问左子树
    PostOrder(b->rchild);   //递归访问右子树
    cout << b->data << " "; //访问根结点
}

非递归

void PostOrder1(BTNode *b) //后序非递归遍历算法
{
    if (b == NULL)
    {
        return;
    }
    BTNode *p, *St[MaxSize];
    bool flag;
    int top = -1;
    do
    {
        while (b != NULL) //将b结点的所有左下结点进栈
        {
            St[++top] = b;
            b = b->lchild;
        }
        p = NULL;    //p指向当前结点的前一个已访问的结点
        flag = true; //flag为真表示正在处理栈顶结点
        while (top != -1 && flag)
        {
            b = St[top];        //取出当前的栈顶元素
            if (b->rchild == p) //右子树不存在或已被访问,访问之
            {
                cout << b->data << " "; //访问b结点
                top--;
                p = b; //p指向被访问的结点
            }
            else
            {
                b = b->rchild; //b指向右子树
                flag = false;  //表示当前不是处理栈顶结点
            }
        }
    } while (top != -1);
    cout << endl;
}

层次遍历

void TravLevel(BTNode *b) //层次遍历
{
    BTNode *Qu[MaxSize]; //定义环形队列
    int front, rear;     //定义队首和队尾指针
    front = rear = 0;    //置队列为空
    if (b != NULL)
    {
        cout << b->data << " ";
    }
    rear++; //根节点进队
    Qu[rear] = b;
    while (rear != front) //队列不为空
    {
        front = (front + 1) % MaxSize;
        b = Qu[front];         //出结点b
        if (b->lchild != NULL) //输出左孩子并进队
        {
            cout << b->lchild->data << " ";
            rear = (rear + 1) % MaxSize;
            Qu[rear] = b->lchild;
        }
        if (b->rchild != NULL) //输出右孩子并进队
        {
            cout << b->rchild->data << " ";
            rear = (rear + 1) % MaxSize;
            Qu[rear] = b->rchild;
        }
    }
    cout << endl;
}

三、在二叉树中查找值为x的节点,试设计打印值为x的节点的所有祖先的算法,假设值为x的节点不多于1个   

        根据题目要求,需要输出值为X的结点的所有祖先结点的值,没有对祖先结点顺序有要求。

         根据二叉树种祖先的定义可知,若结点p的结点的左孩子或右孩子是结点q,则结点p是结点q的祖先;

        若结点p的左孩子或右孩子是q结点的祖先,则结点p也是结点q的祖先。

         设f(b,x)表示结点b是否为值是x的结点的祖先,若结点b是值为x的结点的祖先,f(b,x)返回true;否则返回flase。

         当f(b,x)分为true时,输出结点p的值。

        求值为X的结点所有祖先的递归模型f(b,x)如下:

         f(b,x)=false            若b==NULL

         f(b,x)=true             若结点b的左孩子或右孩子的data域为x

         f(b,x)=false            若f(b->lchild,x)为true或f(b->rchild,x)为true

         f(b,x)=false            其它情况

bool ancestor(BTNode *b, ElemType x)
{
    if (b == NULL)
    {
        return false;
    }
    else if (b->lchild != NULL && b->lchild->data == x || b->rchild != NULL && b->rchild->data == x)
    {
        cout << b->data << " ";
        return true;
    }
    else if (ancestor(b->lchild, x) || ancestor(b->rchild, x))
    {
        cout << b->data << " ";

        return true;
    }
    else
    {
        return false;
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值