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

📄 ospf6_bintree.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
字号:
#include <zebra.h>#include "ospf6_bintree.h"static struct bintree_node *bintree_lookup_node_min (struct bintree_node *subroot){  struct bintree_node *node;  if (subroot == NULL)    return NULL;  node = subroot;  while (node->bl_left)    node = node->bl_left;  return node;}static struct bintree_node *bintree_lookup_node_max (struct bintree_node *subroot){  struct bintree_node *node;  assert (subroot != NULL);  node = subroot;  while (node->bl_right)    node = node->bl_right;  return node;}void *bintree_lookup (void *data, struct bintree *tree){  int cmp;  struct bintree_node *node;  node = tree->root;  while (node)    {      if (tree->cmp)        cmp = (*tree->cmp) (node->data, data);      else        cmp = (node->data - data);      if (cmp == 0)        break;      if (cmp > 0)        node = node->bl_left;      else /* if (cmp < 0) */        node = node->bl_right;    }  if (node)    return node->data;  return NULL;}void *bintree_lookup_min (struct bintree *tree){  struct bintree_node *node;  node = bintree_lookup_node_min (tree->root);  if (node == NULL)    return NULL;  return node->data;}void *bintree_lookup_max (struct bintree *tree){  struct bintree_node *node;  node = bintree_lookup_node_max (tree->root);  if (node == NULL)    return NULL;  return node->data;}intbintree_add (void *data, struct bintree *tree){  int cmp = 0;  struct bintree_node *node, *parent;  node = tree->root;  parent = NULL;  while (node)    {      if (tree->cmp)        cmp = (*tree->cmp) (node->data, data);      else        cmp = (node->data - data);      if (cmp == 0)        break;      parent = node;      if (cmp > 0)        node = node->bl_left;      else /* if (cmp < 0) */        node = node->bl_right;    }  if (node)    return -1;  node = malloc (sizeof (struct bintree_node));  memset (node, 0, sizeof (struct bintree_node));  node->tree = tree;  node->data = data;  if (parent)    {      node->parent = parent;      assert (cmp != 0);      if (cmp > 0)        {          node->parent_link = BL_LEFT;          parent->bl_left = node;        }      else /* if (cmp < 0) */        {          node->parent_link = BL_RIGHT;          parent->bl_right = node;        }    }  else    tree->root = node;  tree->count++;  return 0;}static voidbintree_remove_nochild (struct bintree_node *node){  assert (node->bl_left == NULL && node->bl_right == NULL);  if (node->parent == NULL)    node->tree->root = NULL;  else    node->parent->link[node->parent_link] = NULL;}static voidbintree_remove_onechild (struct bintree_node *node){  assert ((node->bl_left == NULL && node->bl_right != NULL) ||          (node->bl_left != NULL && node->bl_right == NULL));  if (node->bl_left)    {      if (node->parent == NULL)        {          node->tree->root = node->bl_left;          node->bl_left->parent = NULL;        }      else        {          node->parent->link[node->parent_link] = node->bl_left;          node->bl_left->parent = node->parent;          node->bl_left->parent_link = node->parent_link;        }    }  else if (node->bl_right)    {      if (node->parent == NULL)        {          node->tree->root = node->bl_right;          node->bl_right->parent = NULL;        }      else        {          node->parent->link[node->parent_link] = node->bl_right;          node->bl_right->parent = node->parent;          node->bl_right->parent_link = node->parent_link;        }    }  else    assert (0);}intbintree_remove (void *data, struct bintree *tree){  int cmp;  struct bintree_node *node;  node = tree->root;  while (node)    {      if (tree->cmp)        cmp = (*tree->cmp) (node->data, data);      else        cmp = (node->data - data);      if (cmp == 0)        break;      if (cmp > 0)        node = node->bl_left;      else /* if (cmp < 0) */        node = node->bl_right;    }  if (node == NULL)    return -1;  if (node->bl_left == NULL && node->bl_right == NULL)    {      bintree_remove_nochild (node);      free (node);      tree->count--;      return 0;    }  if ((node->bl_left == NULL && node->bl_right != NULL) ||      (node->bl_left != NULL && node->bl_right == NULL))    {      bintree_remove_onechild (node);      free (node);      tree->count--;      return 0;    }  if (node->bl_left != NULL && node->bl_right != NULL)    {      struct bintree_node *successor;      /* find successor of the removing node */      successor = bintree_lookup_node_min (node->bl_right);      /* remove successor from tree */      if (successor->bl_right)        bintree_remove_onechild (successor);      else        bintree_remove_nochild (successor);      /* swap removing node with successor */      successor->parent = node->parent;      successor->parent_link = node->parent_link;      successor->bl_left = node->bl_left;      successor->bl_right = node->bl_right;      /* if the successor was the node->bl_right itself,         bintree_remove_**child may touch node->bl_right,         so only the successor->bl_right may be NULL         by above assignment */      successor->bl_left->parent = successor;      if (successor->bl_right)        successor->bl_right->parent = successor;      if (successor->parent == NULL)        tree->root = successor;      else        successor->parent->link[successor->parent_link] = successor;      free (node);      tree->count--;      return 0;    }  /* not reached */  return -1;}/* in-order traversal */voidbintree_head (struct bintree *tree, struct bintree_node *node){  struct bintree_node *head;  head = bintree_lookup_node_min (tree->root);  if (head == NULL)    {      node->parent = NULL;      node->bl_left = NULL;      node->bl_right = NULL;      node->data = NULL;      return;    }  node->tree = head->tree;  node->parent = head->parent;  node->parent_link = head->parent_link;  node->bl_left = head->bl_left;  node->bl_right = head->bl_right;  node->data = head->data;}intbintree_end (struct bintree_node *node){  if (node->parent || node->bl_left || node->bl_right || node->data)    return 0;  return 1;}#define GOTO_PROCED_SUBTREE_TOP(node) \  while (node->parent && node->parent->bl_right && \         node->parent->bl_right->data == node->data) \    { \      node->data = node->parent->data; \      node->bl_left = node->parent->bl_left; \      node->bl_right = node->parent->bl_right; \      node->parent_link = node->parent->parent_link; \      node->parent = node->parent->parent; \    }voidbintree_next (struct bintree_node *node){  struct bintree_node *next = NULL;  /* if node have just been removed, current point should have just been     replaced with its successor. that certainly  will not be processed     yet, so process it */  if (node->parent == NULL)    {      if (node->tree->root == NULL)        {          assert (node->tree->count == 0);          node->parent = NULL;          node->bl_left = NULL;          node->bl_right = NULL;          node->data = NULL;          return;        }      else if (node->tree->root->data != node->data)        next = node->tree->root;    }  else if (node->parent->link[node->parent_link] == NULL)    {      if (node->parent_link == BL_LEFT)        next = node->parent;      else        {          GOTO_PROCED_SUBTREE_TOP (node);          next = node->parent;        }    }  else if (node->parent->link[node->parent_link]->data != node->data)    next = node->parent->link[node->parent_link];  if (next == NULL)    {      if (node->bl_right)        next = bintree_lookup_node_min (node->bl_right);      else        {          GOTO_PROCED_SUBTREE_TOP (node);          next = node->parent;        }    }  if (next)    {      node->tree = next->tree;      node->parent = next->parent;      node->parent_link = next->parent_link;      node->bl_left = next->bl_left;      node->bl_right = next->bl_right;      node->data = next->data;    }  else    {      node->parent = NULL;      node->bl_left = NULL;      node->bl_right = NULL;      node->data = NULL;    }}struct bintree *bintree_create (){  struct bintree *tree;  tree = malloc (sizeof (struct bintree));  memset (tree, 0, sizeof (struct bintree));  return tree;}voidbintree_delete (struct bintree *tree){  struct bintree_node node;  for (bintree_head (tree, &node); ! bintree_end (&node);       bintree_next (&node))    bintree_remove (node.data, tree);  assert (tree->count == 0);  free (tree);}int indent_num = 0;voidbintree_print_sub (void (*print) (int, void *), struct bintree_node *subroot){  if (subroot == NULL)    return;  if (subroot->bl_right)    {      indent_num++;      bintree_print_sub (print, subroot->bl_right);      indent_num--;    }  (*print) (indent_num, subroot->data);  if (subroot->bl_left)    {      indent_num++;      bintree_print_sub (print, subroot->bl_left);      indent_num--;    }}voidbintree_print (void (*print) (int, void *), struct bintree *tree){  indent_num = 0;  bintree_print_sub (print, tree->root);}

⌨️ 快捷键说明

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