一步两步学算法之操作二叉树

操作二叉树代码比较长    二叉树基本功能在了  注释打的比较少

  1 #include "stdio.h"
  2 #include "stdlib.h"
  3 #define QUEUE_MAXSIZE 50
  4
  5 typedef char DATA;
  6 typedef struct ChainTree
  7 {
  8     DATA data;
  9     struct ChainTree *left;
 10     struct ChainTree *right;
 11 }ChainBinTree;
 12 void oper(ChainBinTree *p)
 13 {
 14     printf("%c",p->data);
 15     return;
 16 }
 17 ChainBinTree *BinTreeInit(ChainBinTree *node)  //初始化二叉树
 18 {
 19         if(node!=NULL)
 20             return node;
 21         else
 22             return NULL;
 23 }
 24
 25 int BinTreeAddNode(ChainBinTree *bt,ChainBinTree *node,int n)
 26                     //bt为父节点,node为子节点,n=1添加左子树,n=2添加右子树
 27 {
 28     if(bt==NULL)
 29     {
 30         printf("父节点不存在,请先设置父节点!\n");
 31         return 0;
 32     }
 33     switch(n)
 34     {
 35         case 1:
 36             if(bt->left)
 37             {
 38                 printf("左子树不为空!\n");
 39                 return 0;
 40             }
 41             else
 42                 bt->left=node;
 43             break;
 44         case 2:
 45             if(bt->right)
 46             {
 47                 printf("右子树不为空!\n");
 48                 return 0;
 49             }
 50             else
 51                 bt->right=node;
 52             break;
 53         default:
 54             printf("参数错误!\n");
 55             return 0;
 56     }
 57     return 1;
 58 }
 59
 60 ChainBinTree *BinTreeLeft(ChainBinTree *bt)  //返回左子树
 61 {
 62     if(bt)
 63         return bt->left;
 64     else
 65         return NULL;
 66 }
 67 ChainBinTree *BinTreeRight(ChainBinTree *bt)  //返回右子树
 68 {
 69     if(bt)
 70         return bt->right;
 71     else
 72         return NULL;
 73 }
 74
 75 int BinTreeIsEmpty(ChainBinTree *bt)
 76 {
 77     if(bt)
 78         return 0;
 79     else
 80         return 1;
 81 }
 82 int BinTreeDepth(ChainBinTree *bt)        //求二叉树深度
 83 {
 84     int dep1,dep2;
 85     if(bt==NULL)
 86         return 0;
 87     else
 88     {
 89         dep1=BinTreeDepth(bt->left);
 90         dep2=BinTreeDepth(bt->right);
 91         if(dep1>dep2)
 92             return dep1+1;
 93         else
 94             return dep2+1;
 95     }
 96 }
 97
 98 ChainBinTree *BinTreeFind(ChainBinTree *bt,DATA data)
 99 {
100     ChainBinTree *p;
101     if(bt==NULL)
102          return NULL;
103     else
104     {
105         if(bt->data==data)
106             return bt;
107         else
108         {
109             if(p=BinTreeFind(bt->left,data))
110                 return p;
111             else if(p=BinTreeFind(bt->right,data))
112                 return p;
113             else
114                 return NULL;
115         }
116     }
117 }
118 void BinTreeClear(ChainBinTree *bt)
119 {
120     if(bt)
121     {
122         BinTreeClear(bt->left);
123         BinTreeClear(bt->right);
124         free(bt);
125         bt=NULL;
126     }
127     return ;
128 }
129 void BinTree_DLR(ChainBinTree *bt,void (*oper)(ChainBinTree *p))
130 {
131     if(bt)
132     {
133         oper(bt);
134         BinTree_DLR(bt->left,oper);
135         BinTree_DLR(bt->right,oper);
136     }
137     return;
138 }
139 void BinTree_LDR(ChainBinTree *bt,void (*oper)(ChainBinTree *p))
140 {
141     if(bt)
142     {
143
144         BinTree_LDR(bt->left,oper);
145         oper(bt);
146         BinTree_LDR(bt->right,oper);
147     }
148     return;
149 }
150 void BinTree_LRD(ChainBinTree *bt,void (*oper)(ChainBinTree *p))
151 {
152     if(bt)
153     {
154
155         BinTree_LRD(bt->left,oper);
156         BinTree_LRD(bt->right,oper);
157         oper(bt);
158
159     }
160     return;
161 }
162
163 void BinTree_Level(ChainBinTree *bt,void (*oper)(ChainBinTree *p))
164 {
165     ChainBinTree *p;
166     ChainBinTree *q[QUEUE_MAXSIZE];
167     int head=0,tail=0;
168     if(bt)
169     {
170         tail=(tail+1)%QUEUE_MAXSIZE;
171         q[tail]=bt;
172     }
173     while(head!=tail)
174     {
175         head=(head+1)%QUEUE_MAXSIZE;
176         p=q[head];
177         oper(p);
178         if(p->left!=NULL)
179         {
180             tail=(tail+1)%QUEUE_MAXSIZE;
181             q[tail]=p->left;
182         }
183         if(p->right!=NULL)
184         {
185             tail=(tail+1)%QUEUE_MAXSIZE;
186             q[tail]=p->right;
187         }
188     }
189     return;
190 }
191
192 ChainBinTree *InitRoot()
193 {
194     ChainBinTree *node;
195     if(node=(ChainBinTree*)malloc(sizeof(ChainBinTree)))
196     {
197         printf("\n输入根节点数据:");
198         scanf("%s",&node->data);
199         node->left=NULL;
200         node->right=NULL;
201         return node;
202     }
203     return NULL;
204 }
205 void AddNode(ChainBinTree *bt)
206 {
207     ChainBinTree *node,*parent;
208     DATA data;
209     char select;
210     if(node=(ChainBinTree*)malloc(sizeof(ChainBinTree)))
211     {
212         printf("\n输入二叉树节点数据:");
213         fflush(stdin);
214         scanf("%s",&node->data);
215         node->left=NULL;
216         node->right=NULL;
217         printf("请输入父节点数据:");
218         fflush(stdin);
219         scanf("%s",&data);
220         parent=BinTreeFind(bt,data);
221         if(!parent)
222         {
223             printf("未找到父节点!\n");
224             free(node);
225             return ;
226
227         }
228         printf("1.添加到左子树\n2.添加到右子树\n");
229         do{
230             select=getchar();
231             select-=‘0‘;
232             if(select==1||select==2)
233                 BinTreeAddNode(parent,node,select);
234         }while(select!=1&&select!=2);
235     }
236     return ;
237 }
238 int main()
239 {
240     ChainBinTree *root=NULL;
241     char select;
242     void(*oper1)(ChainBinTree*);
243     oper1=oper;
244     do
245     {
246         printf("\n1.设置二叉树根元素        2.添加二叉树节点\n");
247         printf("3.先序遍历            4.中序遍历\n");
248         printf("5.后序遍历            6.按层遍历\n");
249         printf("7.二叉树深度            0.退出\n");
250
251         select=getchar();
252         if(select==‘\n‘){
253             select=getchar();
254         }
255         switch(select)
256         {
257             case ‘1‘:
258                 root=InitRoot();
259                 break;
260             case ‘2‘:
261                 AddNode(root);
262                 break;
263             case ‘3‘:
264                 printf("\n先序遍历的结果:");
265                 BinTree_DLR(root,oper1);
266                 printf("\n");
267                 break;
268             case ‘4‘:
269                 printf("\n中序遍历的结果:");
270                 BinTree_LDR(root,oper1);
271                 printf("\n");
272                 break;
273             case ‘5‘:
274                 printf("\n后序遍历的结果:");
275                 BinTree_LRD(root,oper1);
276                 printf("\n");
277                 break;
278             case ‘6‘:
279                 printf("\n按层遍历的结果:");
280                 BinTree_Level(root,oper1);
281                 printf("\n");
282                 break;
283             case ‘7‘:
284                 printf("\n二叉树的深度为:%d\n",BinTreeDepth(root));
285                 break;
286             case ‘0‘:
287                 break;
288         }
289     }while(select!=‘0‘);
290     BinTreeClear(root);
291     root=NULL;
292     return 0;
293 }
时间: 2024-10-09 20:16:59

