一:初衷
我自己也好奇,为什么莫名其妙的想起写这个,其实数据里面包含的结构和逻辑我自己觉得才是最原始经典的,最近也在学swift,就向着利用swift整理一些二叉树。自己刚开始的时候也是用OC看着别的小伙伴的博客在写的,OC的逻辑是理清楚了,但用swift去写的时候,遇到些许问题,不是逻辑上的问题,就是语法问题。经过这两天的这个二叉树遇到的问题发现,还是觉得基础不够扎实。以为最基本的掌握了,其实不然,有好多东西还是欠火候!还是得静下心,就从最基本的开始吧!不知道有没有和我一样的小伙伴,基础你真的打好了吗?哈哈··
二:先利用OC写二叉树基本的创建和遍历
你可以先学习一些这些基本的一些概念,什么是二叉树,二叉树遍历的分类和基本规则。
1 二叉树的概念:点击—这是度娘给的答案,还是挺完整的,不知道的可以去看看它的基本概念和一些基本的性质。
2 二叉树的深度和宽度(下面代码有具体的说到)
3 二叉树遍历: 先序遍历 中序遍历 后序遍历 层次遍历 (这也是在度娘找的,答案很精辟)
三:OC 二叉树代码(从.H 文件到 .M 文件 再到 调用方法的顺序)
下面是 ZXTThreeObject.h 整个文件的代码,整个文件方便学习。里面思路的整理解释我全都加在代码注释里面了,仔细阅读就OK。
// Created by mxsm on 16/3/30. // Copyright © 2016年 mxsm. All rights reserved. // #import <Foundation/Foundation.h> @interface ZXTThreeObject : NSObject // 值 @property(nonatomic,assign)NSInteger Value; // 左节点 @property(nonatomic,strong) ZXTThreeObject * leftTreeNode; // 右节点 @property(nonatomic,strong) ZXTThreeObject * rightTreeNode; /* 基本方法 */ // 创建二叉树 +(ZXTThreeObject * )CreatTreesWithValues:(NSArray * )Values; // 计算二叉树的深度 +(NSInteger)DepthOfTree:(ZXTThreeObject * ) RootNode; // 计算二叉树的宽度 +(NSInteger)WidthOfTree:(ZXTThreeObject * )RootNode; // 先序遍历二叉树 +(void)XianXuBianLTreeNode:(ZXTThreeObject * ) RootTreeNode handle:(void(^)(ZXTThreeObject * Treenode))handle; // 中序遍历二叉树 +(void)ZhongXuBLTreeNode:(ZXTThreeObject * ) RootTreeNode handle:(void(^)(ZXTThreeObject * Treenode))handle; // 后序遍历二叉树 +(void)HouXuBLTreeNode:(ZXTThreeObject * ) RootNode handle:(void (^)(ZXTThreeObject * treenode))handle; // 层次遍历 +(void)CengCiBLTreeNode:(ZXTThreeObject * ) RootNode handle:(void(^)(ZXTThreeObject * treenode))handle; @end
下面是 ZXTThreeObject.m 的文件
// // ZXTThreeObject.m // sinatest // // Created by mxsm on 16/3/30. // Copyright © 2016年 mxsm. All rights reserved. // #import "ZXTThreeObject.h" @implementation ZXTThreeObject /* 创建二叉树 */ +(ZXTThreeObject * )CreatTreesWithValues:(NSArray * )Values { ZXTThreeObject * RootNode = nil; for (NSInteger i =0 ; i < Values.count; i++) { NSInteger vlaue = [Values[i]integerValue]; // 一直返回的是根节点 RootNode = [ZXTThreeObject addTreeNode:RootNode values:vlaue]; } return RootNode; } #pragma mark 添加节点 +(ZXTThreeObject * ) addTreeNode:(ZXTThreeObject * )treeNode values:(NSInteger)value { if (!treeNode) { treeNode=[[ZXTThreeObject alloc]init]; treeNode.Value=value; NSLog(@"节点:%ld",(long)value); } // value 值小于 节点的值 插入 左节点 else if (value <= treeNode.Value) { NSLog(@"-------to left"); treeNode.leftTreeNode = [self addTreeNode:treeNode.leftTreeNode values:value]; } // 否则就是右边的节点值 else { NSLog(@"=======to right"); treeNode.rightTreeNode = [self addTreeNode:treeNode.rightTreeNode values:value]; } NSLog(@"返回节点的值:%ld",(long) treeNode.Value); return treeNode; /* 这里调用的思想是递归的思想,递归大家应该都理解,但我不知道有多少孩纸和我一样,刚开始不理解其中的运行过程。 你要是理解了其中的运行过程,你也就理解了他的创建。。 */ /* 这里返回的 treeNode 这个参数其实是一个局部变量,不管上面嵌套调用多少次 +(ZXTThreeObject * ) addTreeNode:(ZXTThreeObject * )treeNode values:(NSInteger)value 这个方法,这里返回值 一次返回的一直都是 它的 最原始的根节点!! (很重要,但如果返回值你写成全局变量就不一样了,他返回的就是最后赋给它的值) (这里简单说一下,局部变量是存储在 栈 中的,全局变量是存储在静态存储区的!!每存储一个局部变量,编译器就会开辟一块 栈区域来保存 方法第一次传递的 treeNode 这个变量,编译器就开辟了 栈区域保存了它的值,后面要是有嵌套调用了这个方法,编译器就又开辟新的栈区域保存他们的返回值,但不会影响第一次保存的值,你要调用多次的话,第一个保存的值也就是最后一个返回的了,这就解释了为什么每次最后的返回值都是 最原始的根节点了!) NSArray * array= @[@"15",@"14",@"16",@"13",@"17",@"18",@"9",@"20",@"16",@"12",@"21",@"22",@"10",@"26",@"1"]; root= [ZXTThreeObject CreatTreesWithValues:array]; ** 以上面创建的数组为例 不管嵌套调用多少次,最后返回的 任然是 @“15” 这个节点,下面是打印的值!! 2016-04-05 11:57:29.532 sinatest[2005:339019] 节点:15 2016-04-05 11:57:29.532 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.532 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.532 sinatest[2005:339019] 节点:14 2016-04-05 11:57:29.532 sinatest[2005:339019] 返回节点的值:14 2016-04-05 11:57:29.532 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.533 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.533 sinatest[2005:339019] 节点:16 2016-04-05 11:57:29.533 sinatest[2005:339019] 返回节点的值:16 2016-04-05 11:57:29.533 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.533 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.533 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.533 sinatest[2005:339019] 节点:13 2016-04-05 11:57:29.533 sinatest[2005:339019] 返回节点的值:13 2016-04-05 11:57:29.533 sinatest[2005:339019] 返回节点的值:14 2016-04-05 11:57:29.533 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.533 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.534 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.534 sinatest[2005:339019] 节点:17 2016-04-05 11:57:29.534 sinatest[2005:339019] 返回节点的值:17 2016-04-05 11:57:29.534 sinatest[2005:339019] 返回节点的值:16 2016-04-05 11:57:29.534 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.534 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.534 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.534 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.534 sinatest[2005:339019] 节点:18 2016-04-05 11:57:29.534 sinatest[2005:339019] 返回节点的值:18 2016-04-05 11:57:29.534 sinatest[2005:339019] 返回节点的值:17 2016-04-05 11:57:29.535 sinatest[2005:339019] 返回节点的值:16 2016-04-05 11:57:29.535 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.535 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.535 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.535 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.535 sinatest[2005:339019] 节点:9 2016-04-05 11:57:29.535 sinatest[2005:339019] 返回节点的值:9 2016-04-05 11:57:29.535 sinatest[2005:339019] 返回节点的值:13 2016-04-05 11:57:29.535 sinatest[2005:339019] 返回节点的值:14 2016-04-05 11:57:29.535 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.536 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.536 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.536 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.536 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.536 sinatest[2005:339019] 节点:20 2016-04-05 11:57:29.536 sinatest[2005:339019] 返回节点的值:20 2016-04-05 11:57:29.536 sinatest[2005:339019] 返回节点的值:18 2016-04-05 11:57:29.536 sinatest[2005:339019] 返回节点的值:17 2016-04-05 11:57:29.536 sinatest[2005:339019] 返回节点的值:16 2016-04-05 11:57:29.536 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.537 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.537 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.537 sinatest[2005:339019] 节点:16 2016-04-05 11:57:29.537 sinatest[2005:339019] 返回节点的值:16 2016-04-05 11:57:29.537 sinatest[2005:339019] 返回节点的值:16 2016-04-05 11:57:29.537 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.537 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.537 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.537 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.537 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.538 sinatest[2005:339019] 节点:12 2016-04-05 11:57:29.538 sinatest[2005:339019] 返回节点的值:12 2016-04-05 11:57:29.538 sinatest[2005:339019] 返回节点的值:9 2016-04-05 11:57:29.538 sinatest[2005:339019] 返回节点的值:13 2016-04-05 11:57:29.538 sinatest[2005:339019] 返回节点的值:14 2016-04-05 11:57:29.538 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.538 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.538 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.538 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.538 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.539 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.539 sinatest[2005:339019] 节点:21 2016-04-05 11:57:29.539 sinatest[2005:339019] 返回节点的值:21 2016-04-05 11:57:29.539 sinatest[2005:339019] 返回节点的值:20 2016-04-05 11:57:29.539 sinatest[2005:339019] 返回节点的值:18 2016-04-05 11:57:29.539 sinatest[2005:339019] 返回节点的值:17 2016-04-05 11:57:29.539 sinatest[2005:339019] 返回节点的值:16 2016-04-05 11:57:29.539 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.539 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.539 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.539 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.540 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.540 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.540 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.540 sinatest[2005:339019] 节点:22 2016-04-05 11:57:29.540 sinatest[2005:339019] 返回节点的值:22 2016-04-05 11:57:29.540 sinatest[2005:339019] 返回节点的值:21 2016-04-05 11:57:29.540 sinatest[2005:339019] 返回节点的值:20 2016-04-05 11:57:29.540 sinatest[2005:339019] 返回节点的值:18 2016-04-05 11:57:29.540 sinatest[2005:339019] 返回节点的值:17 2016-04-05 11:57:29.540 sinatest[2005:339019] 返回节点的值:16 2016-04-05 11:57:29.541 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.541 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.541 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.541 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.541 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.541 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.541 sinatest[2005:339019] 节点:10 2016-04-05 11:57:29.541 sinatest[2005:339019] 返回节点的值:10 2016-04-05 11:57:29.541 sinatest[2005:339019] 返回节点的值:12 2016-04-05 11:57:29.541 sinatest[2005:339019] 返回节点的值:9 2016-04-05 11:57:29.541 sinatest[2005:339019] 返回节点的值:13 2016-04-05 11:57:29.542 sinatest[2005:339019] 返回节点的值:14 2016-04-05 11:57:29.542 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.542 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.542 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.542 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.542 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.542 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.542 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.542 sinatest[2005:339019] =======to right 2016-04-05 11:57:29.542 sinatest[2005:339019] 节点:26 2016-04-05 11:57:29.543 sinatest[2005:339019] 返回节点的值:26 2016-04-05 11:57:29.543 sinatest[2005:339019] 返回节点的值:22 2016-04-05 11:57:29.543 sinatest[2005:339019] 返回节点的值:21 2016-04-05 11:57:29.543 sinatest[2005:339019] 返回节点的值:20 2016-04-05 11:57:29.543 sinatest[2005:339019] 返回节点的值:18 2016-04-05 11:57:29.543 sinatest[2005:339019] 返回节点的值:17 2016-04-05 11:57:29.543 sinatest[2005:339019] 返回节点的值:16 2016-04-05 11:57:29.543 sinatest[2005:339019] 返回节点的值:15 2016-04-05 11:57:29.543 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.543 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.544 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.544 sinatest[2005:339019] -------to left 2016-04-05 11:57:29.544 sinatest[2005:339019] 节点:1 2016-04-05 11:57:29.544 sinatest[2005:339019] 返回节点的值:1 2016-04-05 11:57:29.544 sinatest[2005:339019] 返回节点的值:9 2016-04-05 11:57:29.544 sinatest[2005:339019] 返回节点的值:13 2016-04-05 11:57:29.544 sinatest[2005:339019] 返回节点的值:14 2016-04-05 11:57:29.544 sinatest[2005:339019] 返回节点的值:15 */ } #pragma mark 计算二叉树的深度 /* 二叉树的深度定义为:从 根节点 到 叶子节点 依次经过的节点形成树的一条路径, 最长路径 的长度为树的深度! 1)如果根节点为空,则深度为0; 2)如果左右节点都是空,则深度为1; 3)递归思想:二叉树的深度=max(左子树的深度,右子树的深度)+ 1 */ +(NSInteger)DepthOfTree:(ZXTThreeObject * ) RootNode { if (!RootNode) { return 0; } else if (!RootNode.leftTreeNode && !RootNode.rightTreeNode) { return 1; } else { NSInteger leftDepth = [self DepthOfTree:RootNode.leftTreeNode]; NSInteger rightDepth = [self DepthOfTree:RootNode.rightTreeNode]; return MAX(leftDepth, rightDepth) + 1; } } #pragma mark 二叉树宽度 /* 二叉树宽度的定义:各层节点数的最大值! */ +(NSInteger)WidthOfTree:(ZXTThreeObject * )RootNode { // 根节点不存在,就返回 0 if (!RootNode) { return 0; } /* 这里这层次遍历有点相似的味道在里面,但不是说完全相同,理解学习思路。 */ NSMutableArray * queeArray = [NSMutableArray array]; NSInteger currentWidth = 0; NSInteger maxWidth = 1;// 前面 0 的不存在就 肯定有,至少是 1 [queeArray addObject:RootNode]; // 添加根节点 while (queeArray.count > 0) { currentWidth=queeArray.count;// 这就是当前的节点的数目,第一层就只有根节点 宽度是1 ,下一层,按照下面逻辑添加了左右节点就变成了 2 // 遍历该层,删除原始数组中遍历过的节点,添加它下一层的节点。再循环遍历 for (NSInteger i=0; i<currentWidth; i++) { ZXTThreeObject * treenode = [queeArray firstObject]; [queeArray removeObjectAtIndex:0]; if (treenode.leftTreeNode) { [queeArray addObject:treenode.leftTreeNode]; } if (treenode.rightTreeNode) { [queeArray addObject:treenode.rightTreeNode]; } } // 一层一层的遍历的时候去最大值,返回 maxWidth = MAX(maxWidth, queeArray.count); } return maxWidth; } /* 先序遍历 下面是遍历的结果; 2016-04-05 10:31:16.627 sinatest[1707:294999] 先序遍历结果:15,14,13,9,1,12,10,16,16,17,18,20,21,22,26 2016-04-05 10:31:16.628 sinatest[1707:294999] 中序遍历结果:1,9,10,12,13,14,15,16,16,17,18,20,21,22,26 2016-04-05 10:31:16.629 sinatest[1707:294999] 后序遍历结果:1,10,12,9,13,14,16,26,22,21,20,18,17,16,15 2016-04-05 10:31:16.629 sinatest[1707:294999] 层次遍历结果:15,14,16,13,16,17,9,18,1,12,20,10,21,22,26 */ +(void)XianXuBianLTreeNode:(ZXTThreeObject * ) RootTreeNode handle:(void(^)(ZXTThreeObject * Treenode))handle { if (RootTreeNode) { if (handle) { handle(RootTreeNode); } // 基本的顺序就是 根节点 --> 左节点 --> 右节点 // 这里这样子调用就有一个方法执行顺序的问题,这样子写嵌套进去方法调用的过程正好就是先序遍历的顺序。 // 下面的中序遍历 和 后序遍历 都是同样的道理。 // 这里的 先 中 后 理解成根节点在遍历过程中的位置就理解了,比如 先序遍历,就是根节点在最前面 中序遍历,就是根节点在中间 [self XianXuBianLTreeNode:RootTreeNode.leftTreeNode handle:handle]; [self XianXuBianLTreeNode:RootTreeNode.rightTreeNode handle:handle]; } } /* 中序遍历 */ +(void)ZhongXuBLTreeNode:(ZXTThreeObject * ) RootTreeNode handle:(void(^)(ZXTThreeObject * Treenode))handle { if (RootTreeNode) { [self ZhongXuBLTreeNode:RootTreeNode.leftTreeNode handle:handle]; if (handle) { handle(RootTreeNode); } [self ZhongXuBLTreeNode:RootTreeNode.rightTreeNode handle:handle]; } } /* 后序遍历 */ +(void)HouXuBLTreeNode:(ZXTThreeObject * ) RootNode handle:(void (^)(ZXTThreeObject * treenode))handle { if (RootNode) { [self HouXuBLTreeNode:RootNode.leftTreeNode handle:handle]; [self HouXuBLTreeNode:RootNode.rightTreeNode handle:handle]; if (handle) { handle(RootNode); } } } /* 层次遍历 层次遍历,就是一层一层的遍历,下面的方法用到了队列的想法。 */ +(void)CengCiBLTreeNode:(ZXTThreeObject * ) RootNode handle:(void(^)(ZXTThreeObject * treenode))handle { if (RootNode) { NSMutableArray * queeArray=[NSMutableArray array]; // 添加了根节点进去 [queeArray addObject:RootNode]; while (queeArray.count>0) { // 取出数组中的第一个元素 ZXTThreeObject * rootnode = [queeArray firstObject]; if (handle) { // 添加这个元素的值到数组中去,这个就结合调用时候的BLOCK去研究,就明白了。 handle(rootnode); } // 添加完这个元素的值就把这个元素删除了 [queeArray removeObjectAtIndex:0]; // 这个节点要有左节点的话,就添加左节点到数组中去,有右节点的话就添加右节点到数组中去。 // 建议一步一步研究这个添加顺序,就可以清晰的看到这个是一层一层的遍历到的。 if (rootnode.leftTreeNode) { [queeArray addObject:rootnode.leftTreeNode]; } if (rootnode.rightTreeNode) { [queeArray addObject:rootnode.rightTreeNode]; } } } } @end
下面是它的调用,也是粘贴了整个文件的代码,它的遍历方法是写在这个按钮点击事件里面了,没什么其他意思。
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. UIButton * button=[UIButton buttonWithType:UIButtonTypeCustom]; button.frame=CGRectMake(100, 100, 100, 40); [button addTarget:self action:@selector(button ) forControlEvents:UIControlEventTouchUpInside]; [button setTitle:@"开始" forState:UIControlStateNormal]; [button setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal]; [self.view addSubview:button]; // 数据源 NSArray * array= @[@"15",@"14",@"16",@"13",@"17",@"18",@"9",@"20",@"16",@"12",@"21",@"22",@"10",@"26",@"1"]; root= [ZXTThreeObject CreatTreesWithValues:array]; } -(void)setUI { [self.delegate younameis:@"caoxiaocao"]; } -(void)button { // 二叉树的深度 NSInteger depth =[ZXTThreeObject DepthOfTree:root]; NSLog(@"二叉树深度:%ld",depth); NSInteger width =[ZXTThreeObject WidthOfTree:root]; NSLog(@"二叉树宽度:%ld",width); // 先序遍历调用 NSMutableArray *orderArray = [NSMutableArray array]; [ZXTThreeObject XianXuBianLTreeNode: root handle:^(ZXTThreeObject * Treenode) { [orderArray addObject:@(Treenode.Value)]; }]; NSLog(@"先序遍历结果:%@", [orderArray componentsJoinedByString:@","]); // 中序遍历调用 NSMutableArray *ordertwoArray = [NSMutableArray array]; [ZXTThreeObject ZhongXuBLTreeNode:root handle:^(ZXTThreeObject *Treenode) { [ordertwoArray addObject:@(Treenode.Value)]; }]; NSLog(@"中序遍历结果:%@", [ordertwoArray componentsJoinedByString:@","]); // 后序遍历调用 NSMutableArray *orderthreeArray = [NSMutableArray array]; [ZXTThreeObject HouXuBLTreeNode:root handle:^(ZXTThreeObject *Treenode) { [orderthreeArray addObject:@(Treenode.Value)]; }]; NSLog(@"后序遍历结果:%@", [orderthreeArray componentsJoinedByString:@","]); // 层次遍历调用 NSMutableArray *orderfourArray = [NSMutableArray array]; [ZXTThreeObject CengCiBLTreeNode:root handle:^(ZXTThreeObject *Treenode) { [orderfourArray addObject:@(Treenode.Value)]; }]; NSLog(@"层次遍历结果:%@", [orderfourArray componentsJoinedByString:@","]); }
四:利用swift创建二叉树
用swift创建二叉树,原理和上面的是一样的,可能就是语法细节的把握,注意细节,还有,好好学习。哈哈··
import UIKit class ZXTreeNode: NSObject { var Value:Int? var leftNode:ZXTreeNode? var rightNode:ZXTreeNode? class func creatTreeNode(RooeNodeArray:[Int]) -> ZXTreeNode { var root:ZXTreeNode? for i in 0..<RooeNodeArray.count { let value = RooeNodeArray[i] root = self.addTreeNode(&root, value: value) } return root! } class func addTreeNode( inout RootNode:ZXTreeNode?,value:Int ) -> ZXTreeNode { if (RootNode == nil ) { RootNode = ZXTreeNode() RootNode!.Value = value print("节点:",RootNode!.Value) } // 值小于根节点的值,插左边 else if (value <= RootNode!.Value) { print("----- to left ") addTreeNode(&RootNode!.leftNode, value: value) } else { print("----- to right") addTreeNode(&RootNode!.rightNode, value: value) } return RootNode! } }
后序还会更新它的遍历方式