创建二叉树

来源:互联网 发布:淘宝拍摄培训 编辑:程序博客网 时间:2024/06/03 22:56
如何在二叉树中定位结点的位置?
指路法定位结点:根据生活中的经历:左拐、右拐、左拐、、、

大致思路:

通过根结点与目标结点的相对位置进行定位,这种方法可以避开二叉树递归的性质“线性定位”

C描述:利用bit位进行指路

#define BT_LEFT 0#define BT_RIGHT 1typedef unsigned long BT_pos;


二叉树的操作:

创建树--btree_create
销毁树--btree_destroy
清空树--btree_clear
插入结点--btree_insert
删除结点--btree_delete
获取结点--btree_get
获取根结点--btree_root
获取树的结点数--btree_count
获取树的度--btree_degree

•插入结点:


/*参数说明tree:待插入结点的二叉树node:待插入的结点pos: 进行“指路”的bit位count:需要指路的次数flag:考虑待插入的结点不在叶结点,而是替代二叉树中原有的一个结点进行插入操作,此标志 用于标示被替换的结点与其子树应在插入结点的左边还是右边。*/int btree_insert(btree* tree, btree_node* node, bt_pos pos, int count, int flag){ head_node* btree_head_node = (head_node*)tree; int ret = (btree_head_node != NULL) && (node != NULL) && ((flag == BT_LEFT) || (flag == BT_RIGHT)); int bit = 0;  if( ret ) {  btree_node* parent = NULL;  btree_node* current = btree_head_node->root;   node->left = NULL;  node->right = NULL;     while( (count > 0) && (current != NULL) )  {   bit = pos & 1;   pos = pos >> 1;      /*记录待插入结点的父结点的位置*/   parent = current;      if(bit == BT_LEFT)   {    current = current->left;   }   else if(bit == BT_RIGHT)   {    current = current->right;   }      count--;  }   if(flag = BT_LEFT)  {   node->left = current;  }  else if(flag = BT_RIGHT)  {   node->right = current;  }   if(parent != NULL)  {   /*由最后一步的指路判断插入结点在父结点的左边还是右边*/   if(bit == BT_LEFT)   {    parent->left = node;   }   else if(bit == BT_RIGHT)   {    parent->right = node;   }  }  else  {   /*此种情况为插入结点为根结点的情况*/   btree_head_node->root = node;  }   btree_head_node->count++; }  return ret;}


•打印函数:

要求体现二叉树的形状,左结点存在而右结点不存在的情况下,相应的也打印出右结点的格式。

实现代码:
/*参数说明:node:打印的结点p_func:打印函数format :打印格式div:格式字符*/static void recursive_display(btree_node *node, btree_printf* p_func, int format, char div){ int i = 0;  if((node != NULL) && (p_func != NULL)) {  for(i=0; i<format; i++)  {   printf("%c", div);  }   p_func(node);   printf("\n");   if((node->left != NULL) || (node->right != NULL))  {   recursive_display(node->left, p_func, format+2, div);   recursive_display(node->right, p_func, format+2, div);  } } else {  for(i=0; i<format; i++)  {   printf("%c", div);  }  printf("\n"); } }void btree_display(btree* tree, btree_printf* p_func, char div){ head_node* btree_head_node = (head_node*)tree;  if(btree_head_node != NULL) {   recursive_display(btree_head_node->root, p_func, 0, div); }} 



•删除结点:

丢弃结点的子树的结点数

实现代码:
/*统计结点数量*/static int recursive_count(btree_node* node){ int ret = 0;  if(node != NULL) {  ret = recursive_count(node->left) + recursive_count(node->right) + 1; }  return ret;}btree_node* btree_delete(btree* tree, bt_pos pos, int count){ head_node* btree_head_node = (head_node*)tree; int bit = 0; btree_node* ret = NULL;  if(btree_head_node != NULL) {  btree_node* parent = NULL;  btree_node* current = btree_head_node->root;   while((count > 0) && (current != NULL))  {   bit = (pos & 1);   pos = (pos >> 1);      parent = current;      if(bit == BT_LEFT)   {    current = current->left;   }   else if(bit == BT_RIGHT)   {    current = current->right;   }      count--;  }     if(parent != NULL)  {   if(bit == BT_LEFT)   {    parent->left = NULL;    }   else if(bit == BT_RIGHT)   {    parent->right = NULL;       }     }  else  {   btree_head_node->root = NULL;  }   ret = current;   /*对删除结点后的二叉树结点数量进行统计,  把删除结点的子树上的结点数量也去掉*/  btree_head_node->count = btree_head_node->count - recursive_count(current); }  return ret;}/*返回节点数量*/int btree_count(btree* tree){ head_node* btree_head_node = (head_node*) tree; int ret = 0;  if(btree_head_node != NULL) {  ret = btree_head_node->count; }  return ret;}



•树的高度:


实现代码:
static int recursive_height(btree_node* node){ int ret = 0;  if(node != NULL) {  int lh = recursive_height(node->left);  int rh = recursive_height(node->right);   ret = ((lh > rh) ? lh : rh) + 1;  }  return ret;}int btree_height(btree* tree){ head_node* btree_head_node = (head_node*) tree; int ret = 0;  if(btree_head_node != NULL) {  ret = recursive_height(btree_head_node->root); }  return ret; } 




•树的度:


考虑到二叉树的性质,度最大为2,想办法利用此特点提高遍历二叉树的效率
在代码中可以这样描述:
若根结点的左孩子存在,度加1,若右孩子也存在,度再加1。直接返回即可,不用再遍历其他子树。
若左右孩子都不存在,则可以判断此树只有根结点,度为0.也直接返回即可。
若左右孩子只存在一个,则开始递归遍历。

实现代码:
static int recursive_degree(btree_node* node){ int ret = 0;  if(node != NULL) {  if(node->left != NULL)  {   ret++;  }  if(node->right != NULL)  {   ret++;  }  if(ret == 1)  {   int ld = recursive_degree(node->left);   int rd = recursive_degree(node->right);         if(ret < ld)      {    ret = ld;   }      if(ret < rd)   {    ret = rd;   }  } } return ret;}int btree_degree(btree* tree){ head_node* btree_head_node = (head_node*)tree; int ret = 0;  if(btree_head_node != NULL) {  ret = recursive_degree(btree_head_node->root); }  return ret;}


0 0
原创粉丝点击