一步两步学算法之操作二叉树的相关文章

一步两步学算法之哈夫曼编码(最优二叉树)

比较难理解的 都打了备注了 1 #include "stdio.h" 2 #include "stdlib.h" 3 #include "string.h" 4 char alphabet[]={'A','B','C','D'}; 5 typedef struct 6 { 7 int weight; //权值 8 int parent; //父节点序号 9 int left ; 10 int right; 11 }HuffmanTree; 12

一步两步学算法之顺序队列

顺序链表代码  非常简单: 但这个代码会有假溢出的状况出现: 就是在队尾已满的情况下,不断出队后 若在此时进行入队操作 判断队列已满的条件是q->head==q->tail 此时这个条件满足. 但实际队列之前已经出队了好几个,前面还有空余空间,这就是假溢出:(原谅我懒得画图) 假溢出解决办法 1.每次出队后 把所有数据都往前移.这种方法要移动大量数据,效率太低. 2.使用循环队列.这种方法明天再打. 1 #define QUEUEMAX 15 2 typedef struct 3 { 4 DA

一步两步学算法之树的遍历 非递归实现

递归的程序其实我觉得可读性较高  但是执行效率低下 为了做一道PAT的题 去理解了下非递归实现树的遍历 用一个栈来实现 先序遍历 先访问节点 再把节点push进栈 再访问 再push 直到next=NULL 然后pop出一个节点 也就是弹出一个节点 访问它的右边 再弹出 在访问 中序遍历 把左边节点全部push进栈 然后弹出 访问中间 再访问右边  再弹出 一直循环 后序遍历 比较难理解  要入两次栈才能访问 先左边全部入栈  栈顶是左边的元素 此书不能访问 因为右边还没入栈 下面给出先序和后序

