在iPhone上展示哈夫曼二叉树
2016-02-25 17:13
281 查看
//
// BTreeNode.h
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface BTreeNode :
NSObject
@property (nonatomic,assign)
int data;
@property (nonatomic,strong)
BTreeNode *leftChild;
@property (nonatomic,strong)
BTreeNode *rightChild;
@property (nonatomic,readonly,
assign)int depth;
@property (nonatomic,readonly,
assign)int maxNodeCount;
@end
//
// BTreeNode.m
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import "BTreeNode.h"
@implementation BTreeNode
- (int)depth {
returnMAX(self.leftChild.depth,self.rightChild.depth)
+1;
}
- (int)maxNodeCount {
return pow(2,self.depth) -1;
}
@end
//
// TreeView.h
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import <UIKit/UIKit.h>
@class BTreeNode;
@interface TreeView :
UIView
@property (nonatomic,strong)
BTreeNode *tree;
@end
//
// TreeView.m
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import "TreeView.h"
#import "BTreeNode.h"
// UIView+ZMX.h文件详细请见https://github.com/zmx6999/ZMXView/tree/master
#import "UIView+ZMX.h"
#define margin 10
#define nodeW ((ScreenW - margin * (self.tree.maxNodeCount +
1)) / self.tree.maxNodeCount)
#define maxNodeCenterHorizontalDistance ((ScreenW - nodeW - margin *
2) * 0.5)
@implementation TreeView
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
[selfappendBTreeNode:self.treefloor:1center:CGPointMake(ScreenW
/2,
60)];
}
- (void)setTree:(BTreeNode *)tree {
_tree = tree;
[selfsetNeedsDisplay];
}
- (void)appendBTreeNode:(BTreeNode *)treeNode floor:(int)floor center:(CGPoint)center {
NSString *str = [NSStringstringWithFormat:@"%d", treeNode.data];
UILabel *label = [[UILabelalloc]
init];
label.text = str;
label.textColor = [UIColorblackColor];
label.font = [UIFontsystemFontOfSize:12];
label.bounds =
CGRectMake(0,
0, nodeW, nodeW);
label.center = center;
label.textAlignment =NSTextAlignmentCenter;
[self addSubview:label];
CGFloat nodeCenterHorizontalDistance =
maxNodeCenterHorizontalDistance * pow(0.5, floor);
CGFloat nodeBorderHorizontalDistance = nodeCenterHorizontalDistance -nodeW;
if (treeNode.leftChild) {
UIBezierPath *path = [UIBezierPathbezierPath];
CGPoint pointA = [UIViewleftBottomPointWithCenter:center
width:nodeW];
[path moveToPoint:pointA];
CGPoint pointB = [UIViewleftBottomPointWithPoint:pointA
horizontalDistance:nodeBorderHorizontalDistance];
[path addLineToPoint:pointB];
[path stroke];
CGPoint leftCenter = [UIViewleftBottomPointWithPoint:center
horizontalDistance:nodeCenterHorizontalDistance];
[self appendBTreeNode:treeNode.leftChildfloor:floor +
1center:leftCenter];
}
if (treeNode.rightChild) {
UIBezierPath *path = [UIBezierPathbezierPath];
CGPoint pointA = [UIViewrightBottomPointWithCenter:center
width:nodeW];
[path moveToPoint:pointA];
CGPoint pointB = [UIViewrightBottomPointWithPoint:pointA
horizontalDistance:nodeBorderHorizontalDistance];
[path addLineToPoint:pointB];
[path stroke];
CGPoint rightCenter = [UIViewrightBottomPointWithPoint:center
horizontalDistance:nodeCenterHorizontalDistance];
[self appendBTreeNode:treeNode.rightChildfloor:floor +
1center:rightCenter];
}
}
@end
//
// ViewController.m
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import "ViewController.h"
#import "BTreeNode.h"
#import "TreeView.h"
#define N 5
@interface
ViewController ()
@property (weak,
nonatomic) IBOutletTreeView *treeView;
@property (nonatomic,strong)
NSMutableArray *trees;
@end
@implementation ViewController
- (NSMutableArray *)trees {
if (_trees ==nil) {
_trees = [NSMutableArrayarray];
}
return _trees;
}
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
int a[N] = {29,8,
14, 7,
23};
[selfinitTreesWithArray:a];
[selfquickSortWithStart:0end:N
-1];
[selfcreateHuffmanTree];
self.treeView.tree =self.trees.firstObject;
}
- (void)initTreesWithArray:(int *)a {
for (int i =0; i <
N; i++) {
BTreeNode *tree = [[BTreeNodealloc]
init];
tree.data = a[i];
tree.leftChild =
nil;
tree.rightChild =
nil;
[self.treesaddObject:tree];
}
}
- (void)quickSortWithStart:(int)s end:(int)t {
if (s >= t) {
return;
}
BTreeNode *sTree = [self.treesobjectAtIndex:s];
int k = sTree.data;
int i = s;
int j = t;
while (i < j) {
while (i < j) {
BTreeNode *jTree = [self.treesobjectAtIndex:j];
if (jTree.data >= k) {
j--;
} else {
break;
}
}
if (i < j) {
[selfexchangeBTreeAtIndex:i
withBTreeAtIndex:j];
}
while (i < j) {
BTreeNode *iTree = [self.treesobjectAtIndex:i];
if (iTree.data <= k) {
i++;
} else {
break;
}
}
if (i < j) {
[selfexchangeBTreeAtIndex:i
withBTreeAtIndex:j];
}
}
[selfquickSortWithStart:s
end:i -1];
[selfquickSortWithStart:i +
1end:t];
}
- (void)exchangeBTreeAtIndex:(int)i withBTreeAtIndex:(int)j {
BTreeNode *tree1 = [self.treesobjectAtIndex:i];
BTreeNode *tree2 = [self.treesobjectAtIndex:j];
tree1.data = tree1.data ^ tree2.data;
tree2.data = tree1.data ^ tree2.data;
tree1.data = tree1.data ^ tree2.data;
}
- (void)insertTree:(BTreeNode *)tree {
for (int i =0; i <
self.trees.count; i++) {
BTreeNode *currentTree = [self.treesobjectAtIndex:i];
if (currentTree.data > tree.data) {
[self.treesinsertObject:tree
atIndex:i];
return;
}
}
[self.treesaddObject:tree];
}
- (void)createHuffmanTree {
if (self.trees.count <2) {
return;
}
BTreeNode *tree1 = [self.treesobjectAtIndex:0];
BTreeNode *tree2 = [self.treesobjectAtIndex:1];
BTreeNode *tree = [[BTreeNodealloc]
init];
tree.data = tree1.data + tree2.data;
tree.leftChild = tree1;
tree.rightChild = tree2;
[self.treesremoveObjectAtIndex:0];
[self.treesremoveObjectAtIndex:0];
[self insertTree:tree];
[selfcreateHuffmanTree];
}
@end
// BTreeNode.h
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface BTreeNode :
NSObject
@property (nonatomic,assign)
int data;
@property (nonatomic,strong)
BTreeNode *leftChild;
@property (nonatomic,strong)
BTreeNode *rightChild;
@property (nonatomic,readonly,
assign)int depth;
@property (nonatomic,readonly,
assign)int maxNodeCount;
@end
//
// BTreeNode.m
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import "BTreeNode.h"
@implementation BTreeNode
- (int)depth {
returnMAX(self.leftChild.depth,self.rightChild.depth)
+1;
}
- (int)maxNodeCount {
return pow(2,self.depth) -1;
}
@end
//
// TreeView.h
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import <UIKit/UIKit.h>
@class BTreeNode;
@interface TreeView :
UIView
@property (nonatomic,strong)
BTreeNode *tree;
@end
//
// TreeView.m
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import "TreeView.h"
#import "BTreeNode.h"
// UIView+ZMX.h文件详细请见https://github.com/zmx6999/ZMXView/tree/master
#import "UIView+ZMX.h"
#define margin 10
#define nodeW ((ScreenW - margin * (self.tree.maxNodeCount +
1)) / self.tree.maxNodeCount)
#define maxNodeCenterHorizontalDistance ((ScreenW - nodeW - margin *
2) * 0.5)
@implementation TreeView
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
[selfappendBTreeNode:self.treefloor:1center:CGPointMake(ScreenW
/2,
60)];
}
- (void)setTree:(BTreeNode *)tree {
_tree = tree;
[selfsetNeedsDisplay];
}
- (void)appendBTreeNode:(BTreeNode *)treeNode floor:(int)floor center:(CGPoint)center {
NSString *str = [NSStringstringWithFormat:@"%d", treeNode.data];
UILabel *label = [[UILabelalloc]
init];
label.text = str;
label.textColor = [UIColorblackColor];
label.font = [UIFontsystemFontOfSize:12];
label.bounds =
CGRectMake(0,
0, nodeW, nodeW);
label.center = center;
label.textAlignment =NSTextAlignmentCenter;
[self addSubview:label];
CGFloat nodeCenterHorizontalDistance =
maxNodeCenterHorizontalDistance * pow(0.5, floor);
CGFloat nodeBorderHorizontalDistance = nodeCenterHorizontalDistance -nodeW;
if (treeNode.leftChild) {
UIBezierPath *path = [UIBezierPathbezierPath];
CGPoint pointA = [UIViewleftBottomPointWithCenter:center
width:nodeW];
[path moveToPoint:pointA];
CGPoint pointB = [UIViewleftBottomPointWithPoint:pointA
horizontalDistance:nodeBorderHorizontalDistance];
[path addLineToPoint:pointB];
[path stroke];
CGPoint leftCenter = [UIViewleftBottomPointWithPoint:center
horizontalDistance:nodeCenterHorizontalDistance];
[self appendBTreeNode:treeNode.leftChildfloor:floor +
1center:leftCenter];
}
if (treeNode.rightChild) {
UIBezierPath *path = [UIBezierPathbezierPath];
CGPoint pointA = [UIViewrightBottomPointWithCenter:center
width:nodeW];
[path moveToPoint:pointA];
CGPoint pointB = [UIViewrightBottomPointWithPoint:pointA
horizontalDistance:nodeBorderHorizontalDistance];
[path addLineToPoint:pointB];
[path stroke];
CGPoint rightCenter = [UIViewrightBottomPointWithPoint:center
horizontalDistance:nodeCenterHorizontalDistance];
[self appendBTreeNode:treeNode.rightChildfloor:floor +
1center:rightCenter];
}
}
@end
//
// ViewController.m
// Huffman
//
// Created by zmx on 16/2/24.
// Copyright © 2016年 zmx. All rights reserved.
//
#import "ViewController.h"
#import "BTreeNode.h"
#import "TreeView.h"
#define N 5
@interface
ViewController ()
@property (weak,
nonatomic) IBOutletTreeView *treeView;
@property (nonatomic,strong)
NSMutableArray *trees;
@end
@implementation ViewController
- (NSMutableArray *)trees {
if (_trees ==nil) {
_trees = [NSMutableArrayarray];
}
return _trees;
}
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
int a[N] = {29,8,
14, 7,
23};
[selfinitTreesWithArray:a];
[selfquickSortWithStart:0end:N
-1];
[selfcreateHuffmanTree];
self.treeView.tree =self.trees.firstObject;
}
- (void)initTreesWithArray:(int *)a {
for (int i =0; i <
N; i++) {
BTreeNode *tree = [[BTreeNodealloc]
init];
tree.data = a[i];
tree.leftChild =
nil;
tree.rightChild =
nil;
[self.treesaddObject:tree];
}
}
- (void)quickSortWithStart:(int)s end:(int)t {
if (s >= t) {
return;
}
BTreeNode *sTree = [self.treesobjectAtIndex:s];
int k = sTree.data;
int i = s;
int j = t;
while (i < j) {
while (i < j) {
BTreeNode *jTree = [self.treesobjectAtIndex:j];
if (jTree.data >= k) {
j--;
} else {
break;
}
}
if (i < j) {
[selfexchangeBTreeAtIndex:i
withBTreeAtIndex:j];
}
while (i < j) {
BTreeNode *iTree = [self.treesobjectAtIndex:i];
if (iTree.data <= k) {
i++;
} else {
break;
}
}
if (i < j) {
[selfexchangeBTreeAtIndex:i
withBTreeAtIndex:j];
}
}
[selfquickSortWithStart:s
end:i -1];
[selfquickSortWithStart:i +
1end:t];
}
- (void)exchangeBTreeAtIndex:(int)i withBTreeAtIndex:(int)j {
BTreeNode *tree1 = [self.treesobjectAtIndex:i];
BTreeNode *tree2 = [self.treesobjectAtIndex:j];
tree1.data = tree1.data ^ tree2.data;
tree2.data = tree1.data ^ tree2.data;
tree1.data = tree1.data ^ tree2.data;
}
- (void)insertTree:(BTreeNode *)tree {
for (int i =0; i <
self.trees.count; i++) {
BTreeNode *currentTree = [self.treesobjectAtIndex:i];
if (currentTree.data > tree.data) {
[self.treesinsertObject:tree
atIndex:i];
return;
}
}
[self.treesaddObject:tree];
}
- (void)createHuffmanTree {
if (self.trees.count <2) {
return;
}
BTreeNode *tree1 = [self.treesobjectAtIndex:0];
BTreeNode *tree2 = [self.treesobjectAtIndex:1];
BTreeNode *tree = [[BTreeNodealloc]
init];
tree.data = tree1.data + tree2.data;
tree.leftChild = tree1;
tree.rightChild = tree2;
[self.treesremoveObjectAtIndex:0];
[self.treesremoveObjectAtIndex:0];
[self insertTree:tree];
[selfcreateHuffmanTree];
}
@end
相关文章推荐
- globalZOrder()与localZOrder()
- linux设备驱动归纳总结(六):1.中断的实现
- 视频的中断退出
- UITableView属性及方法大全
- 解决apache启动错误"httpd:Could not reliably determine
- 大型网站架构系列:电商网站架构案例(1)
- 类 的默认拷贝构造是浅拷贝。 若要深拷贝,则需要自己重写拷贝构造函数。
- Web开发者推荐的最佳HTML5/CSS3代码生成器
- Android项目:手机安全卫士(2)—— 版本升级
- (26)odoo中的序列运用
- SSO单点登录
- 想更好的实现DevOps吗?不妨试试ChatOps
- UIModalPresentationStyle和UIModalTransitionStyle
- 基于HTML5 Ajax实现文件上传并显示进度条
- Latex快速入门-papering必读
- java教程+ppt
- 例题3-4 周期串
- popup
- Maven学习笔记——常用插件配置详解
- 字符串哈希函数