Skip to content

Instantly share code, notes, and snippets.

@codetalks-new
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codetalks-new/b3bedbee22eb34c61f17 to your computer and use it in GitHub Desktop.
Save codetalks-new/b3bedbee22eb34c61f17 to your computer and use it in GitHub Desktop.
Swift 绘制二叉树类
import UIKit
class TreeNode{
let val:Int
var left:TreeNode?
var right:TreeNode?
init(val:Int){
self.val = val
}
}
struct TreeNodeRect{
let treeNode:TreeNode
let rect : CGRect
init(treeNode:TreeNode,rect:CGRect){
self.treeNode = treeNode
self.rect = rect
}
var center:CGPoint{
return rect.center
}
}
extension CGRect{
init(center:CGPoint,radius:CGFloat){
origin = CGPoint(x: center.x - radius, y: center.y - radius)
size = CGSize(width: radius, height: radius)
}
init(center:CGPoint,width:CGFloat, height:CGFloat){
origin = CGPoint(x: center.x - width * 0.5, y: center.y - height * 0.5)
size = CGSize(width: width, height: height)
}
init(center:CGPoint,size:CGSize){
origin = CGPoint(x: center.x - size.width * 0.5, y: center.y - size.height * 0.5)
self.size = size
}
var center:CGPoint{
return CGPoint(x: minX + width * 0.5, y: minY + height * 0.5)
}
}
class BinaryTreeView: UIView{
var binaryTree:TreeNode
var radius : CGFloat = 30
var lineSpacing : CGFloat = 60
var treeNodeRects:[TreeNodeRect] = []
init(frame:CGRect,binaryTree:TreeNode){
self.binaryTree = binaryTree
super.init(frame: frame)
backgroundColor = UIColor.whiteColor()
regenerateNodeList()
}
override func drawRect(rect: CGRect) {
let ctx = UIGraphicsGetCurrentContext()
let lineNodes = treeNodeRects
let nodeRectByNode = {
(node:TreeNode) -> TreeNodeRect? in
for nr in lineNodes{
if nr.treeNode === node{
return nr
}
}
return nil
}
let drawLineWithPoint = {
(from:CGPoint,to: CGPoint) -> Void in
CGContextMoveToPoint(ctx, from.x, from.y)
CGContextAddLineToPoint(ctx, to.x, to.y)
}
for nodeRect in lineNodes{
let node = nodeRect.treeNode
if let left = node.left{
if let leftRect = nodeRectByNode(left){
drawLineWithPoint(nodeRect.center,leftRect.center)
}
}
if let right = node.right{
if let rightRect = nodeRectByNode(right){
drawLineWithPoint(nodeRect.center,rightRect.center)
}
}
}
CGContextStrokePath(ctx)
UIColor(white: 0.88, alpha: 1.0)
for nodeRect in treeNodeRects{
CGContextFillEllipseInRect(ctx, nodeRect.rect)
}
for nodeRect in treeNodeRects{
drawTextInRect(String(nodeRect.treeNode.val), rect: nodeRect.rect)
}
}
func drawTextInRect(text:String,rect:CGRect){
let attrs = [NSForegroundColorAttributeName: UIColor.whiteColor(),
NSFontAttributeName: UIFont.systemFontOfSize(rect.height * 0.5)
]
let attributedText = NSMutableAttributedString(string: text,attributes: attrs)
let textSize = attributedText.size()
let textRect = CGRect(center: CGPoint(x: rect.midX, y: rect.midY), size:textSize)
attributedText.drawInRect(textRect)
}
private func regenerateNodeList(){
treeNodeRects.removeAll()
arrangeTreeNode(binaryTree, inRect: bounds)
setNeedsDisplay()
}
func arrangeTreeNode(treeNode:TreeNode,inRect rect:CGRect){
let nodeRect = CGRect(center: CGPoint(x: rect.midX, y: rect.minY + radius), radius: radius)
treeNodeRects.append(TreeNodeRect(treeNode: treeNode, rect: nodeRect))
let childRect = rect.rectsByDividing(nodeRect.height + lineSpacing, fromEdge: .MinYEdge).remainder
let childRects = childRect.rectsByDividing(childRect.width * 0.5, fromEdge: .MinXEdge)
if let left = treeNode.left{
arrangeTreeNode(left, inRect: childRects.slice)
}
if let right = treeNode.right{
arrangeTreeNode(right, inRect: childRects.remainder)
}
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
let binaryTree4 = createBinaryTree4()
let binaryTreeView = BinaryTreeView(frame: CGRect(x: 0, y: 0, width: 320, height: 480), binaryTree: binaryTree4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment