算法9---完全二叉树

算法9---完全二叉树

树结构的基本特征

(1)在一个树结构中,有且仅有一个节点没有直接前驱,这个节点就是树的根节点;

(2)除了根节点外,其余结个节点有且仅有一个直接前驱;

(3)每个结点都可以有任意多个直接后继;

树有一些基本的概念要清楚

父结点和子结点;

兄弟结点;

结点的度;

树的度;

叶结点;

分支结点;

结点的层数;

树的深度;

有序树;

无序树;

森林;

首先二叉树有两种表示方式,一种是使用数组结构来进行顺序存储,

如下

1 #define MAXLEN 100
2 typedef char DATA;
3 typedef DATA seqbitree[MAXLEN];
4 seqbitree bt;//定义保存二叉树的数组

还有一种方式是采用链表的方法进程存储,大多数情况下都是以这种方式;

这种链式存储结构的定义方式如下:

 1 #define MAXLEN 100
 2 typedef char DATA;
 3 typedef struct chainTree
 4 {
 5     DATA nodeData;
 6
 7     struct chainTree *lsonNode;
 8     struct chainTree *rsonNode;
 9     struct chainTree *parentNode;
10 }chainTreeType;

二叉树的完整的操作具体实现如下。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <conio.h>
  4
  5 #define MAXLEN 20
  6 typedef char DATA;
  7 typedef struct CBT
  8 {
  9     DATA data;
 10     struct CBT *left;
 11     struct CBT *right;
 12 }CBTType;
 13
 14 CBTType *initTree()
 15 {
 16     CBTType *node;
 17     if (node=(CBTType *)malloc(sizeof(CBTType)))
 18     {
 19         printf("please input the root! \n");
 20         scanf("%s",&node->data);
 21         node->left=NULL;
 22         node->right=NULL;
 23         if (node!=NULL)
 24         {
 25             return node;
 26         }
 27         else
 28             return NULL;
 29
 30     }
 31     return NULL;
 32 }
 33
 34
 35 //查询节点是否存在
 36 CBTType *Treefindnode(CBTType *treeNode,DATA data)
 37 {
 38
 39
 40     if (treeNode==NULL)
 41     {
 42         return NULL;
 43     }
 44     else
 45     {
 46         if (treeNode->data==data)
 47         {
 48             return treeNode ;
 49         }
 50         else
 51         {
 52             if (treeNode=Treefindnode(treeNode->left,data))
 53             {
 54                 return treeNode;
 55             }
 56             else if (treeNode=Treefindnode(treeNode->right,data))
 57             {
 58                 return treeNode;
 59             }
 60             else
 61                 return NULL;
 62         }
 63     }
 64 }
 65
 66 //增加结点
 67
 68 void AddTreeNode(CBTType *treeNode)
 69 {
 70     CBTType *pnode,*parent;
 71     DATA data;
 72     char flag;
 73     if (pnode=(CBTType*)malloc(sizeof(CBTType)))
 74     {
 75         printf("input the node data \n");
 76         fflush(stdin);
 77         scanf("%s",&pnode->data);
 78         pnode->left=NULL;
 79         pnode->right=NULL;
 80
 81         printf("input the node‘s parent node\n");
 82         fflush(stdin);
 83         scanf("%s",&data);
 84         parent=Treefindnode(treeNode,data);
 85         if (!parent)
 86         {
 87             printf("can‘t find the parent node!\n");
 88             free(pnode);
 89             return ;
 90         }
 91         printf("1.add to the left node!\n2.add to the right node!");
 92         do
 93         {
 94             flag=getch();
 95             flag-=‘0‘;
 96             if (flag==1||flag==2)
 97             {
 98                 if (parent==NULL)
 99                 {
100                     printf("no parent node,please give parent node first!\n");
101                 }
102                 else
103                 {
104                     switch(flag)
105                     {
106                         case 1:  //添加到左节点
107                             if (parent->left)  //左节点不为空
108                             {
109                                 printf("the lefe node is not empty!\n");
110                             }
111                             else
112                             {
113                                 parent->left=pnode;
114                             }
115                             break;
116                         case 2:
117                             if (parent->right)
118                             {
119                                 printf("the right node is not empty!\n");
120                             }
121                             else
122                                 parent->right=pnode;
123                             break;
124                         default:
125                             printf("useless parameter!\n");
126                     }
127                 }
128             }
129         }while(flag!=1&&flag!=2);
130
131     }
132 }
133
134
135 //获得左子树
136 CBTType *Treeleftnode(CBTType *treeNode)
137 {
138     if (treeNode)
139     {
140         return treeNode->left;
141     }
142     else
143         return NULL;
144 }
145
146
147 //获得右子树
148 CBTType *Treerightnode(CBTType *treeNode)
149 {
150     if (treeNode)
151     {
152         return treeNode->right;
153     }
154     else
155         return NULL;
156 }
157
158
159 //判断空树
160
161 int Treeisempty(CBTType *TreeNode)
162 {
163     if(TreeNode)
164         return 0;
165     else
166         return 1;
167 }
168
169 //计算二叉树的深度
170
171 int Treedepth(CBTType *treeNode)
172 {
173     int depleft,depright;
174     if (treeNode==NULL)
175     {
176         return 0;
177     }
178     else
179     {
180         depleft=Treedepth(treeNode->left);
181         depright=Treedepth(treeNode->right);
182         if (depleft>depright)
183         {
184             return depleft+1;
185         }
186         else
187             return depright+1;
188     }
189 }
190
191
192 //清空二叉树
193 void ClearTree(CBTType *treeNode)
194 {
195     if (treeNode)
196     {
197         ClearTree(treeNode->left);
198         ClearTree(treeNode->right);
199         free(treeNode);
200         treeNode=NULL;
201     }
202 }
203
204
205 //显示节点数据
206 void display(CBTType *p)
207 {
208     printf("%c",p->data);
209 }
210
211 //二叉树的遍历
212 //层次遍历
213 void levelTree(CBTType *treeNode)
214 {
215     CBTType *q[MAXLEN];
216     int head=0,tail=0;
217     if (treeNode)
218     {
219         tail=(tail+1)%MAXLEN;
220         q[tail]=treeNode;
221     }
222     while(head!=tail)
223     {
224         head=(head+1)%MAXLEN;
225         treeNode=q[head];
226         if (treeNode->left!=NULL)
227         {
228             tail=(tail+1)%MAXLEN;
229             q[tail]=treeNode->left;
230         }
231         if (treeNode->right!=NULL)
232         {
233             tail=(tail+1)%MAXLEN;
234             q[tail]=treeNode->right;
235         }
236     }
237 }
238
239
240
241 //先序遍历,中序遍历和后序遍历
242
243 void dlrTree(CBTType *p)
244 {
245     if(p)
246     {
247         printf("%c\n", p->data);
248         dlrTree(p->left);
249         dlrTree(p->right);
250     }
251 }
252
253 void ldrTree(CBTType *p)
254 {
255     if(p)
256     {
257         dlrTree(p->left);
258         printf("%c\n", p->data);
259         dlrTree(p->right);
260     }
261 }
262
263 void lrdTree(CBTType *p)
264 {
265     if(p)
266     {
267         dlrTree(p->left);
268         dlrTree(p->right);
269         printf("%c\n", p->data);
270     }
271 }
272
273
274 int main()
275 {
276     CBTType *root=NULL;
277     char flag1;
278     char flag2;
279     root =initTree();
280     do{
281         printf("please chose option to add node!\n");
282         printf("0.quit\t");
283         printf("1.add the bitree node.\n");
284         flag1=getch();
285         switch(flag1)
286         {
287             case ‘1‘:
288                 AddTreeNode(root);
289                 break;
290             case ‘0‘:
291                 break;
292             default:
293                 ;
294         }
295
296     }while(flag1!=‘0‘);
297
298
299     do{
300         printf("please chose the method to travese the tree,input 0 means quit!\n");
301         printf("1.xian xu bian li\t");
302         printf("2.zhong xu bian li\n");
303         printf("3.xian xu bian li\t");
304         printf("4.ceng ci bian li\n");
305         flag2=getch();
306         switch(flag2)
307         {
308             case ‘0‘:
309                 break;
310             case ‘1‘:
311                 printf("the answer of dlrTree travese:\n");
312                 dlrTree(root);
313                 printf("\n");
314                 break;
315             case ‘2‘:
316                 printf("the answer of ldrTree travese:\n");
317                 ldrTree(root);
318                 printf("\n");
319                 break;
320             case ‘3‘:
321                 printf("the answer of lrdTree travese:\n");
322                 lrdTree(root);
323                 printf("\n");
324                 break;
325             case ‘4‘:
326                 printf("the answer of levelTree travese:\n");
327                 levelTree(root);
328                 printf("\n");
329                 break;
330             default:
331                 ;
332         }
333     }while(flag2!=‘0‘);
334
335     printf("the depth of the tree is:%d\n", Treedepth(root));
336     ClearTree(root);
337     root=NULL;
338 }
时间: 2024-10-05 17:41:17

