二叉树

1.二叉树的结构
顺序表    ->查找快,新增删除慢;
链表    ->查找慢,新增删除快;
二叉树    ->查找、新增、删除都比较快;
 
二叉树结构:
 
满二叉树:所有的节点都是有数据的
 
完全二叉树:从右往左看,右边的元素可以不满,左边的元素必须是满的
 
二叉树的一些常用概念:
    根节点    ->第一个元素就是根节点,例如上图中的节点1;
    父节点    ->相对于子节点来说的,例如上图中1是2的父节点,2是的父节点;
    子节点    ->与父节点相反;
    左子树    ->如果一个节点下面没有子节点,该节点叫叶子;
                  ->父节点下面的子节点可能是叶子节点,也可能是树;
                  ->二叉树的父节点最多有2个子节点;
                  ->左边的子节点称为左子树;                     
    右子树    ->父节点右边的子节点称为右子树;
 
2.二叉树的高度
二叉树的层级数称为高度;
 
例如:下图中以a为根节点二叉树高度为5;
    以b为根节点二叉树高度为4;
 
3.二叉树的遍历
二叉树有3中常用的遍历方式:
    1】前序遍历:(根 左 右)   
        对上图中的树遍历结果:GDAFEMHZ
 
    2】中序遍历:(左 根 右)
        结果:ADEFGHMZ        
 
    3】后序遍历:(左 右 根)  
        结果:AEFDHZMG
 
 
4.区分二叉树和双向链表
二叉树和双向链表的反汇编结果类似;都是一大堆数据,然后有2个地址;
追踪到地址处又是相同的结构:一堆数据其中有2个地址;
也有可能是一堆数据,有3个地址的结构,如果是这样一定是二叉树,3个地址分别为左子树、右子树、父节点;
 
5.练习三种遍历
中序遍历的思路:
    拿上面的图来分析;
    中序遍历规则为输出顺序:左 根 右
    
    然后从下往上将拆解的子树替换,得到遍历顺序;
    例如:用GDH替换左子树1,得到顺序GDHBE,然后用GDHBE替换左子树,得到顺序GDHBEA右子树;
        
 
头文件:
#ifndef TREENODE_H
#define TREENODE_H
 
 
#include "stdio.h"
#include "stdlib.h"
#include "windows.h"
 
 
class Monster                            
{                            
public:                            
    int ID;                        
    int Level;                        
    char Name[20];                        
public:                            
    Monster(){}                        
    Monster(int ID,int Level,char* Name)                        
    {                        
        this->ID = ID;                    
        this->Level = Level;                    
        memcpy(&this->Name,Name,strlen(Name)+1);                    
    }                        
};                            
                            
template<class T>                            
class TreeNode{                            
public:                            
    T element;                    //当前节点存储的数据    
    TreeNode<T>* pLeft;                    //指向左子节点的指针    
    TreeNode<T>* pRight;                    //指向右子节点的指针    
                            
    TreeNode(T& ele){                        
        //初始化Node节点                    
        memset(&element,0,sizeof(TreeNode));                    
        //为元素赋值                    
        memcpy(&element,&ele,sizeof(T));                    
        pLeft = pRight = NULL;                    
    }                        
};                            
                            
template<class T>                            
class BSortTree{                            
public:                            
    BSortTree();                    //构造函数    
    ~BSortTree();                    //析构函数    
public:                            
    void InOrderTraverse(TreeNode<T>* pNode);                    //中序遍历    
    void PreOrderTraverse(TreeNode<T>* pNode);                    //前序遍历    
    void PostOrderTraverse(TreeNode<T>* pNode);                    //后序遍历    
    TreeNode<T>* GetRoot();                    //返回根节点    
    int GetDepth(TreeNode<T>* pNode);                    //返回某个节点的高度/深度    
private:                            
    void Init();
    void Clear(TreeNode<T>* pNode);
private:                            
    TreeNode<T>* m_pRoot;                    //根结点指针    
    int size;                    //树中元素总个数    
};                            
                            
template<class T>                             
BSortTree<T>::BSortTree()                            
{                            
    Init();                        
}                            
template<class T>                             
BSortTree<T>::~BSortTree(){                                                    
    //释放所以节点空间                        
    Clear(m_pRoot);
}                            
                            
