数据结构--二叉树的基本操作

首先通过一张图来认识树:
这里写图片描述
树:由N(N>=0)个结点构成的集合。对N>1的树,有:
1.有一个特殊的结点,称为根结点,根结点没有前驱结点
2.除根结点外,其余结点被分为M(M>0)个互不相交的集合T1、T2…..Tm,其中每一个集合Ti(1<=i<=m)有是一颗结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。,因此,树是递归定义的。代码实现多采用递归的思想。

二叉树的遍历:

遵循某种次序,遍历二叉树中的所有结点,使得每个结点被访问一次,而且仅访问一次。“访问”:即对根结点施行某些操作。
前序遍历:先访问根结点,再前序遍历根结点的左子树,最后前序遍历根结点的右子树。
中序遍历:先中序遍历根结点的左子树,再访问根结点,最后中序遍历根结点的右子树。
后序遍历:先后序遍历根结点的左子树,再后序遍历根结点的右子树,最后访问根结点。
层序遍历:按照二叉树的层序次序(即从根结点层到叶结点层),同一层中按先左子树再右子树的次序遍历二叉树。
例如:如下一棵树,它的前序、中序、后序、层序遍历
这里写图片描述
代码实现:

bin_tree.h

  1 #pragma once                                                 
  2 #include <stdio.h>
  3 typedef char TreeNodeType;
  4 //使用孩子表示法来表示一棵树
  5 typedef struct TreeNode {
  6     TreeNodeType data;
  7     struct TreeNode* lchild;
  8     struct TreeNode* rchild;
  9 }TreeNode;
 10 
 11 //对于链表来说,使用链表的头节点指针来表示一个链表
 12 //对于二叉树来说,使用跟结点的指针来表示一棵树
 13 //树的初始化
 14 void TreeInit(TreeNode** pRoot);
 15 //前序遍历
 16 void TreePreOrder(TreeNode* root);
 17 //中序遍历
 18 void TreeInOrder(TreeNode* root);
 19 //后序遍历
 20 void TreePostOrder(TreeNode* root);
 21 //层序遍历
 22 void TreeLevelOrder(TreeNode* root);
 23 
 24 //输入一个数组(数组中的每个元素就是树上的结点),根据数组的内容
 25 //构建出一颗树,数组中元素的内容符合树的先序遍历结果(包含所有空结点)
 26 TreeNode* TreeCreate(TreeNodeType arry[],size_t size,char null_node);
 27 
 28 //求二叉树中结点的个数                                                                                      
 29 size_t TreeSize(TreeNode* root);
 30 //求二叉树中叶子结点的个数
 31 size_t TreeLeafSize(TreeNode* root);
 32 //求二叉树中第K层结点的个数
 33 size_t TreeKLevelSize(TreeNode* root,int K);
 34 
 35 //求二叉树的高度/深度
 36 size_t TreeHeight(TreeNode* root);
 37 
 38 void TreeDestroy(TreeNode* root);
 39 
 40 //在二叉树中查找结点,给定一个数值,求出对应结点的指针
 41 //假设二叉树中的结点是不重复的
 42 TreeNode* TreeFind(TreeNode* root,TreeNodeType to_find);
 43 
 44 //求出child的父节点
 45 TreeNode* FindParent(TreeNode* root,TreeNode* child);
 46 
 47 //求出当前节点的左子树和右子树
 48 TreeNode* LChild(TreeNode* node);
 49 TreeNode* RChild(TreeNode* node);    

bin_tree.c

1 #include <stdio.h>                                                                                          
  2 #include <stdlib.h>
  3 #include "bin_tree.h"
  4 #include "seqqueue.h"
  5 
  6 TreeNode* CreateTreeNode(TreeNodeType value){
  7     TreeNode* new_node = (TreeNode*)malloc(sizeof(TreeNode));
  8     new_node->data = value;
  9     new_node->lchild = NULL;
 10     new_node->rchild = NULL;
 11     return new_node;
 12 }
 13 
 14 void DestroyTreeNode(TreeNode* node){
 15     free(node);
 16 }
 17 
 18 void TreeInit(TreeNode** pRoot){
 19     if(pRoot == NULL){                                                                                      
 20         //非法输入
 21         return;
 22     }
 23     *pRoot = NULL;
 24     return;
 25 }
 26 
 27 void TreePreOrder(TreeNode* root){
 28     if(root == NULL){
 29         //空树
 30         return;
 31     }
 32     //先访问根结点,访问即打印
 33     printf("%c ",root->data);
 34     //然后递归的遍历左子树
 35     TreePreOrder(root->lchild);
 36     //最后在递归的遍历右子树
 37     TreePreOrder(root->rchild);
 38     return;
 39 }
 40 
 41 void TreeInOrder(TreeNode* root){
 42     if(root == NULL){
 43         //空树
 44         return;
 45     }
 46     //先递归的遍历左子树
 47     TreeInOrder(root->lchild);
 48     //再访问根结点
 49     printf("%c ",root->data);
 50     //最后递归的遍历右子树
 51     TreeInOrder(root->rchild);
 52     return;
 53 }
 54 
 55 void TreePostOrder(TreeNode* root){
 56     if(root == NULL){
 57         //空树
 58         return;
 59     }
 60     //先递归的遍历左子树
 61     TreePostOrder(root->lchild);
 62     //再递归的遍历右子树
 63     TreePostOrder(root->rchild);
 64     //最后访问根结点
 65     printf("%c ",root->data);
 66     return;
 67 }
 68 
 69 void TreeLevelOrder(TreeNode* root){
 70     if(root == NULL){
 71         //空树
 72         return;
 73     }                                                                                                       
 74     SeqQueue queue;
 75     SeqQueueInit(&queue);
 76     SeqQueuePush(&queue,root);
 77     while(1){
 78         SeqQueueType front;
 79         int ret = SeqQueueFront(&queue,&front);
 80         if(ret == 0){
 81             //如果队列取队首元素失败,说明队列为空
 82             //如果队列为空就说明遍历结束了
 83             break;
 84         }
 85         //访问树中的元素,打印当前值
 86         printf("%c ",front->data);
 87         //把当前队首元素出队列
 88         SeqQueuePop(&queue);
 89         //把当前元素的左右子树入队列
 90     
 91         if(front->lchild != NULL){
 92             SeqQueuePush(&queue,front->lchild);
 93         }
 94         if(front->rchild != NULL){                                                                          
 95             SeqQueuePush(&queue,front->rchild);
 96         }
97     }
 98     return;
 99 }
