码迷,mamicode.com
首页 > 其他好文 > 详细

创建二叉树

时间:2015-04-25 16:41:39      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:遍历   二叉树实现   c   

如何在二叉树中定位结点的位置?
指路法定位结点:根据生活中的经历:左拐、右拐、左拐、、、

大致思路:

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

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

#define BT_LEFT 0
#define BT_RIGHT 1
typedef 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;
}


创建二叉树

标签:遍历   二叉树实现   c   

原文地址:http://blog.csdn.net/u011467781/article/details/45271267

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!