您的位置:首页 > 其它

在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: