【算法笔记第9节-树 】遍历

目录

1.常用操作

2.给定一棵二叉树的先序遍历序列和中序遍历序列,重建这颗二叉树。

3.给出一棵二叉树的后序遍历序列和中序遍历序列,求这棵二叉树的层序遍历序列。

4.二叉树静态化

5.树的静态写法

6. 二叉树静态化

7. 二叉查找树

8. 平衡二叉树

9. 并查集

10. 堆排序


  1. 常用操作

#include<stdio.h>
struct node
{
    int data;//数据域
    int layer;//层次
    node* lchild; //指向左子树 根节点的指针
    node* rchild;//指向右子树根结点的指针
};
//新建结点
node* newNode(int v)
{
    node* Node = new node;//申请一个node型变量的地址空间
    Node->data = v;//结点权值为v
    Node->lchild = Node->rchild = NULL;//初始状态下没有左右孩子
    return Node;
}
//二叉树的查找
void search(node* root, int x, int newdata)
{
    if(root==NULL)
    {
        return;//空树,死胡同(递归边界)
    }
    if(root->data==x)//找到数据域为x,把它修改为newdata
    {
        root->data = newdata;
    }
    search(root->lchild, x, newdata);
    search(root->rchild, x, newdata);
}

//insert函数将在二叉树中插入一个数据域为x的新结点
//注意根结点指针root要使用引用,否则插入不会成功
void insert(node *&root, int x)
{
    if(root==NULL)//空树,说明查找失败,也即插入位置(递归边界)
    {
        root = newNode(x);
        return;
    }
    if(由二叉树的性质,x应该插在左子树)
    {
        insert(root->lchild,x);
    }
    else
        insert(root->rchild, x);
}
//二叉树的建立
node* Create(int data[], int n)
{
    node *root = NULL;
    for(int i=0; i<n; i++)
        insert(root, data[i]);
    return root;//返回根结点
}

//先序遍历二叉树
void pre(node* root)
{
    if(root==NULL)
        return;//到达空树
    printf("%d\n", root->data);//访问根结点,例如将其数据域输出
    pre(root->lchild);//访问左子树
    pre(root->rchild);//访问右子树
}

//中序遍历二叉树
void pre(node* root)
{
    if(root==NULL)
        return;//到达空树
    pre(root->lchild);//访问左子树
    printf("%d\n", root->data);//访问根结点,例如将其数据域输出
    pre(root->rchild);//访问右子树
}

//后序遍历二叉树
void pre(node* root)
{
    if(root==NULL)
        return;//到达空树
    pre(root->lchild);//访问左子树
    pre(root->rchild);//访问右子树
    printf("%d\n", root->data);//访问根结点,例如将其数据域输出
}

//层次遍历
void level(node* root)
{
    queue<node*> q;//注意队列中是存地址
    root->layer = 1;
    q.push(root);//根结点入队
    while(!q.empty())
    {
        node *now = q.front();//取队首元素
        q.pop();
        printf("%d", now->data);//访问队首元素
        if(now->lchild!=NULL) 
        {   now->lchild->layer = now->layer+1;
            q.push(now->lchild);
        }
        if(now->rchild!=NULL) 
        {
            now->rchild->layer = now->layer+1;
            q.push(now->rchild);
        }
    }
}

 

  1. 给定一棵二叉树的先序遍历序列和中序遍历序列,重建这颗二叉树。

    #include<stdio.h>
    struct node
    {
        int data;//数据域
        node* lchild; //指向左子树 根节点的指针
        node* rchild;//指向右子树根结点的指针
    };
    int pre[50], in[50], post[50];//先序,中序,后序
    
    //先序和中序建表
    //当前先序序列区间为[preL, preR],中序序列区间为[inL, intR],返回根结点地址
    node* creat(int preL, int preR, int inL, int inR)
    {
        if(preL > preR)
            return NULL;
        node *root = new node;//新建一个节点,用来存放当前二叉树的根节点
        root->data = pre[preL];//新结点的数据域为根节点的值
        int k;
        for(k=inL; k<=inR; k++)
        {
            if(in[k]==pre[preL])//在中序序列中找到in[k]==pre[L]的结点
                break;
        }
        int numLeft = k-inL;//左子树的结点个数
        
        //左子树的先序区间[preL+1, preL+numLeft] 中序区间[inL, k-1]
        //返回左子树的根节点地址,赋值为root的左指针
        root->lchild = creat(preL+1, preL+numLeft, inL, k-1);
        
        //右字数的先序区间为[preL+numLeft+1, preR],中序区间为[k+1, inR]
        root->rchild = creat(preL+numLeft+1, preR, k+1, inR);
        return root;
    }
    
    

     

  2. 给出一棵二叉树的后序遍历序列和中序遍历序列,求这棵二叉树的层序遍历序列。

    #include<stdio.h>
    #include<queue>
    using namespace std;
    struct node
    {
        int data;//数据域
        node* lchild; //指向左子树 根节点的指针
        node* rchild;//指向右子树根结点的指针
    };
    int pre[50], in[50], post[50];//先序,中序,后序
    int n;
    
    //后序和中序建表
    node* creat(int postL, int postR, int inL, int inR)
    {
        if(postL > postR)
            return NULL;
        node *root = new node;//新建一个节点,用来存放当前二叉树的根节点
        root->data = post[postR];//新结点的数据域为根节点的值
        int k;
        for(k=inL; k<=inR; k++)
        {
            if(in[k]==post[postR])//在中序序列中找到in[k]==pre[L]的结点
                break;
        }
        int numLeft = k-inL;//左子树的结点个数
    
        root->lchild = creat(postL, postL+numLeft-1, inL, k-1);
    
        root->rchild = creat(postL+numLeft, postR-1, k+1, inR);
        return root;
    }
    int num = 0;
    void bfs(node* root)//层次遍历
    {
        queue<node*> q;
        q.push(root);
        while(!q.empty())
        {
            node *now = q.front();
            q.pop();
            printf("%d", now->data);
            num++;
            if(num<n) printf(" ");
            if(now->lchild!=NULL) q.push(now->lchild);
            if(now->rchild!=NULL) q.push(now->rchild);
        }
    }
    
    int main()
    {
        scanf(&#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值