template<class T>                             
void BSortTree<T>::Init()                            
{                                                    
    Monster m1(1,1,"刺猬");                        
    Monster m2(2,2,"野狼");                        
    Monster m3(3,3,"野猪");                        
    Monster m4(4,4,"士兵");                        
    Monster m5(5,5,"火龙");                        
    Monster m6(6,6,"独角兽");                        
    Monster m7(7,7,"江湖大盗");                        
                            
    TreeNode<Monster>* n1 = new TreeNode<Monster>(m1);                        
    TreeNode<Monster>* n2 = new TreeNode<Monster>(m2);                        
    TreeNode<Monster>* n3 = new TreeNode<Monster>(m3);                        
    TreeNode<Monster>* n4 = new TreeNode<Monster>(m4);                        
    TreeNode<Monster>* n5 = new TreeNode<Monster>(m5);                        
    TreeNode<Monster>* n6 = new TreeNode<Monster>(m6);                        
    TreeNode<Monster>* n7 = new TreeNode<Monster>(m7);                        
                            
    m_pRoot = n5;                        
    n5->pLeft = n4;                        
    n5->pRight = n6;                        
    n4->pLeft = n1;                        
    n1->pRight = n2;                        
    n6->pLeft = n3;                        
    n3->pRight = n7;                        
    size = 7;                        
    /*                        
                     5
                    / \                
                   4   6    
                  /   /    
                 1    3        
                  \    \
                   2    7        
                            
    */                        
}
 
//删除节点
template<class T>
void BSortTree<T>::Clear(TreeNode<T>* pNode){
    if(pNode != NULL){    
        Clear(pNode->pLeft);
        Clear(pNode->pRight);
        delete pNode;
        pNode = NULL;
    }
}
                            
template<class T>                             
TreeNode<T>* BSortTree<T>::GetRoot()                            
{                            
    return m_pRoot;                        
}                            
template<class T>                            
int BSortTree<T>::GetDepth(TreeNode<T>* pNode)                            
{                            
     if(pNode==NULL)                             
    {                            
    return 0;                          
    }                            
    else                              
    {                              
        int m = GetDepth(pNode->pLeft);                              
        int n = GetDepth(pNode->pRight);                              
        return (m > n) ? (m+1) : (n+1);                               
    }                              
}        
 
//中序遍历所有怪物,列出怪的名字                    
template<class T>                             
void BSortTree<T>::InOrderTraverse(TreeNode<T>* pNode)                            
{                                                    
        if(pNode != NULL){
        InOrderTraverse(pNode->pLeft);
        printf("%d:%s\t",*(int*)(&(pNode->element)),(char*)((int)(&(pNode->element))+8));    //用指针强转的方式读取结构中的值
        InOrderTraverse(pNode->pRight);    
    }                
                            
}                            
 
//前序遍历所有怪物,列出怪的名字                                
template<class T>                             
void BSortTree<T>::PreOrderTraverse(TreeNode<T>* pNode)                            
{    
    if(pNode!=NULL)                             
    {                            
        printf("%d:%s\t",pNode->element.ID,pNode->element.Name);
        PreOrderTraverse(pNode->pLeft);
        PreOrderTraverse(pNode->pRight);                    
    }                        
}                            
 
//后序遍历所有怪物,列出怪的名字                            
template<class T>                             
void BSortTree<T>::PostOrderTraverse(TreeNode<T>* pNode)                            
{                            
                            
    if(pNode != NULL){
        PostOrderTraverse(pNode->pLeft);
        PostOrderTraverse(pNode->pRight);
        printf("%d:%s\t",pNode->element.ID,pNode->element.Name);
    }                                
                            
}                            
 
#endif

 

测试:
#include "TreeNode.h"
 
void main(){
    BSortTree<Monster>* tree = new BSortTree<Monster>;
 
    //前序遍历
    printf("前序遍历\n");
    tree ->PreOrderTraverse(tree->GetRoot());
    printf("\n");
 
    //后序遍历
    printf("后序遍历\n");
    tree ->PostOrderTraverse(tree->GetRoot());
    printf("\n");
 
    //中序遍历
    printf("中序遍历\n");
    tree ->InOrderTraverse(tree->GetRoot());
    printf("\n");
    
    getchar();
}

 

结果:
 
 
 
 
 
posted @ 2019-12-06 08:34  L丶银甲闪闪  阅读(361)  评论(0编辑  收藏  举报