算法9---完全二叉树的相关文章

算法题---完全二叉树的判定

思想:根据完全二叉树的定义,对完全二叉树按照从上到下.从左到右的层次遍历,应该满足一下两条要求: ●某节点没有左孩子,则一定无右孩子 ●若某节点缺左或右孩子,则其所有后继一定无孩子 若不满足上述任何一条,均不为完全二叉树. void IsComplete_BiTree(BiTree T) { if (T == NULL) { cout << "NULL BITREE error!" << endl; return; } Node*Q[MAXSIZE];Node*

设计一个算法,判断一个二叉树是否为完全二叉树

思想:根据完全二叉树的定义,对完全二叉树按照从上到下.从左到右的层次遍历,应该满足一下两条要求: ●某节点没有左孩子,则一定无右孩子 ●若某节点缺左或右孩子,则其所有后继一定无孩子 若不满足上述任何一条,均不为完全二叉树. 算法思路:采用层序遍历算法,用cm变量值表示迄今为止二叉树为完全二叉树(其初值为1,一旦发现不满足上述条件之一,则置cm为0),bj变量值表示迄今为止所有节点均有左右孩子(其初值为1),一旦发现一个节点没有左孩子或没有右孩子时置bj为0),在遍历完毕后返回cm的值. 对应的算

