嵌入式学习26(数据结构 树)

本文介绍了树的基本概念,包括节点分类、节点的关系及树的存储方式等,并深入探讨了二叉树的特殊形状、遍历方法及其构建过程。
                     **树**

树:是n(n>=0)个节点的有限集合(n=0称为空树)。在任意一颗非空树中,(n=1)有且仅有一个特定的节点称为根节点,n>1时,其余节点(非根节点)可分为y个互不相交的有限集。
节点分类:
节点的度:每个节点拥有的子节点的个数
叶子节点:没有孩子的节点(度为0)
数的度:最大节点度
节点的关系:
孩子节点:节点的子树
双亲节点:相应拥有孩子的节点
兄弟节点:同一个双亲节点的
树的层次:
节点的层次:从根节点开始,根的子节点+1,直到此节点
树的层次(高度、深度):最大节点的层次
堂兄弟:在同一层次,但双亲不同
树的存储:(物理存储:顺序存储、链式存储)
顺序树形结构:用数组存储节点,表示出1:N
链式存储结构:用链表来存储节点
双亲法:每个节点只需记录父节点
优点:访问上层方便 缺点:访问子节点麻烦(必须从头到尾)
孩子法:每个节点只需要记录子节点,每个节点有树的度+1的空间
优点:访问子节点方便 缺点:浪费空间

                **二叉树**       

二叉数:是n(n>=0)个节点有限集合:(n==0空的二叉树),且由一个根节点和两棵互不相交的左右子节点的二叉树组成。
特殊的形状:(n<=3)
1. 空树:n=0
2. 只有一个根
3. 只有左子树
4. 只有右子树
斜树:所有节点在左(右)侧
满二叉树:所有节点都存在左右孩子,并且叶子节点在同一层上。
完全二叉树:从左往右,没有缺省

总结:
 在二叉树第i层最多2^(i-1)个节点
 层次为d的二叉树,最多有2^d -1个节点

print –>root (打印) left left 明确先访问还是先打印
left (访问) print->root right
right(访问) right print->root 递归
前序 中序 后序

遍历:每个节点都访问一次
层次:(从根开始)从上到下,从左往右 A->B->C->D->E->F->G
前序:先根,再左子树,再右子树 A->B->D->E->C->F->G
总结:第一个节点为根节点
中序:先左子树,再根,再右子树。D->B->E->A->F->C->G
总结:根节点在中间,根的左子树在根的左侧,根的右子树在根的右侧
后序: 先右再根再左 G->C->F->A->E->B->D

题目:给出前序:A-B-D-C-F ,中序B-D-A-C-F画出树的形状
1. A为根,左子树为BD,右子树CF
2. 对于左子树BD,B为根,D为B的右子树
3. 同理对于右子树CF,C为根,F为C的右子树
完工~

树的实现代码

#include<iostream>
using namespace std;
struct NODE 
{
//数据区
    char data;
//左右子树
    struct NODE* lchild;
    struct NODE* rchild;
};
typedef struct NODE Node,* pNode;

class tree
{
public:
    tree();//无参构造
    tree(const char*);//有参构造
    tree(tree&);//拷贝构造
    ~tree();
    bool CreateTree();  
    pNode GetRoot();//提供接口--返回root
    void PreOrderTraverse(pNode);//前序
    void InOrderTraverse(pNode);//中序
    void PostOrderTraverse(pNode);//后序


private:
    bool Create(pNode&);
    pNode root;
};
//创建树--提供外接口
bool tree::CreateTree()
{
    this->Create(this->root);
}
tree::tree():root(NULL){}
//有参构造
tree::tree(const char* str)
{

}
//拷贝构造
tree::tree(tree& t)
{
}
//析构函数
tree::~tree()
{
}
//构造树--前序(后序,层次)构建
bool tree::Create(pNode& ploc)      //ploc只是当前子树的别名
{
    int data;
    cout<<"please input:";
    cin>>data;

//如果str->当前字符为$,当前指向的孩子节点为NULL
    if(-1==data)
        ploc=NULL;
    else//如果有节点
    {
        data+='A';
//先构造子树的根节点
        ploc=new Node;
        ploc->data=data;//存储值
//构造子树
        Create(ploc->lchild);//递归
        Create(ploc->rchild);//递归
    }
}
pNode tree::GetRoot()
{
//返回地址
    return this->root;
}
//前序遍历
void tree::PreOrderTraverse(pNode ploc)//遍历当前节点的左右子树
{
//先(打印)根,再左子树,再右子树
    if(NULL==ploc)//没有子树
        return ;
    //只操作当前节点
    cout<<ploc->data<<" ";  //先打印
    //孩子操作交给下一次递归操作
    PreOrderTraverse(ploc->lchild); //遍历当前节点的左子树
    PreOrderTraverse(ploc->rchild); //遍历当前节点的右子树

}
//中序
void tree::InOrderTraverse(pNode ploc)
{
    if(NULL==ploc)
        return;
//先左 再中  再右
    InOrderTraverse(ploc->lchild);
    //当前节点操作
    cout<<ploc->data<<" ";
    InOrderTraverse(ploc->rchild);
}
//后序
void tree::PostOrderTraverse(pNode ploc)
{
//先左 再右  再中
    if(NULL==ploc)
        return;
    PostOrderTraverse(ploc->lchild);
    PostOrderTraverse(ploc->rchild);
    cout<<ploc->data<<" ";
}

int main()
{
//定义类:
    tree t;
//构造
    t.CreateTree(); 
//遍历
    cout<<"后序"<<endl;
    t.PostOrderTraverse(t.GetRoot());
    cout<<"中序"<<endl;
    t.InOrderTraverse(t.GetRoot());
    cout<<"前序"<<endl;
    t.PreOrderTraverse(t.GetRoot());

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值