数据结构——二叉树

Posted クトリ・ノタ・セニオリス

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构——二叉树相关的知识,希望对你有一定的参考价值。

树的一些基本术语(针对我个人觉得要必要列出来的

  • 结点的度:结点拥有的子树数。
  • 树的度:树内各结点度的最大值。
  • 非终端结点:度不为0的结点称为非终端结点或分支结点。除根结点外,非终端结点也称为内部结点。
  • 层次:根为第一层,不是第零层。
  • 树的深度:树中结点的最大层次,深度也称为高度。
  • 森林:是m(m>=0)棵互不相交的树的集合。对树中每个结点而言,其子树的集合即为森林。对森林加上一个根,森林即成为树;删去根,树即成为森林。

二叉树的一些性质:

  1. 在二叉树的第i层上至多有2i-1个结点(i>=1)。
  2. 深度为k的二叉树至多有2k-1个结点(k>=1)。
  3. 在任意一棵二叉树中,若终端结点(叶子结点)的个数为n0,度为2的结点数为n2,则n0=n2+1
  4. 包含n个结点的二叉树的高度至少为log2 (n+1)
  5. 具有n个结点的完全二叉树的深度为
      
    (注:[ ]表示向下取整)

二叉树的一些概念:

  • 满二叉树:深度为k且含有2k-1个结点的二叉树。(即除叶子结点外,所有结点都有左儿子和右儿子。
  • 完全二叉树:若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

 

                      

      满二叉树     

 

 

          

      完全二叉树   

 

 

      

    非完全二叉树

 


补充:

根据遍历序列确定一棵二叉树:

  先序序列+中序序列   >>>

    先:根左右 → 第一个一定是根

    中:左根右 → 根据先序找到一个根后,把序列由根划分成左子树和右子树

    对左子树和右子树进行同样的操作,直到子树为空。(可见也是一种递归思想。

  中序序列+后序序列   >>>

    后:左右根 → 序列的最后一个为根

    中:左根右 → 根据后序找到一个根后,把序列由根划分成左子树和右子树

    对左子树和右子树进行同样的操作,直到子树为空。(递归

  先序加后序是无法确定一颗二叉树的,因为由上可见,中序由先序或后序提供的根来确定左右子树,没有中序是无法完成这个递归过程的,也就无法确定一颗二叉树。


 

接下来就是二叉树的代码了,它实现了二叉树的基本存储结构和一些基本的操作:

  ps:这里注意一下先序遍历建立二叉树时的数据输入,要按根左右的顺序注意-1结束符的输入。

  例:1 2 3 -1 -1 4 5 -1 6 -1 -1 7 -1 -1 -1

  1 #include<iostream>
  2 #include<stdlib.h>
  3 #include<queue>        //层次遍历时要用到队列
  4 using namespace std;
  5 
  6 #define MAXSIZE 100
  7 typedef int ElemType;
  8 typedef int Status;
  9 
 10 //二叉链表存储表示
 11 typedef struct BiTNode
 12 {
 13     ElemType data;                        //结点数据域
 14     struct BiTNode *lchild, *rchild;    //左右孩子指针
 15 }BiTNode, *BiTree;
 16 
 17 //初始化,构造一个空树
 18 void InitBT(BiTree &T)
 19 {
 20     T = NULL;
 21 }
 22 
 23 //先序遍历建立二叉树
 24 void CreateBT(BiTree &T)
 25 {
 26     ElemType ch;
 27     cin >> ch;
 28     if (ch == -1)        //输入元素,以-1结束
 29         T = NULL;
 30     else
 31     {
 32         T = (BiTNode *)malloc(sizeof(BiTNode));        //分配内存空间
 33         T->data = ch;
 34         CreateBT(T->lchild);                        //递归建立其左子树
 35         CreateBT(T->rchild);                        //递归建立其右子树
 36     }
 37 }
 38 
 39 //检查二叉树是否为空,空返回1,非空返回0
 40 int EmptyBT(BiTree T)
 41 {
 42     if (T == NULL)
 43         return 1;
 44     else
 45         return 0;
 46 }
 47 
 48 //二叉树的深度
 49 int DepthBT(BiTree T)
 50 {
 51     if (T == NULL)    //空树深度为0
 52         return 0;
 53     else
 54     {
 55         int a = DepthBT(T->lchild);                //递归求左子树深度
 56         int b = DepthBT(T->rchild);                //递归求右子树深度
 57         return (a > b ? (a + 1) : (b + 1));        //取最大的即为树的深度,注意加1
 58     }
 59 }
 60 
 61 //查找二叉树BT中值为x的结点,若查找成功返回1,否则返回0
 62 int FindBT(BiTree T, ElemType x)
 63 {
 64     if (T == NULL)
 65         return 0;
 66     if (T->data == x)
 67         return 1;
 68     if (FindBT(T->lchild, x) || FindBT(T->rchild, x))    //递归在它的左子树和右子树里面找
 69         return 1;
 70     else
 71         return 0;
 72 }
 73 
 74 //先序遍历,根左右
 75 void  PreOrder(BiTree T)
 76 {
 77     if (T)    //树非空
 78     {
 79         cout << T->data << " ";
 80         PreOrder(T->lchild);
 81         PreOrder(T->rchild);
 82     }
 83 }
 84 
 85 //中序遍历,左根右
 86 void InOrder(BiTree T)
 87 {
 88     if (T)
 89     {
 90         InOrder(T->lchild);
 91         cout << T->data << " ";
 92         InOrder(T->rchild);
 93     }
 94 }
 95 
 96 //后序遍历,左右根
 97 void  PostOrder(BiTree T)
 98 {
 99     if (T)
100     {
101         InOrder(T->lchild);
102         InOrder(T->rchild);
103         cout << T->data << " ";
104     }
105 }
106 
107 //层次遍历
108 void  LevelOrder(BiTree T)
109 {
110     BiTree p;
111     if (T)
112     {
113         queue<BiTree>Q;        //创建一个队列Q
114         Q.push(T);            //将树入队
115         while (!Q.empty())    //队列非空
116         {
117             p = Q.front();
118             Q.pop();
119             cout << p->data << " ";
120             if (p->lchild)        //先左子树出队
121                 Q.push(p->lchild);
122             if (p->rchild)        //后右子树出队
123                 Q.push(p->rchild);
124         }
125     }
126 }
127 
128 //叶子结点个数
129 int  LeafCount(BiTree T)
130 {
131     if (!T)
132         return 0;
133     int count = 0;        //计数器
134     if (!T->lchild && !T->rchild)        //左右子树都为空,则为一个叶子结点
135     {
136         count++;
137     }
138     int a = LeafCount(T->lchild);        //递归求其左子树叶子结点数
139     int b = LeafCount(T->rchild);        //递归求其右子树叶子结点数
140     count += (a + b);
141     return count;
142 }
143 
144 //总结点数
145 int  NodeCount(BiTree T)
146 {
147     if (!T)
148         return 0;
149     else
150         return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;    //加一个根节点
151 }
152 
153 //清除二叉树
154 void ClearBTree(BiTree &T)
155 {
156     if (T)
157     {
158         ClearBTree(T->lchild);
159         ClearBTree(T->rchild);
160         delete T;
161         T = NULL;
162     }
163 }
164 
165 int main()
166 {
167     BiTree T;
168     int x;
169 
170     T = NULL;
171 
172     cout << "1.建立二叉树\\n";
173 
174     cout << "2.先序遍历二叉树\\n";
175 
176     cout << "3.中序遍历二叉树\\n";
177 
178     cout << "4.后序遍历二叉树\\n";
179 
180     cout << "5.层次遍历二叉树\\n";
181 
182     cout << "6.查找二叉树中元素\\n";
183 
184     cout << "7.计算二叉树的深度\\n";
185 
186     cout << "8.计算二叉树的叶子结点个数\\n";
187 
188     cout << "9.计算二叉树的结点总个数\\n";
189 
190     cout << "10.清除二叉树\\n";
191 
192     cout << "0.退出\\n";
193 
194     int choose = 0;
195 
196     while (choose != -1)
197     {
198         cout << "请选择你要执行的操作:";
199         cin >> choose;
200         switch (choose)
201         {
202         case 1:    //先序遍历建立二叉树
203             cout << "请输入二叉树中元素,以-1结束:";
204             CreateBT(T);
205             cout << "二叉树建立成功!" << endl;
206             break;
207         case 2:    //先序遍历输出二叉树
208             PreOrder(T);
209             cout << endl;
210             break;
211         case 3:    //中序遍历输出二叉树
212             InOrder(T);
213             cout << endl;
214             break;
215         case 4:    //后序遍历输出二叉树
216             PostOrder(T);
217             cout << endl;
218             break;
219         case 5:    //层次遍历输出二叉树
220             LevelOrder(T);
221             cout << endl;
222             break;
223         case 6:    //查找二叉树中是否存在元素x
224             cout << "请输入要查找的元素x:";
225             cin >> x;
226             if (FindBT(T, x))
227                 cout << "查找成功!" << endl;
228             else
229                 cout << "查找失败!" << endl;
230             break;
231         case 7:    //二叉树深度
232             cout << DepthBT(T) << endl;
233             break;
234         case 8:    //叶子结点数
235             cout << LeafCount(T) << endl;
236             break;
237         case 9:    //总结点数
238             cout << NodeCount(T) << endl;
239             break;
240         case 10://清除二叉树
241             ClearBTree(T);
242             cout << "清除成功!" << endl;
243             break;
244         case 0:    //退出
245             exit(0);
246             break;
247         }
248     }
249     system("pause");
250     return 0;
251 }

 

以上是关于数据结构——二叉树的主要内容,如果未能解决你的问题,请参考以下文章

数据结构中二叉树的顺序存储结构代码怎么编写?

数据结构二叉树经典基础习题

数据结构 二叉树的简单理解和代码实现

求数据结构算法平衡二叉树实现代码

输出二叉树树形的数据结构程序代码怎么写

求数据结构(C语言版)建立二叉树的代码~~急~~谢谢了