码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构-树

时间:2019-11-24 15:39:07      阅读:51      评论:0      收藏:0      [点我收藏+]

标签:end   对象   bool   void   dep   保存   二叉树的遍历   creat   修改   

树:
     n(n≥0)个结点构成的有限集合
     
     性质:
        树中有一个称为“根(Root)”的特殊结点,用 r 表示
        其余结点可分为m(m>0)个互不相交的有限集T1,T2,... ,Tm,其 中每个集合本身又是一棵树,称为原来树的“子树(SubTree)” 
        子树是不相交的
        除了根结点外,每个结点有且仅有一个父结点;
        一棵N个结点的树有N-1条边。 
        
    树的基本术语:
        1. 结点的度(Degree):结点的子树个数 
        2. 树的度:树的所有结点中最大的度数 
        3. 叶结点(Leaf):度为0的结点 
        4. 父结点(Parent):有子树的结点是其子树 的根结点的父结点 
        5. 子结点(Child):若A结点是B结点的父结 点,则称B结点是A结点的子结点;子结点也 称孩子结点。 
        6. 兄弟结点(Sibling):具有同一父结点的各 结点彼此是兄弟结点。 
        7. 路径和路径长度:从结点n1到nk的路径为一 个结点序列n1 , n2 ,… , nk , ni是 ni+1的父结 点。路径所包含边的个数为路径的长度。 
        9.  祖先结点(Ancestor):沿树根到某一结点路 径上的所有结点都是这个结点的祖先结点。 
        10.  子孙结点(Descendant):某一结点的子树 中的所有结点是这个结点的子孙。 
        11. 结点的层次(Level):规定根结点在1层, 其它任一结点的层数是其父结点的层数加1。 
        12. 树的深度(Depth):树中所有结点中的最 大层次是这棵树的深度。 
        
    使用儿子-兄弟表示发可以使用二叉树表示度大于2的树

    