100 
101 TreeNode* _TreeCreate(TreeNodeType arry[],size_t size,size_t* index,TreeNodeType null_node){
102     if(index == NULL){
103         //非法输入
104         return NULL;
105     }
106     if(*index >= size){
107         return NULL;
108     }
109     if(arry[*index] == null_node){
110         return NULL;
111     }
112     TreeNode* new_node = CreateTreeNode(arry[*index]);
113     ++(*index);
114     new_node->lchild = _TreeCreate(arry,size,index,null_node);
115     ++(*index);                                                                                             
116     new_node->rchild = _TreeCreate(arry,size,index,null_node);
117     return new_node;
118 }
119 
120 TreeNode* TreeCreate(TreeNodeType arry[],size_t size,char null_node){
121     //表示当前取数组中的那个元素
122     size_t index = 0;
123     return _TreeCreate(arry,size,&index,null_node);
124 }
125 
126 TreeNode* TreeClone(TreeNode* root){
127     if(root == NULL){
128         //空树
129         return NULL;
130     }
131     //按照先序方式来遍历
132     TreeNode* new_node = CreateTreeNode(root->data);
133     new_node->lchild = TreeClone(root->lchild);
134     new_node->rchild = TreeClone(root->rchild);
135     return new_node;
136 }                                                                                                           
137 //销毁的过程中一定要保证左右子树能够被正确找到,所有按照后序的方式来销毁
138 void TreeDestroy(TreeNode* root){
139     if(root == NULL){
140         //空树
141         return;
142     }
143     //按照后序遍历的方式来销毁整个树
144     TreeDestroy(root->lchild);
145     TreeDestroy(root->rchild);
146     DestroyTreeNode(root);
147     return;
148 }
149 
150 //方法一
151 void _TreeSize(TreeNode* root,size_t* size){
152     if(root == NULL){
153         //空树
154         return;
155     }
156     //按照前序的方式遍历,这里的访问是++
157     ++(*size);                                                                                            
158     _TreeSize(root->lchild,size);
159     _TreeSize(root->rchild,size);
160 }
161 size_t TreeSize(TreeNode* root){
162     size_t size = 0;
163     _TreeSize(root,&size);
164     return size;
165 }
166 //方法二
167 size_t TreeSize(TreeNode* root){
168     if(root == NULL){
169         //空树
170         return 0;
171     }
172     return 1 + TreeSize(root->lchild) + TreeSize(root->rchild);
173 }
174 
175 size_t TreeLeafSize(TreeNode* root){
176     if(root == NULL){
177         //空树
178         return 0;                                                                                           
179     }
180     if(root->lchild == NULL && root->rchild == NULL){
181         //root是叶子结点
182         return 1;
183     }
184     //root不是叶子结点
185     return TreeLeafSize(root->lchild) + TreeLeafSize(root->rchild);
186 }
187 
188 size_t TreeKLevelSize(TreeNode* root,int K){
189     if(root == NULL || K < 1){
190         //root等于空是空树,K<1是非法输入
191        return 0;
192     }
193     if(K == 1){
194       return 1;
195     }
196     return TreeKLevelSize(root->lchild ,K - 1) + TreeKLevelSize(root->rchild,K - 1);
197 
198 }
199                                                                                                             
200 size_t TreeHeight(TreeNode* root){
201     if(root == NULL){
202         //空树
203         return 0;
204     }
205     if(root->lchild == NULL && root->rchild == NULL){
206         return 1;
207     }
208     size_t lheight = TreeHeight(root->lchild);
209     size_t rheight = TreeHeight(root->rchild);
210 
211     return 1 + (lheight > rheight ? lheight : rheight);
212 }
213 
214 TreeNode* TreeFind(TreeNode* root,TreeNodeType to_find){
215     if(root == NULL){
216         //空树
217         return NULL;
218     }
219     if(root->data == to_find){
220         return root;                                                                                        
221     }
222     TreeNode* lresult = TreeFind(root->lchild,to_find);
223     TreeNode* rresult = TreeFind(root->rchild,to_find);
224     //不等于空,说明找到了
225     return lresult != NULL ? lresult : rresult;
226 }
227 
228 TreeNode* FindParent(TreeNode* root,TreeNode* child){
229     if(root == NULL || child == NULL){
230         return NULL;
231     }
232     if(root->lchild == child || root->rchild == child){
233         return root;
234     }
235     TreeNode* lresult = FindParent(root->lchild,child);
236     TreeNode* rresult = FindParent(root->rchild,child);
237     return lresult != NULL ? lresult : rresult;
238 }
239 
240 TreeNode* LChild(TreeNode* node){
241     if(node == NULL){                                                                                       
242         return NULL;
243     }
244     return node->lchild;
245 }
246 
247 TreeNode* RChild(TreeNode* node){
248     if(node == NULL){
249         return NULL;
250     }
251     return node->rchild;
252 }

猜你喜欢

转载自blog.csdn.net/liru_1996/article/details/80187914