从零开始学swift(五)-算法之利用栈实现二叉树遍历
来源:互联网 发布:人脸特征比对算法 编辑:程序博客网 时间:2024/06/05 20:02
如果你能用swift写出栈并利用其实现二叉树的遍历,我可以负责任地说,再学一些iOS基础,开发一款本地的简单app是绰绰有余了。不过你们想想,谁没事用swift实现这个遍历呢,诶下个月考托福,还要准备建模,我还有好多作业,先停更一个月,一个月足够让你从什么都不会到了解swift了。
开始正题,如何用swift实现stack,在苹果官网上面有,源码是这样滴
struct Stack<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() }}
还是比较简洁易懂的
接着我们在Stack里面写一个方法isEmpty()用来判断是否为空
mutating func isEmpty()->Bool{ if(items.isEmpty) {return true} else {return false} }
下面我们来借助之前的两节算法内容,利用栈实现二叉树三种遍历。
我们建树的方法跟之前基本一样,
func createTree(i:Int, n:Int)->UnsafeMutablePointer<Tree>?{//又有问号 var p : UnsafeMutablePointer<Tree>?//又有问号 if (i >= n) {return nil} p = UnsafeMutablePointer<Tree>.alloc(sizeof(Tree)) p?.memory.data = random() % 6 + 1//又有问号//这里换了一种方法 p?.memory.lchild = createTree(i*2+1, n)//又有问号 p?.memory.rchild = createTree(i*2+2, n)//又有问号 return p}前序和中序遍历跟C差不多
func preOrder(t : UnsafeMutablePointer<Tree>?){ var stack = Stack<UnsafeMutablePointer<Tree>>() var tree = t while (tree != nil || !stack.isEmpty()){ if(tree != nil){ visited(tree!) stack.push(tree!)//入栈 tree = tree?.memory.lchild } else{ tree = stack.pop()//出栈 tree = tree?.memory.rchild } }}func inOrder(t : UnsafeMutablePointer<Tree>?){ var stack = Stack<UnsafeMutablePointer<Tree>>() var tree = t while (tree != nil || !stack.isEmpty()){ if(tree != nil){ stack.push(tree!) tree = tree?.memory.lchild } else{ tree = stack.pop() visited(tree!) tree = tree?.memory.rchild } }}真正重头的是后续遍历,由于后续遍历要标记左右子树的状态,这样的话就不得不存储两个量,因此我想到的方法是建立一个存指针的2*1的矩阵,然后将矩阵压入stack
首先建立一个矩阵
struct TreeMatrix { let rows: Int, columns: Int var grid: [UnsafeMutablePointer<Tree>?] init() { self.rows = 2 self.columns = 1 grid = Array(count: rows * columns, repeatedValue: nil) } func indexIsValidForRow(row: Int, column: Int) -> Bool { return row >= 0 && row < rows && column >= 0 && column < columns } subscript(row: Int, column: Int) -> UnsafeMutablePointer<Tree>?{ get { assert(indexIsValidForRow(row, column: column), "Index out of range") return grid[(row * columns) + column] } set { assert(indexIsValidForRow(row, column: column), "Index out of range") grid[(row * columns) + column] = newValue } }}
然后我们重写一个Stack_2
struct Stack_2<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } mutating func isEmpty()->Bool{ if(items.isEmpty) {return true} else {return false} } mutating func top()->T{ return items.last! }}
然后建立一个 boolTree,如果访问左右子树,则将矩阵里第二行的指针指向该树,用来判断状态,借此实现后续遍历
var boolTree : UnsafeMutablePointer<Tree>? = createTree(0, 1)func postOrder(t : UnsafeMutablePointer<Tree>?){ var stack = Stack_2<TreeMatrix>() var tree = TreeMatrix() tree[0,0] = t while (tree[0,0] != nil || !stack.isEmpty()){ if(tree[0,0] != nil){ stack.push(tree) tree[0,0] = tree[0,0]?.memory.lchild } else{ if(stack.top()[1,0] == nil) { var tempTree = stack.pop() tempTree[1,0] = boolTree stack.push(tempTree) tree[0,0] = stack.top()[0,0]?.memory.rchild } else{ visited(stack.pop()[0,0]!) } } }}
这样就实现了后续遍历。还没有完,我想用swift输入一个整数,然后生成对应节点个数的二叉树,这就涉及到了swift的控制台输入,可惜呀,没找到,于是我决定用swift与oc混编实现(这就是swift的强大之处,我 swift可以用你的oc类)
选择new File
建立一个叫Read的类,在头文件里面加上
#import <Foundation/Foundation.h>@interface Read: NSObject-(int) readnum;//-(int) read;@end
.m文件加上
#import "Read.h"@implementation Read-(int) readnum{ int readNum; scanf ("%d", &readNum); return readNum; }@end
在另一个bridging-heading文件里面加上
#import "Read.h"
然后就可以调用了
我们在swift文件里面可以这么调用
var readNumber = Read()var n : Int = Int(readNumber.readnum())var newTree : UnsafeMutablePointer<Tree>? = createTree(0,n)
最后就是测试运行啦
preOrder(newTree!)println()inOrder(newTree!)println()postOrder(newTree!)
我们来看一下结果
输入6的话
到这里我们的算法就告一段落啦,一个月以后再开始写ios基础。
0 0
- 从零开始学swift(五)-算法之利用栈实现二叉树遍历
- 从零开始学swift(四)-算法之二叉树的建立与遍历
- 利用栈实现二叉树的后序遍历算法
- 数据结构-----层次遍历二叉树算法(利用队列实现)
- 利用java实现二叉树以及非递归遍历算法
- 从零开始学swift(三)-算法之斐波那契数列
- 从零开始学swift(一)-基础语法之Hello World实现
- 从零开始学swift(二)-基础语法之语法篇
- 二叉树遍历算法实现
- 二叉树遍历算法实现
- 二叉树遍历算法实现
- 从零开始学Swift之Hello World
- 从零开始学Swift之再遇变量
- 利用栈实现二叉树的后序遍历
- 利用栈来实现二叉树前序遍历
- 二叉树利用队列实现层次遍历
- 从零开始学算法(五)最短路径之Floyed-Warshall算法
- Swift 算法实战之路:二叉树
- Java中两种字符串初始化方法的区别
- HDU - 5202 Rikka with string 贪心
- 前端那些事儿(2) --- javascript模块化(下)
- Why Windows Threads Are Better Than POSIX Threads
- 本月几天
- 从零开始学swift(五)-算法之利用栈实现二叉树遍历
- Win8Metro(C#)数字图像处理--2.33图像非线性变换
- java分页实现代码
- 感悟(3)——此刻反思2
- 事件总线框架---Otto
- (others)OSPF协议中的很重要的一句话
- IOS开发之三级控制器的使用与自定义标签工具栏
- Python对目录、文件的操作
- 第六周上机实践项目1——深复制体验(3)