二叉树:
    二叉树T:一个有穷的结点集合。 
    这个集合可以为空       
    若不为空,则它是由根结点和称为其左子树TL和右子树TR的 两个不相交的二叉树组成。     
        
    二叉树的子树有左右顺序之分     
    
    特殊二叉树:
        斜二叉树
        完美二叉树 /满二叉树
        完全二叉树:有n个结点的二叉树,对树中结点按 从上至下、从左到右顺序进行编号, 编号为i(1 ≤ i ≤ n)结点与满二叉树 中编号为 i 结点在二叉树中位置相同 
    
    二叉树的几个重要性质:
        一个二叉树第 i 层的最大结点数为: 2^(i-1),i>=1。
         深度为k的二叉树有最大结点总数为: 2^(k-1),k>=1。 
        对任何非空二叉树 T,若n0表示叶结点的个数、n2是 度为2的非叶结点个数,那么两者满足关系n0 = n2 +1。 
    
    二叉树的抽象数据类型定义 :
        类型名称:二叉树 数据对象集:一个有穷的结点集合。      若不为空,则由根结点和其左、右二叉子树组成。 
 
        操作集: BT? BinTree, Item ? ElementType,重要操作有: 
        1、Boolean IsEmpty( BinTree BT ): 判别BT是否为空; 
        2、void Traversal( BinTree BT ):遍历,按某顺序访问每个结点; 
        3、BinTree CreatBinTree( ):创建一个二叉树。

    二叉树的遍历:
        先序----根、左子树、右子树; 
        中序---左子树、根、右子树; 
        后序---左子树、右子树、根 
        层次遍历,从上到下、从左到右 
        
    二叉树的存储结构:
        1.顺序存储结构:
            完全二叉树:按从上至下、从左到右顺序存
    
            一般二叉树也可以采用这种结构,但会造成空间浪费…… 
        
        2.链表存储 
            每个节点包含三个域:
                data:保存节点的值
                left:指针,指向左儿子
                right:指针,指向右儿子
                
                
    二叉树的遍历:    
        递归遍历:
            先序
            void PreOrderTraversal( BinTree BT ) {     
                if( BT ) {         
                    printf(“%d”, BT->Data);         
                    PreOrderTraversal( BT->Left );         
                    PreOrderTraversal( BT->Right );     
                } 
            } 
            中序
            void PreOrderTraversal( BinTree BT ) {     
                if( BT ) {      
                    PreOrderTraversal( BT->Left );                        
                    printf(“%d”, BT->Data);                
                    PreOrderTraversal( BT->Right );     
                } 
            } 
            后序
            void PreOrderTraversal( BinTree BT ) {     
                if( BT ) {      
                    PreOrderTraversal( BT->Left );                                      
                    PreOrderTraversal( BT->Right );    
                    printf(“%d”, BT->Data);  
                } 
            } 
    
        非递归遍历:
            中序遍历非递归遍历算法 :
                遇到一个结点,就把它压栈,并去遍历它的左子树; 
                当左子树遍历结束后,从栈顶弹出这个结点并访问它
                然后按其右指针再去中序遍历该结点的右子树。 
                void InOrderTraversal( BinTree BT ) {  
                    BinTree T=BT; 
                    Stack S = CreatStack( MaxSize ); /*创建并初始化堆栈S*/ 
                    while( T || !IsEmpty(S) ){     
                        while(T){   /*一直向左并将沿途结点压入堆栈*/         
                            Push(S,T);          
                            T = T->Left;      
                        }     
                        if(!IsEmpty(S)){         
                            T = Pop(S); /*结点弹出堆栈*/         
                            printf(“%5d”, T->Data); /*(访问)打印结点*/         
                            T = T->Right; /*转向右子树*/     
                        } 
                    } 
                }     
            先序遍历非递归遍历算法 :
                void InOrderTraversal( BinTree BT ) {  
                    BinTree T=BT; 
                    Stack S = CreatStack( MaxSize ); /*创建并初始化堆栈S*/ 
                    while( T || !IsEmpty(S) ){     
                        while(T){   /*一直向左并将沿途结点压入堆栈*/  
                            printf(“%5d”, T->Data); /*(访问)打印结点*/         //就移动了这一行
                            Push(S,T);          
                            T = T->Left;      
                        }     
                        if(!IsEmpty(S)){         
                            T = Pop(S); /*结点弹出堆栈*/         
                            T = T->Right; /*转向右子树*/     
                        } 
                    } 
                }     
    
            层序遍历 
                队列实现:遍历从根结点开始,首先将根结点入队,然后开始执 行循环:结点出队、访问该结点、其左右儿子入队
                
            
            先序和中序遍历序列或者后序和中序遍历序列来确定一棵二叉树 
            
二叉搜索树:
    也称二叉排序树或二叉查找树     
    二叉搜索树:一棵二叉树,可以为空;如果不为空,满足以下性质:         
        非空左子树的所有键值小于其根结点的键值。     
        非空右子树的所有键值大于其根结点的键值    
        左、右子树都是二叉搜索树。     
            
    二叉搜索树的查找:先和根节点比较,比根节点小则去左子树找,否则去右子树找,依次往下找知道找到指定的值
        最大元素一定是在树的最右分枝的端结点上     
        最小元素一定是在树的最左分枝的端结点上 
    二叉搜索树的插入 :关键是要找到元素应该插入的位置,可以采用与Find类似的方法         
    二叉搜索树的删除,三种情况:
        1.要删除的是叶结点:直接删除,并再修改其父结点指针---置为NULL     
        2.要删除的结点只有一个孩子结点:将其父结点的指针指向要删除结点的孩子结点 
        3.要删除的结点有左、右两棵子树: 
            用另一结点替代被删除结点:右子树的最小元素 或者 左子树的最大元素 


        
    

 

数据结构-树

标签:end   对象   bool   void   dep   保存   二叉树的遍历   creat   修改   

原文地址:https://www.cnblogs.com/liuxuelin/p/11922244.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!