#include
#include
#define ARRAY_SIZE (63)
#define NODE_DISTANCE (4)
#define PRINT_OFFSET (2)
typedef enum _CHILD_DIRECTION
{
LEFT_CHILD = 1,
RIGHT_CHILD,
NOT_CHILD,
}CHILD_DIRECTION;
typedef struct _Node {
int value;
struct _Node *left;
struct _Node *right;
}Node;
typedef struct _NodeInfo {
struct _Node *node;
struct _NodeInfo *parent;
int height;
int offset;
int distance_between_nodes;
CHILD_DIRECTION direction;
}NodeInfo;
static int queue_head_idx = 0, queue_tail_idx = 0;
static NodeInfo node_queue[ARRAY_SIZE+1];
static void queue_reset()
{
queue_head_idx = queue_tail_idx = 0;
}
static int queue_empty()
{
return queue_head_idx == queue_tail_idx;
}
static int queue_full()
{
return ((queue_head_idx+1)%(ARRAY_SIZE+1)) == queue_tail_idx;
}
static void queue_insert(NodeInfo node_info)
{
if (queue_full() == 0)
{
node_queue[queue_head_idx] = node_info;
queue_head_idx++;
queue_head_idx = queue_head_idx%(ARRAY_SIZE+1);
}
}
static NodeInfo queue_offer()
{
NodeInfo ret_node_info = {0};
if (queue_empty() == 0)
{
ret_node_info = node_queue[queue_tail_idx];
queue_tail_idx++;
queue_tail_idx = queue_tail_idx%(ARRAY_SIZE+1);
}
return ret_node_info;
}
static Node * create_sub_tree(int *src, int start, int end)
{
Node *node;
int mid;
if (start > end) return NULL;
mid = (start + end)/2;
node = malloc(sizeof(Node));
if (node)
{
node->value = src[mid];
node->left = create_sub_tree(src, start, mid -1);
node->right= create_sub_tree(src, mid+1, end);
}
return node;
}
static void create_binary_tree(Node** root, int *src, int size)
{
printf("create_binary_tree begin\n");
if (root == NULL) return;
*root = create_sub_tree(src, 0, size-1);
printf("create_binary_tree end\n");
}
static void print_node(int height, NodeInfo *node_info_ordered, int size)
{
int i, j, node_idx = 0, last_node_level = height;
NodeInfo *node_info;
NodeInfo *parent_node;
int target_offset, current_offset;
int current_line_width, node_num_in_current_line;
current_offset = 0;
target_offset = node_info_ordered[node_idx].distance_between_nodes/2 + PRINT_OFFSET;
node_info_ordered[node_idx].offset = target_offset;
node_num_in_current_line = 1;
while(current_offset < target_offset) {
printf(" ");
current_offset++;
}
while (node_idx < size)
{
node_info = &node_info_ordered[node_idx];
if(node_info->height != last_node_level)
{
printf("\n");
parent_node = node_info->parent;
current_line_width = parent_node->distance_between_nodes/2;
current_offset = 0;
target_offset = parent_node->offset - (current_line_width/2);
while(current_offset < target_offset) {
printf(" ");
current_offset++;
}
for(i=0; iheight;
node_num_in_current_line *= 2;
current_offset = 0;
}
parent_node = node_info->parent;
if(parent_node != NULL)
{
if (node_info->direction == LEFT_CHILD)
{
node_info->offset = parent_node->offset - (parent_node->distance_between_nodes/4);
}
else
{
node_info->offset = parent_node->offset + (parent_node->distance_between_nodes/4);
}
}
target_offset = node_info->offset;
while(current_offset < target_offset) {
printf(" ");
current_offset++;
}
current_offset += printf("%d", node_info->node->value);
node_idx++;
}
printf("\n");
}
static int preordering_traverse(int height, Node* root, NodeInfo *node_info_ordered)
{
NodeInfo node_info = {0};
Node* node;
int idx = 0, h;
int i=1, distance_between_nodes = NODE_DISTANCE;
while(ileft)
{
node_info.node = node->left;
node_info.height = h-1;
node_info.parent = &node_info_ordered[idx-1];
node_info.distance_between_nodes = node_info.parent->distance_between_nodes/2;
node_info.direction = LEFT_CHILD;
queue_insert(node_info);
}
if (node->right)
{
node_info.node = node->right;
node_info.height = h-1;
node_info.parent = &node_info_ordered[idx-1];;
node_info.distance_between_nodes = node_info.parent->distance_between_nodes/2;
node_info.direction = RIGHT_CHILD;
queue_insert(node_info);
}
}
return idx;
}
#define TREE_MAX(a,b) (((a)>(b))?(a):(b))
static int calc_tree_height(Node* root)
{
if(root != NULL)
return TREE_MAX(1+calc_tree_height(root->left), 1+calc_tree_height(root->right));
else
return 0;
}
static void print_tree(Node* root)
{
int height, offset, size;
Node *node = root;
NodeInfo node_queue_ordered[ARRAY_SIZE+1];
height = calc_tree_height(root);
printf("print_tree height = %d\n", height);
size = preordering_traverse(height, root, node_queue_ordered);
print_node(height, node_queue_ordered, size);
queue_reset();
}
int main()
{
int a[ARRAY_SIZE] = {3,5,5,1,2,6,8,4,7,9, \
3,5,5,1,2,6,8,4,7,9, \
3,5,5,1,3,5,5,1,2,6, \
8,4,7,9,3,5,5,1,2,6, \
3,5,5,1,3,5,5,1,2,6, \
8,4,7,9,3,5,5,1,8,4, \
7,9,3};
Node* root;
printf("print binary tree begin\n");
create_binary_tree(&root, a, ARRAY_SIZE);
print_tree(root);
printf("print binary tree end\n");
return 0;
}
Print binary tree
最新推荐文章于 2024-02-27 16:31:50 发布