⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtree.c

📁 嵌入式下基于MiniGUI的Web Browser
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (tree->root)    return g_tree_node_search (tree->root, search_func, user_data);  else    return NULL;}/** * g_tree_height: * @tree: a #GTree. *  * Gets the height of a #GTree. * * If the #GTree contains no nodes, the height is 0. * If the #GTree contains only one root node the height is 1. * If the root node has children the height is 2, etc. *  * Return value: the height of the #GTree. **/gintg_tree_height (GTree *tree){  g_return_val_if_fail (tree != NULL, 0);  if (tree->root)    return g_tree_node_height (tree->root);  else    return 0;}/** * g_tree_nnodes: * @tree: a #GTree. *  * Gets the number of nodes in a #GTree. *  * Return value: the number of nodes in the #GTree. **/gintg_tree_nnodes (GTree *tree){  g_return_val_if_fail (tree != NULL, 0);  if (tree->root)    return g_tree_node_count (tree->root);  else    return 0;}static GTreeNode*g_tree_node_insert (GTree     *tree,                    GTreeNode *node,		    gpointer   key,		    gpointer   value,                    gboolean   replace,		    gboolean  *inserted){  gint  old_balance;  gint  cmp;  if (!node)    {      *inserted = TRUE;      return g_tree_node_new (key, value);    }  cmp = tree->key_compare (key, node->key, tree->key_compare_data);  if (cmp == 0)    {      *inserted = FALSE;      if (tree->value_destroy_func)	tree->value_destroy_func (node->value);      node->value = value;            if (replace)	{	  if (tree->key_destroy_func)	    tree->key_destroy_func (node->key);	  node->key = key;	}      else	{	  /* free the passed key */	  if (tree->key_destroy_func)	    tree->key_destroy_func (key);	}      return node;    }  if (cmp < 0)    {      if (node->left)	{	  old_balance = node->left->balance;	  node->left = g_tree_node_insert (tree,                                           node->left,					   key, value,					   replace, inserted);	  if ((old_balance != node->left->balance) && node->left->balance)	    node->balance -= 1;	}      else	{	  *inserted = TRUE;	  node->left = g_tree_node_new (key, value);	  node->balance -= 1;	}    }  else if (cmp > 0)    {      if (node->right)	{	  old_balance = node->right->balance;	  node->right = g_tree_node_insert (tree,                                            node->right,					    key, value, 					    replace, inserted);	  if ((old_balance != node->right->balance) && node->right->balance)	    node->balance += 1;	}      else	{	  *inserted = TRUE;	  node->right = g_tree_node_new (key, value);	  node->balance += 1;	}    }  if (*inserted)    {      if ((node->balance < -1) || (node->balance > 1))	node = g_tree_node_balance (node);    }  return node;}static GTreeNode*g_tree_node_remove (GTree         *tree,                    GTreeNode     *node,		    gconstpointer  key,                    gboolean       notify){  GTreeNode *new_root;  gint old_balance;  gint cmp;  if (!node)    return NULL;  cmp = tree->key_compare (key, node->key, tree->key_compare_data);  if (cmp == 0)    {      GTreeNode *garbage;      garbage = node;      if (!node->right)	{	  node = node->left;	}      else	{	  old_balance = node->right->balance;	  node->right = g_tree_node_remove_leftmost (node->right, &new_root);	  new_root->left = node->left;	  new_root->right = node->right;	  new_root->balance = node->balance;	  node = g_tree_node_restore_right_balance (new_root, old_balance);	}      if (notify)        {          if (tree->key_destroy_func)            tree->key_destroy_func (garbage->key);          if (tree->value_destroy_func)            tree->value_destroy_func (garbage->value);        }#ifdef ENABLE_GC_FRIENDLY      garbage->left = NULL;      garbage->key = NULL;      garbage->value = NULL;#endif /* ENABLE_GC_FRIENDLY */      G_LOCK (g_tree_global);      garbage->right = node_free_list;      node_free_list = garbage;      G_UNLOCK (g_tree_global);   }  else if (cmp < 0)    {      if (node->left)	{	  old_balance = node->left->balance;	  node->left = g_tree_node_remove (tree, node->left, key, notify);	  node = g_tree_node_restore_left_balance (node, old_balance);	}    }  else if (cmp > 0)    {      if (node->right)	{	  old_balance = node->right->balance;	  node->right = g_tree_node_remove (tree, node->right, key, notify);	  node = g_tree_node_restore_right_balance (node, old_balance);	}    }  return node;}static GTreeNode*g_tree_node_balance (GTreeNode *node){  if (node->balance < -1)    {      if (node->left->balance > 0)	node->left = g_tree_node_rotate_left (node->left);      node = g_tree_node_rotate_right (node);    }  else if (node->balance > 1)    {      if (node->right->balance < 0)	node->right = g_tree_node_rotate_right (node->right);      node = g_tree_node_rotate_left (node);    }  return node;}static GTreeNode*g_tree_node_remove_leftmost (GTreeNode  *node,			     GTreeNode **leftmost){  gint old_balance;  if (!node->left)    {      *leftmost = node;      return node->right;    }  old_balance = node->left->balance;  node->left = g_tree_node_remove_leftmost (node->left, leftmost);  return g_tree_node_restore_left_balance (node, old_balance);}static GTreeNode*g_tree_node_restore_left_balance (GTreeNode *node,				  gint       old_balance){  if (!node->left)    node->balance += 1;  else if ((node->left->balance != old_balance) &&	   (node->left->balance == 0))    node->balance += 1;  if (node->balance > 1)    return g_tree_node_balance (node);  return node;}static GTreeNode*g_tree_node_restore_right_balance (GTreeNode *node,				   gint       old_balance){  if (!node->right)    node->balance -= 1;  else if ((node->right->balance != old_balance) &&	   (node->right->balance == 0))    node->balance -= 1;  if (node->balance < -1)    return g_tree_node_balance (node);  return node;}static GTreeNode *g_tree_node_lookup (GTreeNode        *node,		    GCompareDataFunc  compare,		    gpointer          compare_data,		    gconstpointer     key){  gint cmp;  if (!node)    return NULL;  cmp = (* compare) (key, node->key, compare_data);  if (cmp == 0)    return node;  if (cmp < 0)    {      if (node->left)	return g_tree_node_lookup (node->left, compare, compare_data, key);    }  else if (cmp > 0)    {      if (node->right)	return g_tree_node_lookup (node->right, compare, compare_data, key);    }  return NULL;}static gintg_tree_node_count (GTreeNode *node){  gint count;  count = 1;  if (node->left)    count += g_tree_node_count (node->left);  if (node->right)    count += g_tree_node_count (node->right);  return count;}static gintg_tree_node_pre_order (GTreeNode     *node,		       GTraverseFunc  traverse_func,		       gpointer       data){  if ((*traverse_func) (node->key, node->value, data))    return TRUE;  if (node->left)    {      if (g_tree_node_pre_order (node->left, traverse_func, data))	return TRUE;    }  if (node->right)    {      if (g_tree_node_pre_order (node->right, traverse_func, data))	return TRUE;    }  return FALSE;}static gintg_tree_node_in_order (GTreeNode     *node,		      GTraverseFunc  traverse_func,		      gpointer       data){  if (node->left)    {      if (g_tree_node_in_order (node->left, traverse_func, data))	return TRUE;    }  if ((*traverse_func) (node->key, node->value, data))    return TRUE;  if (node->right)    {      if (g_tree_node_in_order (node->right, traverse_func, data))	return TRUE;    }  return FALSE;}static gintg_tree_node_post_order (GTreeNode     *node,			GTraverseFunc  traverse_func,			gpointer       data){  if (node->left)    {      if (g_tree_node_post_order (node->left, traverse_func, data))	return TRUE;    }  if (node->right)    {      if (g_tree_node_post_order (node->right, traverse_func, data))	return TRUE;    }  if ((*traverse_func) (node->key, node->value, data))    return TRUE;  return FALSE;}static gpointerg_tree_node_search (GTreeNode     *node,		    GCompareFunc   search_func,		    gconstpointer  data){  gint dir;  if (!node)    return NULL;  do {    dir = (* search_func) (node->key, data);    if (dir == 0)      return node->value;    if (dir < 0)      node = node->left;    else if (dir > 0)      node = node->right;  } while (node);  return NULL;}static gintg_tree_node_height (GTreeNode *node){  gint left_height;  gint right_height;  if (node)    {      left_height = 0;      right_height = 0;      if (node->left)	left_height = g_tree_node_height (node->left);      if (node->right)	right_height = g_tree_node_height (node->right);      return MAX (left_height, right_height) + 1;    }  return 0;}static GTreeNode*g_tree_node_rotate_left (GTreeNode *node){  GTreeNode *right;  gint a_bal;  gint b_bal;  right = node->right;  node->right = right->left;  right->left = node;  a_bal = node->balance;  b_bal = right->balance;  if (b_bal <= 0)    {      if (a_bal >= 1)	right->balance = b_bal - 1;      else	right->balance = a_bal + b_bal - 2;      node->balance = a_bal - 1;    }  else    {      if (a_bal <= b_bal)	right->balance = a_bal - 2;      else	right->balance = b_bal - 1;      node->balance = a_bal - b_bal - 1;    }  return right;}static GTreeNode*g_tree_node_rotate_right (GTreeNode *node){  GTreeNode *left;  gint a_bal;  gint b_bal;  left = node->left;  node->left = left->right;  left->right = node;  a_bal = node->balance;  b_bal = left->balance;  if (b_bal <= 0)    {      if (b_bal > a_bal)	left->balance = b_bal + 1;      else	left->balance = a_bal + 2;      node->balance = a_bal - b_bal + 1;    }  else    {      if (a_bal <= -1)	left->balance = b_bal + 1;      else	left->balance = a_bal + b_bal + 2;      node->balance = a_bal + 1;    }  return left;}static voidg_tree_node_check (GTreeNode *node){  gint left_height;  gint right_height;  gint balance;    if (node)    {      left_height = 0;      right_height = 0;            if (node->left)	left_height = g_tree_node_height (node->left);      if (node->right)	right_height = g_tree_node_height (node->right);            balance = right_height - left_height;      if (balance != node->balance)	g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO,	       "g_tree_node_check: failed: %d ( %d )\n",	       balance, node->balance);            if (node->left)	g_tree_node_check (node->left);      if (node->right)	g_tree_node_check (node->right);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -