数据结构之二叉树(数组)

本文详细介绍了二叉树的定义、形态和相关术语,并通过代码展示了如何使用数组来实现二叉树,包括树的基本操作如创建、搜索、添加、删除结点以及遍历。特别地,解释了如何利用数组索引来表示二叉树中父子结点的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二叉树的定义

  二叉树(binary tree)由结点的有限集合构成,这个有限集合或者为空集(empty),或者为由一个根结点(root)及两棵互不相交、分别称作这个根的左子树(left subtree)右子树(right subtree)的二叉树组成的集合。


二叉树的五种基本形态


二叉树相关术语

p二叉树是由唯一的起始结点引出的结点集合。这个起始结点称为根(root)

p二叉树中的任何非根结点都有且仅有一个前驱结点,称之为该结点的父结点(或称为双亲,parent)。根结点即为二叉树中唯一没有父结点的结点

p二叉树中的任何结点最多可能有两个后继结点,分别称为左子结点(或左孩子、左子女,left child)和右子结点(或右孩子,右子女,right child),具有相同父结点的结点之间互称兄弟结点(sibling)

p二叉树中结点的子树数目称为结点的度(degree)

p没有子结点的结点称为叶结点 (leaf,也称“树叶”或“终端结点”),叶结点的度为0

p除叶结点以外的那些非终端结点称为内部结点(或分支结点,internal node)

p父结点k与子结点k’之间存在一条有向连线<k, k>,称作边(edge)

p若二叉树中存在结点序列{k0k1,…,ks},使得<k0k1>< k1k2>,…,< ks-1ks>都是二叉树中的边,则称从结点k0到结点ks存在一条路径(path),该路径所经历的边的个数称为这条路径的路径长度(path length)。若有一条由 k到达ks的路径,则称kks的祖先(ancestor)ksk的子孙(descendant)

p断掉一个结点与其父结点的连接,则该结点与其子孙构成的树就称为以该结点为根的子树(subtree)

p从根结点到某个结点的路径长度称为结点的层数(level),根结点为第0层,非根结点的层数是其父结点的层数加1


数组实现二叉树

    课程要求:完成树的基本操作
    1、树的创建和销毁
    2、树中结点的搜索
    3、树中结点的添加和删除
    4、树中结点的遍历
    
    Tree(int size, int* pRoot);                                //创建树
    ~Tree();                                                //销毁树
    int* SearchNode(int nodeindex);                            //根据索引寻找结点
    bool AddNode(int nodeindex, int direction, int* pNode);    //添加结点
    bool DeleteNode(int nodeindex, int* pNode);                //删除结点
    void TreeTraverse();                                    //遍历结点

    关于数组与树之间的算法转换
    
    int tree[n]        3 5 8 2 6 9 7        父亲结点下标*2 + 1 = 该结点左孩子
                                              父亲结点下标*2 + 2 = 该结点右孩子 

        3(0)
    5(1)    8(2)
2(3)  6(4) 9(5)  7(6) 


[cpp]  view plain  copy
  1. <span style="font-size:18px;">/*****************数组实现二叉树tree.h*********************/  
  2. #ifndef _TREE_H  
  3. #define _TREE_H  
  4.   
  5. class Tree {  
  6.     int* m_pTree;  
  7.     int m_iSize;  
  8. public:  
  9.     Tree(int size, int* pRoot);                             //创建树  
  10.     ~Tree();                                                //销毁树  
  11.     int* SearchNode(int nodeindex);                         //根据索引寻找结点  
  12.     bool AddNode(int nodeindex, int direction, int* pNode); //添加结点  
  13.     bool DeleteNode(int nodeindex, int* pNode);             //删除结点  
  14.     void TreeTraverse();                                    //遍历结点  
  15. };  
  16.   
  17. #endif</span>  

