二叉树的基本操作————数据结构//复习复习复习

#include <bits/stdc++.h>
#define MAX 1000
using namespace std;
typedef struct node
{
    int INFO;
    struct node *LLINK, *RLINK; //用指针的原因 该结构体还未建成
} T;

//8.思路:在遍历结点时对其进行判定
void BianLi(T *root)
{
    static int num = 0; //这里设置为静态变量 函数结束内存不会释放
    if (root)
    {
        if (root->LLINK && root->RLINK)
            num++;
        BianLi(root->LLINK);
        BianLi(root->RLINK);
    }
}
//9.思路:对根节点先改变左右孩子 再进行遍历
void Change(T *root)
{
    if (root)
    {
        T *temp = root->LLINK;
        root->LLINK = root->RLINK;
        root->RLINK = temp;
        Change(root->LLINK);
        Change(root->RLINK);
    }
}
//10.思路:在先序遍历的基础上修改 将遍历的代码改成判断代码
int k; //在调用函数前进行赋值
void BianLi(T *root)
{
    static int num = 0; //这里设置为静态变量 函数结束内存不会释放
    if (root)
    {
        num++;
        if (num == k)
            printf("%d\n", root->INFO);
        BianLi(root->LLINK);
        BianLi(root->RLINK);
    }
}
//11.思路:在遍历时进行判定 相等就删除并标记其后代 不等继续遍历
int x; //调用函数前赋值
void Delet(T *root, bool flag)
{ //flag为标记 true表示该删
    if (root)
    {
        if (root->INFO == x || flag)
        { //满足条件或该删
            Delet(root->LLINK, true);
            Delet(root->RLINK, true);
            delete root; //对应创建空间的代码 这里对应 new
        }
        else
        {
            Delet(root->LLINK, false);
            Delet(root->RLINK, false);
        }
    }
}
//12.思路:没说是链式 采用数组
int Tree[MAX]; //调用函数前赋值
void print(int x, int n)
{ // n表示使用数组空间最大值
    int k = 0;
    for (int i = 0; i < n; i++)
    { //找x
        if (Tree[i] == x)
        {
            k = i;
            break;
        }
    }
    int mystack[MAX], len = 0;
    while (k)
    {//模拟入栈
        k /= 2; //利用了二叉树的特性
        mystack[len++] = Tree[k];
    }
    for (int i = len - 1; i >= 0; i--) //正向输出其祖先
        printf("%d ", mystack[i]);
}
/**
注:
后序非递归遍历的过程中,
栈中保留的是当前结点的所有祖先。
这是和先序及中序遍历不同的。
在某些和祖先有关的算法中,此算法很有价值。
**/
//13.思路:利用递归即栈的特性 若采取后续遍历 则遍历该节点时栈内全为其父结点
T *Ancestor(T *root, T *p, T *q)
{
    int mystack_n = 0, mystack1_n = 0, mystack2_n = 0;
    T *mystack[MAX], *mystack1[MAX], *mystack2[MAX];
    T *temp = root, *record = NULL;
    while (temp || mystack_n)
    {
        if (temp)
        {//一直找左孩子并入栈
            mystack[mystack_n++] = temp;
            temp = temp->LLINK;
        }
        else
        {
            temp = mystack[mystack_n - 1];//取栈头
            if (temp->INFO == p->INFO)
            { //找到p结点 就把栈复制 来存储p的祖先
                for (int i = 0; i < mystack_n; i++)
                    mystack1[i] = mystack[i];
                mystack1_n = mystack_n;
            }
            if (temp->INFO == q->INFO)
            { //找到q结点 就把栈复制 来存储q的祖先
                for (int i = 0; i < mystack_n; i++)
                    mystack2[i] = mystack[i];
                mystack2_n = mystack_n;
            }
            if (temp->RLINK && temp->RLINK != record)
            {
                temp = temp->RLINK; //到了没左孩子的时候走右孩子
                mystack[mystack_n++] = temp;
                temp = temp->LLINK; //temp已更新 可能存在左孩子
            }
            else
            {
                mystack_n--;   //退栈
                record = temp; //记录访问的结点用来防止重复入栈
                temp = NULL;   //下次访问时直接退栈
            }
        }
    }
    T *r = NULL;
    for (int i = mystack2_n - 1; i >= 0; i--)
    {
        for (int j = mystack1_n; j >= 0; j--)
        {
            if (mystack2[i]->INFO == mystack1[j]->INFO)
            { //对比两个栈的元素 本质是比较两个结点的祖先
                r = mystack1[j];
                break;
            }
        }
    }
    return r;
}
//14.思路:在层次遍历时记录每层的结点数 注意要在每层最后一个结点将数置零
int Width(T *root)
{
    int max = 0, num = 0;
    if (root)
    {
        int myqueue_h = 0, myqueue_t = 0;
        T *myqueue[MAX];             //模拟队列
        T *p, *q, *last = root;      //工作指针 标记指针 每层最后的指针
        myqueue[myqueue_t++] = root; //先让根入队列
        while (myqueue_h != myqueue_t)
        {
            p = myqueue[myqueue_h++]; //去队列的头
            if (p->LLINK)
            {
                myqueue[myqueue_t++] = p->LLINK;
                q = p->LLINK;
                num++;
            }
            if (p->RLINK)
            {
                myqueue[myqueue_t++] = p->RLINK;
                q = p->RLINK;
                num++;
            }
            if (p == last)
            { //判定是否为每层最后结点
                last = q;
                if (num > max)
                    max = num;
                num = 0;
            }
        }
    }
    return max;
}
//15.思路:利用满二叉树的特点
void PreToPost(int pre[], int low1, int high1, int post[], int low2, int high2)
{
    if (high1 >= low1)
    {
        post[high2] = pre[low1];
        int half = (high1 - low1) / 2; //在pre数组里half为前半部分 在post数组中为后半部分
        PreToPost(pre, low1 + 1, low1 + half, post, low2, low2 + half - 1);
        //去头后 数组pre的前半段是数组post数组的前半段去尾
        PreToPost(pre, low1 + half + 1, high1, post, low2 + half, high2 - 1);
        //数组pre的后半段是数组post数组的后半段去尾
    }
}
//16.思路:同8 在遍历时进行叶子结点的判定并操作
T *head, *q;
void BianLi(T *root)
{
    if (root)
    {
        if (!root->LLINK && !root->RLINK)
        { //当左右孩子都是空的
            if (!head)
            { //插头
                head = root;
                q = head;
            }
            else
            { //链表插入
                q->RLINK = root;
                q = root;
            }
        }
        BianLi(root->LLINK);
        BianLi(root->RLINK);
    }
}
//17.思路:直接递归模拟
bool Similar(T *root1, T *root2)
{
    if (root1 == NULL && root2 == NULL)
        return true; //空树
    else if (root1 == NULL || root2 == NULL)
        return false; //除了全空的话 有一个空就不相似
    else
        return Similar(root1->LLINK, root2->LLINK) && Similar(root1->RLINK, root2->RLINK);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值