C++算法之 判断是否为完全二叉树

判断完全二叉树: 完全二叉树,除最后一层外,每一层上的节点树都达到了最大值:在最后一层上只缺少右边的若干节点! 算法思路: 按层次(从上到下,从左到右)遍历二叉树,当遇到一个节点的左子树为空时,则该节点右子树必须为空,且后面遍历的节点左 右子树都必须为空,否则不是完全二叉树. 代码: bool IsCompleteBTree(BTree* pRoot) { if (pRoot == NULL) return false; queue<BTree *> q; q.push(pRoot); boo

数据结构与算法(八)-二叉树(斜二叉树、满二叉树、完全二叉树、线索二叉树)

前言:前面了解了树的概念和基本的存储结构类型及树的分类,而在树中应用最广泛的种类是二叉树 一.简介 在树型结构中,如果每个父节点只有两个子节点,那么这样的树被称为二叉树(Binary tree).其中,一个父结点的两个字节点分别叫做“左子节点”和“右子节点”.不过也不是所有父节点都有两个子节点,只有左子节点或者只有右子节点的情况也存在.另外,也会存在叶子结点,也就是一个子节点都没有的节点,唯一的限制就是每一个节点的子节点不能超过两个. 之前谈过的单向链表,是一种通过“指向下一个元素的指针”来连接

算法学习——Count Complete Tree Nodes (计算完全二叉树的节点数)

完全二叉树——若设二叉树的深度为h,除第 h 层外,其它各层 (1-h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树. 解题思路: 满二叉树有一个性质是节点数等于2^h-1(h为高度),所以可以这样判断节点的左右高度是不是一样,如果是一样说明是满二叉树,就可以用公式2^h-1(h为高度),如果左右不相等就递归计算左右节点. 具体代码如下: /** * Definition for a binary tree node. * public class Tr

常用数据结构算法 : 完全二叉树判别

import java.util.LinkedList; import java.util.Queue; /********************************************************** * 非递归方法,基本是层次遍历二叉树 依次检查每一个节点: * 1.当发现有一个节点的左子树为空,右子树不为空时 直接返回false. * 2.当发现有一个节点的左子树不为空,右子树为空时,置标志位为1. * 3.当发现有一个节点的左右子树均为空时,置标志位为1. ****

Java与算法之(7) - 完全二叉树

树 下图是一"棵"树的样子.树这个名称起的很形象,整个数据结构由根.枝.叶组成,其中1为根节点,2.3是1的子节点,4.5.6.8.9.10这几个没有子节点的节点称为叶节点. 节点的度:一个节点的子树的数量称为该节点的度.例如,图中节点2的度为3,节点3的度为2. 树的度:一棵树的度是指该树中节点的最大度数.如图中树的度是3. 节点的层数:每个节点都处在一定的层次上,图中根节点在第1层,2.3节点在第二层. 树的深度:一棵树中节点的最大层数称为树的深度.如中所示的树的深度为4. 二叉树

算法 排序NB二人组 堆排序 归并排序

参考博客:基于python的七种经典排序算法     常用排序算法总结(一) 序前传 - 树与二叉树 树是一种很常见的非线性的数据结构,称为树形结构,简称树.所谓数据结构就是一组数据的集合连同它们的储存关系和对它们的操作方法.树形结构就像自然界的一颗树的构造一样,有一个根和若干个树枝和树叶.根或主干是第一层的,从主干长出的分枝是第二层的,一层一层直到最后,末端的没有分支的结点叫做叶子,所以树形结构是一个层次结构.在<数据结构>中,则用人类的血统关系来命名,一个结点的分枝叫做该结点的"

《转》八大算法详细讲解

转自http://blog.csdn.net/jobbofhe/article/details/51426934 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序.堆排序或归并排序序. 快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短:

排序——堆排序算法

堆排序利用的完全二叉树这种数据结构所设计的一种算法,不过也是选择排序的一种. 堆实质上是满足如下性质的完全二叉树:k[i]<=k[2*i]&&k[i]<=k[2*i+1]或者k[i]>=k[2*i]&&k[i]>=k[2*i+1], 树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字. 堆分大顶堆和小顶堆:k[i]<=k[2*i]&&k[i]<=k[2*i+1]是小顶堆,k[i]>=k[2