[cpp]  view plain  copy
  1. <span style="font-size:18px;">/*****************数组实现二叉树tree.cpp*********************/  
  2. #include "tree.h"  
  3. #include <iostream>  
  4.   
  5. using namespace std;  
  6.   
  7. Tree::Tree(int size, int* pRoot)  
  8. {  
  9.     m_iSize = size;  
  10.     m_pTree = new int[size];  
  11.     for(int i = 0 ; i < size; i++)  
  12.     {  
  13.         m_pTree[i] = 0;  
  14.     }  
  15.     m_pTree[0] = *pRoot;  
  16. }  
  17.       
  18. Tree::~Tree()  
  19. {  
  20.     delete []m_pTree;  
  21.     m_pTree = NULL;  
  22. }  
  23.       
  24. int* Tree::SearchNode(int nodeindex)  
  25. {  
  26.     if(nodeindex < 0 || nodeindex >= m_iSize)  
  27.     {  
  28.         return NULL;  
  29.     }  
  30.     if(m_pTree[nodeindex] == 0)  
  31.     {  
  32.         return NULL;  
  33.     }  
  34.     return &m_pTree[nodeindex];  
  35. }  
  36.   
  37. bool Tree::AddNode(int nodeindex, int direction, int* pNode)  
  38. {  
  39.     if(nodeindex < 0 || nodeindex >= m_iSize)  
  40.     {  
  41.         return false;  
  42.     }  
  43.     if(m_pTree[nodeindex] == 0)  
  44.     {  
  45.         return false;  
  46.     }  
  47.       
  48.     if(direction == 0)  
  49.     {  
  50.         if(nodeindex*2+1 >= m_iSize)  
  51.         {  
  52.             return false;  
  53.         }  
  54.         if(m_pTree[nodeindex*2+1] != 0)  
  55.         {  
  56.             return false;  
  57.         }  
  58.         m_pTree[nodeindex*2+1] = *pNode;  
  59.     }  
  60.     if(direction == 1)  
  61.     {  
  62.         if(nodeindex*2+2 >= m_iSize)  
  63.         {  
  64.             return false;  
  65.         }  
  66.         if(m_pTree[nodeindex*2+2] != 0)  
  67.         {  
  68.             return false;  
  69.         }  
  70.         m_pTree[nodeindex*2+2] = *pNode;  
  71.     }  
  72.     return true;  
  73. }  
  74.   
  75. bool Tree::DeleteNode(int nodeindex, int* pNode)  
  76. {  
  77.     if(nodeindex < 0 || nodeindex >= m_iSize)  
  78.     {  
  79.         return false;  
  80.     }  
  81.     if(m_pTree[nodeindex] == 0)  
  82.     {  
  83.         return false;  
  84.     }  
  85.       
  86.     *pNode = m_pTree[nodeindex];  
  87.     m_pTree[nodeindex] = 0;  
  88.     return true;  
  89. }  
  90.   
  91. void Tree::TreeTraverse()  
  92. {  
  93.     for(int i = 0; i < m_iSize; i++)  
  94.     {  
  95.         cout<<m_pTree[i]<<"  ";  
  96.     }  
  97. }</span>  

[cpp]  view plain  copy
  1. <span style="font-size:18px;">#include "tree.h"  
  2. #include <iostream>  
  3.   
  4. using namespace std;  
  5.   
  6. int main()  
  7. {  
  8.     int root = 3;  
  9.     Tree *tree = new Tree(10, &root);  
  10.       
  11.     int node1 = 5;  
  12.     int node2 = 8;  
  13.     tree->AddNode(0, 0, &node1);  
  14.     tree->AddNode(0, 1, &node2);  
  15.       
  16.     int node3 = 2;  
  17.     int node4 = 6;  
  18.     tree->AddNode(1, 0, &node3);  
  19.     tree->AddNode(1, 1, &node4);  
  20.       
  21.     int node5 = 9;  
  22.     int node6 = 7;  
  23.     tree->AddNode(2, 0, &node5);  
  24.     tree->AddNode(2, 1, &node6);  
  25.       
  26.     tree->TreeTraverse();  
  27.     cout<<endl;  
  28.     int *p = tree->SearchNode(2);  
  29.     cout<<*p<<endl;  
  30.       
  31.     int node = 0;  
  32.     tree->DeleteNode(6, &node);  
  33.     cout<<"node = "<<node<<endl;  
  34.       
  35.     tree->TreeTraverse();  
  36.     cout<<endl;  
  37.       
  38.     return 0;  
  39. }</span>  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值