【数据结构】树


知识架构

在这里插入图片描述


相关代码

#include <iostream>
using namespace std;

/**
 * 1. 二叉树的存储结构
 */

//1.1 顺序存储
#define MaxSize 100
struct TreeNode {
    int value[MaxSize];
    bool isEmpty;
};


//1.2 链式存储
typedef struct BiTNode{
    int data;
    struct BiTNode *lchild,*rchild;
}BiTNode, *BiNode;


/**
 * 2. 二叉树的遍历
 */

//2.1 先序遍历:根左右

void PreOrder(BiNode T){
    if (T != NULL){
        cout << T->data << endl; // 访问根节点
        PreOrder(T->lchild); //遍历左子树
        PreOrder(T->rchild); //遍历右子树
    }
}

//2.2 中序遍历
void MidOrder(BiNode T){
    if (T != NULL){
        MidOrder(T->lchild); //遍历左子树
        cout << T->data << endl; // 访问根节点
        MidOrder(T->rchild); //遍历右子树

    }
}

//2.2 后序遍历
void PostOrder(BiNode T){
    if (T != NULL){
        PostOrder(T->lchild); //遍历左子树
        PostOrder(T->rchild); //遍历右子树
        cout << T->data << endl; // 访问根节点
    }
}


//2.3 求树的深度
int treeDepth(BiNode T){
    if (T == NULL){
        return 0;
    } else {
        int l = treeDepth(T->lchild);
        int r = treeDepth(T->rchild);
        return l>r ? l+1:r+1;
    }
}

//3. 线索二叉树

typedef struct ThreadNode{
    int data;
    struct ThreadNode *lchild,*rchild;
    int ltag,rtag;
}ThreadNode, *ThreadTree;

//辅助全局变量,用于查找结点p的前驱
ThreadNode *pre = NULL;//指向当前结点的前驱

//3.1 中序线索二叉树
void visit(ThreadTree q) {
    if (q->lchild == NULL){
        //左孩子为空,建立前驱索引
        q->lchild = pre;
        q->ltag = 1;
    }
    if (pre != NULL && pre->rchild == NULL){
        //前一个结点右孩子为空,指向当前结点(后继)
        pre->rchild = q;
        pre->rtag = 1;
    }
    pre =  q;
}

//!!!上面完成后,需要对最后一个结点进行处理,即pre结点,判断pre->rchild 是否为 NULL,是-》设置pre->rtag=1;

void InThread(ThreadTree T){
    if (T != NULL){
        InThread(T->lchild); //遍历左子树
        visit(T); // 访问根节点
        InThread(T->rchild); //遍历右子树
    }
}

//3.2 先序线索二叉树
void PreThread(ThreadTree T){
    visit(T);
    if (T->ltag != 1){
        //左孩子不是一个线索时
        PreThread(T->lchild);
    }

    PreThread(T->rchild);
}


7月24日

  1. 题目描述
    PIPI现在有两个序列,分别为二叉树的先序序列和二叉树的中序序列,他想由这两个序列还原二叉树,你能帮PIPI还原吗?
  2. 输入
    第一行输入序列的长度n (0<n<100).
    第二行输入二叉树的先序序列。
    第三行输入二叉树的中序序列。
  3. 输出
    输出二叉树的后序遍历序列。
  4. 样例输入
    6
    1 2 3 4 5 6
    3 2 4 1 6 5
  5. 样例输出
    3 4 2 6 5 1

想法应该没错,但是内存超限

#include<bits/stdc++.h>
using namespace std;

typedef struct BiNode{
    char data;
    struct BiNode *lChild;
    struct BiNode *rChild;
}*BiTree;

/**
 *
 * @param preSet 先序序列
 * @param midSet 中序序列
 * @param sSize  序列长度
 * @return  构造的二叉树
 */
struct BiNode *createWithMidAndPre(struct BiNode *root,char *preSet,char *midSet,int sSize) {
    if (0 == sSize)
        return NULL;

    root = (struct BiNode *) malloc(sizeof(struct BiNode));
    root->data = preSet[0]; //先序的第一个结点为根节点
    root->lChild = NULL;
    root->rChild = NULL;

    int p = 0;
    while (p < sSize) {
        //找到根节点在中序序列的位置
        if (midSet[p] == preSet[0])
            break;
        p++;
    }


    int leftSize = p;
    int rightSize = sSize - p - 1;

    root->lChild = createWithMidAndPre(root->lChild,
                                       preSet + 1, midSet, leftSize);

    root->rChild = createWithMidAndPre(root->rChild,
                                       preSet + leftSize + 1,
                                       midSet + leftSize + 1,
                                       rightSize);
    return root;
}


//后续遍历
void PostOrder(BiTree T){
    if (T != NULL){
        PostOrder(T->lChild); //遍历左子树
        PostOrder(T->rChild); //遍历右子树
        cout << T->data <<" "; // 访问根节点
    }
}



int main(){
    BiTree T;
    int n;
    char *pre,*mid;
    cin>>n;
    pre = (char *) malloc(sizeof(char)*n);
    mid = (char *) malloc(sizeof(char)*n);
    for (int i = 0; i < n; ++i){
        cin>>pre[i];
    }
    for (int i = 0; i < n; ++i){
        cin>>mid[i];
    }
    T = createWithMidAndPre(T,pre,mid,n);

    PostOrder(T);
    cout<<endl;
    free(pre);
    free(mid);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值