二叉树(链式结构)

 

 

  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5 #include <conio.h>
  6 
  7 #define MAXLEN 20;                                //最大长度
  8 
  9 typedef char DATA;                                //定义元素类型
 10 typedef struct CBT                                //定义二叉树结点类型
 11 {
 12     DATA data;                                    //元素数据
 13     struct CBT *left;                            //左子树结点指针
 14     struct CBT *right;                            //右子树结点指针
 15 }CBTType;
 16 
 17 CBTType *InitTree()                                //初始化二叉树的根
 18 {
 19     CBTType *node;
 20 
 21     if(node=(CBTType *)malloc(sizeof(CBTType)))    //申请内存
 22     {
 23         printf("请先输入一个根结点数据:\n");
 24         scanf("%c",&node->data);
 25         node->left = NULL;
 26         node->right = NULL;
 27 
 28         if(node!=NULL)                            //如果二叉树根结点不为空
 29         {
 30             return node;
 31         }
 32         else
 33         {
 34             return NULL;
 35         }
 36         return NULL;
 37     }
 38 }
 39 
 40 CBTType *TreeFindNode(CBTType *treeNode, DATA data)        //查找结点
 41 {
 42     CBTType *ptr;
 43 
 44     if(treeNode == NULL)
 45     {
 46         return NULL;
 47     }
 48     else
 49     {
 50         if(treeNode->data == data)
 51         {
 52             return treeNode;
 53         }
 54         else
 55         {
 56             if(ptr=TreeFindNode(treeNode->left,data))            //分别向左右子树递归查找
 57             {
 58                 return ptr;
 59             }
 60             else if(ptr=TreeFindNode(treeNode->right,data))
 61             {
 62                 return ptr;
 63             }
 64             else
 65             {
 66                 return NULL;
 67             }
 68         }
 69     }
 70 }
 71 
 72 void AddTreeNode(CBTType *treeNode)                //添加结点
 73 {
 74     CBTType *pnode, *parent;
 75     DATA data;
 76     char menusel;
 77 
 78     if(pnode=(CBTType *)malloc(sizeof(CBTType)))    //分配内存
 79     {
 80         printf("输入二叉树结点数据:\n");
 81         fflush(stdin);
 82         scanf("%c",&pnode->data);
 83         pnode->left = NULL;
 84         pnode->right = NULL;                    //设置左右子树为空
 85 
 86         printf("请输入核结点父结点数据:");
 87         fflush(stdin);
 88         scanf("%c",&data);
 89         parent = TreeFindNode(treeNode,data);        //查找指定数据的结点
 90         if(!parent)                                    //如果未找到
 91         {
 92             printf("未找到该父结点!\n");
 93             free(pnode);                            //释放创建的结点内存
 94             return;
 95         }
 96         printf("1.添加该结点到左子树\n 2.添加该结点到右子树\n");
 97         do
 98         {
 99             menusel = _getch();                        //输入选择项
100             menusel -= '0';
101             if(menusel==1 || menusel==2)
102             {
103                 if(parent==NULL)
104                 {
105                     printf("不存在父结点,请先设置父结点!\n");
106                 }
107                 else
108                 {
109                     switch (menusel)
110                     {
111                     case 1:                                //添加到左结点
112                         if(parent->left)                    //左子树不为空
113                         {
114                             printf("左子树不为空!\n");
115                         }
116                         else
117                         {
118                             parent->left = pnode;
119                         }
120                         break;
121                     case 2:                                //添加到右结点
122                         if(parent->right)                //右子树不为空
123                         {
124                             printf("右子树不为空!\n");
125                         }
126                         else
127                         {
128                             parent->right = pnode;
129                         }
130                         break;
131                     default:
132                         printf("无效参数!\n");
133                         break;
134                     }
135                 }
136             }            
137         }while(menusel != 1 && menusel != 2);
138     }
139 }
140 
141 CBTType *TreeLeftNode(CBTType *treeNode)            //获取左子树
142 {
143     if(treeNode)
144     {
145         return treeNode->left;
146     }
147     else
148     {
149         return NULL;
150     }
151 }
152 
153 CBTType *TreeRightNode(CBTType *treeNode)            //获取右子树
154 {
155     if(treeNode)
156     {
157         return treeNode->right;
158     }
159     else
160     {
161         return NULL;
162     }
163 }
164 
165 int TreeIsEmpty(CBTType *treeNode)                    //判断空树
166 {
167     if(treeNode)
168     {
169         return 0;
170     }
171     else
172     {
173         return 1;
174     }
175 }
176 
177 int TreeDepth(CBTType *treeNode)                    //计算二叉树的深度
178 {
179     int depleft, depright;
180 
181     if(treeNode==NULL)
182     {
183         return 0;                                    //对于空树,深度为0
184     }
185     else
186     {
187         depleft = TreeDepth(treeNode->left);        //左子树深度(递归调用)
188         depright = TreeDepth(treeNode->right);        //右子树深度(递归调用)
189         if(depleft>depright)
190         {
191             return depleft + 1;
192         }
193         else
194         {
195             return depright +1;
196         }
197     }
198 }
199 
200 void ClearTree(CBTType *treeNode)                    //清空二叉树
201 {
202     if(treeNode)
203     {
204         ClearTree(treeNode->left);                    //清空左子树
205         ClearTree(treeNode->right);                    //清空右子树
206         free(treeNode);                                //释放当前结点所占内存
207         treeNode = NULL;
208     }
209 }
210 
211 void TreeNodeData(CBTType *p)                        //显示结点数据
212 {
213     printf("%c",p->data);                            //输出结点数据
214 }
215 
216 void DLRTree(CBTType *treeNode, void(*TreeNodeData)(CBTType *p))        //先序遍历
217 {
218     if(treeNode)
219     {
220         TreeNodeData(treeNode);                        //显示结点的数据
221         DLRTree(treeNode->left, TreeNodeData);
222         DLRTree(treeNode->right, TreeNodeData);
223     }
224 }
225 
226 void LDRTree(CBTType *treeNode, void(*TreeNodeData)(CBTType *p))        //中序遍历
227 {
228     if(treeNode)
229     {
230         LDRTree(treeNode->left, TreeNodeData);        //中序遍历左子树
231         TreeNodeData(treeNode);                        //显示结点数据
232         LDRTree(treeNode->right, TreeNodeData);        //中序遍历右子树
233     }
234 }
235 
236 void LRDTree(CBTType *treeNode, void(*TreeNodeData)(CBTType *p))        //后序遍历
237 {
238     if(treeNode)
239     {
240         LRDTree(treeNode->left, TreeNodeData);        //后序遍历左子树
241         LRDTree(treeNode->right, TreeNodeData);        //后序遍历右子树
242         TreeNodeData(treeNode);                        //显示结点数据
243     }
244 }
245 
246 void main()
247 {
248     CBTType *root = NULL;                            //root为指向二叉树根结点的指针
249     char menusel;
250     void(*TreeNodeData1)(CBTType *p);                //指向函数的指针
251     TreeNodeData1 = TreeNodeData;                    //指向具体操作的函数
252     //设置根元素
253     root = InitTree();
254     //添加结点
255     do
256     {
257         printf("请选择菜单添加二叉树的结点\n");
258         printf("0.退出\t");                            //显示菜单
259         printf("1.添加二叉树的结点\n");
260         menusel = _getch();
261         switch (menusel)
262         {
263         case '1':                                    //添加结点
264             AddTreeNode(root);
265             break;
266         case '0':
267             break;
268         default:
269             break;
270         }
271     }while(menusel!='0');
272 
273     //遍历
274     do
275     {
276         printf("请选择菜单遍历二叉树,输入0表示退出:\n");
277         printf("1.先序遍历DLR\t");                    //显示菜单
278         printf("2.中序遍历LDR\n");
279         printf("3.后序遍历LRD\t");
280         menusel=_getch();
281         switch (menusel)
282         {
283         case '0':
284             break;
285         case '1':                                    //先序遍历
286             printf("\n先序遍历DLR的结果: ");
287             DLRTree(root,TreeNodeData1);
288             printf("\n");
289             break;
290         case '2':                                    //中序遍历
291             printf("\n中序遍历的结果:");
292             LDRTree(root, TreeNodeData1);
293             printf("\n");
294             break;
295         case '3':                                    //后序遍历
296             printf("\n后序遍历LRD的结果:");
297             LRDTree(root,TreeNodeData1);
298             printf("\n");
299             break;
300         default:
301             break;
302         }
303     }while(menusel != '0');
304 
305     //深度
306     printf("\n二叉树深度为:%d\n",TreeDepth(root));
307 
308     ClearTree(root);                                //清空二叉树
309     root = NULL;
310 }
View Code

 

 

 

 

posted @ 2013-12-06 16:58  lmy4710  阅读(174)  评论(0)    收藏  举报