一步两步学算法之图的广度搜索

bfs利用队列搜索    详细看代码 #define VERTEX_MAX 26 //图的最大定点数 #define MAXVALUE 32767 //最大值 #include "stdio.h" #define QUEUE_MAXSIZE 10 //队列最大容量 typedef struct { char Vertex[VERTEX_MAX]; //保存定点信息的数组 int Edges[VERTEX_MAX][VERTEX_MAX]; //边的权 int IsTrav[VERTEX

一步两步学算法之图邻接表实现

图的邻接表实现 这种结构创建邻接表时添加节点较为绕 建议断点调试下看看 邻接表和邻接矩阵相比 邻接表节省空间但是很难判断两个节点之间是否有边  此种结构要在稀疏图下才划算 下面是代码 1 #define VERTEX_MAX 20 2 #include "stdio.h" 3 #include "malloc.h" 4 typedef struct edgeNode 5 { 6 int Vertex; //顶点序号 7 int weight; 8 struct ed

一步两步学算法之最小生成树Prim算法

prim就是一个让树长大的过程  弄一个集合   从一个点开始不断向外搜索 找到权值最小的点 放进集合中  从这个集合所连的边再向外找 1 #define USED 0 2 #define NOADJ -1 3 void Prim(MaxtrixGraph G) 4 { 5 int i,j,k,min,sum=0; 6 int weight[VERTEX_MAX]; 7 char tmpvertex[VERTEX_MAX]; //临时顶点信息 8 9 for(i=1;i<G.VertexNum;

一步两步学算法之中序遍历线索二叉树

1 typedef enum 2 { 3 SubTree, //子树 4 Thread //线索 5 }NodeFlag; 6 7 typedef struct ThreadTree 8 { 9 DATA data; 10 NodeFlag lflag; 11 NodeFlag rflag; 12 struct ThreadTree *left; 13 struct ThreadTree *right; 14 }ThreadBinTree; 15 16 ThreadBinTree *Previo

一步两步学算法之二叉搜索树

Binary Search Tree  又叫二叉查找树,二叉排序树 这是种什么样的树呢? 其实就是根节点的左子树比根节点小  右子树比根节点大  同时 左子树和右子树也是二叉搜索树 代码比较简单 基本用递归实现 比较好理解  只有删除带有左右子树的节点时比较难理解 方法就是 直接在右子树找一个最小的节点 取代要被删除的节点 再继续删除右子树里的节点 详细看代码 1 #include "stdio.h" 2 #include "stdlib.h" 3 typedef

一步两步学算法之树的后序遍历 非递归实现

之前发过一篇博文  代码未测试直接发出来  被 @hoodlum1980 指出有错误 深表惭愧 参考了他的一篇关于后序遍历的文章 http://www.cnblogs.com/hoodlum1980/p/3901359.html   这是他的博文地址 又写了一遍代码  经测试通过 这个比较容易理解  给你一棵树 遍历每个节点 看它的左右儿子是否为空  若都为空或者flag都为1  则输出 flag为1的意思 就是之前已经输出了 详细看代码 1 typedef struct bintre 2 {