Swift2.2 看完这篇博客 你不想懂也会懂得----二叉树
一:初衷
我自己也好奇,为什么莫名其妙的想起写这个,其实数据里面包含的结构和逻辑我自己觉得才是最原始经典的,最近也在学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!
}
}
后序还会更新它的遍历方式
Swift2.2 看完这篇博客 你不想懂也会懂得----二叉树的更多相关文章
- [转帖]看完这篇文章,我奶奶都懂了https的原理
看完这篇文章,我奶奶都懂了https的原理 http://www.17coding.info/article/22 非对称算法 以及 CA证书 公钥 核心是 大的质数不一分解 还有 就是 椭圆曲线算法 ...
- 看完这篇文章,我奶奶都懂了https的原理
本文在个人技术博客同步发布,详情可猛戳 亦可扫描屏幕右方二维码关注个人公众号 Http存在的问题 上过网的朋友都知道,网络是非常不安全的.尤其是公共场所很多免费的wifi,或许只是攻击者的一个诱饵 ...
- 第一篇博客 ---- 分享关于Maven使用的一些技巧
Maven环境搭建 在官网上下载maven安装包,地址:http://maven.apache.org/download.cgi . 解压文件到电脑坐在盘符目录,如E:\apache-maven-3. ...
- 第一篇博客:Hello World
2016年10月10日,双十,好日子,决定开始写第一篇博客,标题想了会,就叫Hello World 吧,哈哈^_^. 首先感谢博客园的管理们能批准我的申请,记得在14年的时候申请过一次,竟然没申请通过 ...
- [书籍]值得纪念的第100篇博客,推荐一些看过的UI书籍
1. 前言 来到博客园11年,这两年闲下来了才有时间写写博客,不知不觉终于写到第100篇博客了.回顾过去发表的博客,居然大部分都与UI相关.明明我本来从事的是Oracle的相关开发,明明我当初的目标是 ...
- 鸿蒙内核源码分析(任务切换篇) | 看汇编如何切换任务 | 百篇博客分析OpenHarmony源码 | v41.03
百篇博客系列篇.本篇为: v41.xx 鸿蒙内核源码分析(任务切换篇) | 看汇编如何切换任务 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁 ...
- 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙看这篇或许真的够了 | 百篇博客分析OpenHarmony源码 | v50.06
百篇博客系列篇.本篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙防掉坑指南 | 51.c.h.o 编译构建相关篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙防掉 ...
- Hello World -- 第一篇博客
今年注定是不寻常的一年,因为技术,接触了许多大牛.通过一篇篇博文,看到了大牛们勤奋好学.孜孜不倦的精神,于是决定也开个博客,向大牛学习. 博客开了,写点什么呢?奈何肚子里墨水不多,吐出来也多是白沫,不 ...
- 看完这篇还不会 GestureDetector 手势检测,我跪搓衣板!
引言 在 android 开发过程中,我们经常需要对一些手势,如:单击.双击.长按.滑动.缩放等,进行监测.这时也就引出了手势监测的概念,所谓的手势监测,说白了就是对于 GestureDetector ...
随机推荐
- PC端 H5实现拍照并上传
<!DOCTYPE HTML><html><head> <meta charset="UTF-8"> <meta name=& ...
- ubuntu12.04安装tar.gz格式的jdk
注意系统的版本,jdk也有32位和64位的,不然会无效 首先将*.tar.gz压缩包解压 命令: tar -xzvf *.tar.gz 假设得到的文件夹为java 将其移动到/usr/中 命令为:su ...
- ubuntu升级php版本
如果安装的 PHP 版本过低的话,可以通过下面的指令来升级: sudo add-apt-repository ppa:ondrej/php5 sudo apt-get update sudo ...
- NPOI使用Datatable导出到Excel
首先要引用dll 下载地址:http://pan.baidu.com/s/1dFr2m 引入命名空间: using NPOI.HSSF.UserModel;using NPOI.SS.UserMode ...
- IOS开发者证书申请及应用上线发布详解(2014版)
其实一直以来我都想做一个最齐全的上传应用到appstore的教程,但一直狠不下心,今天凌晨2点12分,我鼓起勇气写教程,来吧不多说.登录开发者中心:http://developer.apple.com ...
- tp框架命名空间
命名空间:相当于虚拟的目录在tp里面主要为了实现自动加载类 TP框架下有一个初始命名空间(相当于根目录)初始命名空间:ThinkPHP\Library 在初始命名空间下又包含很多根命名空间这些根命名空 ...
- IOS开发中各种型号的分辨率及软件图标的制作
IOS中各手机的分辨率为: 5.5寸: 1242*2208;4.7寸: 750*1334;4.0寸: 640*1136;3.5寸: 640*960; 软件的图标有以下需求(注意选中右侧红色框中这一条) ...
- mysql 常用指令
修改表的字符集 88down voteaccepted If you want to change the table default character set and all character ...
- UVa 10041 - Vito's Family
题目大意:给出一些点,找到一个位置使这个位置到所有的点的距离的和最短. 很明显,排序,找中位数.关于中位数:有n个从小到大的数,k=(n+1)/2,若n为奇数,k为中位数,若n为偶数,k为中间那两个数 ...
- Android与Linux以及GNU的关系
转帖自 http://www.eefocus.com/Kevin/blog/09-11/179409_1dc9a.html 作者: Kevin 本文转贴自 http://mmdays.com/2008 ...