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

📄 glpavl.c

📁 著名的大规模线性规划求解器源码GLPK.C语言版本,可以修剪.内有详细帮助文档.
💻 C
字号:
/* glpavl.c (binary search tree) *//************************************************************************  This code is part of GLPK (GNU Linear Programming Kit).**  Copyright (C) 2000,01,02,03,04,05,06,07,08,2009 Andrew Makhorin,*  Department for Applied Informatics, Moscow Aviation Institute,*  Moscow, Russia. All rights reserved. E-mail: <mao@mai2.rcnet.ru>.**  GLPK is free software: you can redistribute it and/or modify it*  under the terms of the GNU General Public License as published by*  the Free Software Foundation, either version 3 of the License, or*  (at your option) any later version.**  GLPK is distributed in the hope that it will be useful, but WITHOUT*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY*  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public*  License for more details.**  You should have received a copy of the GNU General Public License*  along with GLPK. If not, see <http://www.gnu.org/licenses/>.***********************************************************************/#include "glpavl.h"AVL *avl_create_tree(int (*fcmp)(void *info, const void *key1,      const void *key2), void *info){     /* create AVL tree */      AVL *tree;      tree = xmalloc(sizeof(AVL));      tree->pool = dmp_create_pool();      tree->root = NULL;      tree->fcmp = fcmp;      tree->info = info;      tree->size = 0;      tree->height = 0;      return tree;}int avl_strcmp(void *info, const void *key1, const void *key2){     /* compare character string keys */      xassert(info == info);      return strcmp(key1, key2);}static AVLNODE *rotate_subtree(AVL *tree, AVLNODE *node);AVLNODE *avl_insert_node(AVL *tree, const void *key){     /* insert new node into AVL tree */      AVLNODE *p, *q, *r;      short int flag;      /* find an appropriate point for insertion */      p = NULL; q = tree->root;      while (q != NULL)      {  p = q;         if (tree->fcmp(tree->info, key, p->key) <= 0)         {  flag = 0;            q = p->left;            p->rank++;         }         else         {  flag = 1;            q = p->right;         }      }      /* create new node and insert it into the tree */      r = dmp_get_atom(tree->pool, sizeof(AVLNODE));      r->key = key; r->type = 0; r->link = NULL;      r->rank = 1; r->up = p;      r->flag = (short int)(p == NULL ? 0 : flag);      r->bal = 0; r->left = NULL; r->right = NULL;      tree->size++;      if (p == NULL)         tree->root = r;      else         if (flag == 0) p->left = r; else p->right = r;      /* go upstairs to the root and correct all subtrees affected by         insertion */      while (p != NULL)      {  if (flag == 0)         {  /* the height of the left subtree of [p] is increased */            if (p->bal > 0)            {  p->bal = 0;               break;            }            if (p->bal < 0)            {  rotate_subtree(tree, p);               break;            }            p->bal = -1; flag = p->flag; p = p->up;         }         else         {  /* the height of the right subtree of [p] is increased */            if (p->bal < 0)            {  p->bal = 0;               break;            }            if (p->bal > 0)            {  rotate_subtree(tree, p);               break;            }            p->bal = +1; flag = p->flag; p = p->up;         }      }      /* if the root has been reached, the height of the entire tree is         increased */      if (p == NULL) tree->height++;      return r;}void avl_set_node_type(AVLNODE *node, int type){     /* assign the type field of specified node */      node->type = type;      return;}void avl_set_node_link(AVLNODE *node, void *link){     /* assign the link field of specified node */      node->link = link;      return;}AVLNODE *avl_find_node(AVL *tree, const void *key){     /* find node in AVL tree */      AVLNODE *p;      int c;      p = tree->root;      while (p != NULL)      {  c = tree->fcmp(tree->info, key, p->key);         if (c == 0) break;         p = (c < 0 ? p->left : p->right);      }      return p;}int avl_get_node_type(AVLNODE *node){     /* retrieve the type field of specified node */      return node->type;}void *avl_get_node_link(AVLNODE *node){     /* retrieve the link field of specified node */      return node->link;}static AVLNODE *find_next_node(AVL *tree, AVLNODE *node){     /* find next node in AVL tree */      AVLNODE *p, *q;      if (tree->root == NULL) return NULL;      p = node;      q = (p == NULL ? tree->root : p->right);      if (q == NULL)      {  /* go upstairs from the left subtree */         for (;;)         {  q = p->up;            if (q == NULL) break;            if (p->flag == 0) break;            p = q;         }      }      else      {  /* go downstairs into the right subtree */         for (;;)         {  p = q->left;            if (p == NULL) break;            q = p;         }      }      return q;}void avl_delete_node(AVL *tree, AVLNODE *node){     /* delete specified node from AVL tree */      AVLNODE *f, *p, *q, *r, *s, *x, *y;      short int flag;      p = node;      /* if both subtrees of the specified node are non-empty, the node         should be interchanged with the next one, at least one subtree         of which is always empty */      if (p->left == NULL || p->right == NULL) goto skip;      f = p->up; q = p->left;      r = find_next_node(tree, p); s = r->right;      if (p->right == r)      {  if (f == NULL)            tree->root = r;         else            if (p->flag == 0) f->left = r; else f->right = r;         r->rank = p->rank; r->up = f;         r->flag = p->flag; r->bal = p->bal;         r->left = q; r->right = p;         q->up = r;         p->rank = 1; p->up = r; p->flag = 1;         p->bal = (short int)(s == NULL ? 0 : +1);         p->left = NULL; p->right = s;         if (s != NULL) s->up = p;      }      else      {  x = p->right; y = r->up;         if (f == NULL)            tree->root = r;         else            if (p->flag == 0) f->left = r; else f->right = r;         r->rank = p->rank; r->up = f;         r->flag = p->flag; r->bal = p->bal;         r->left = q; r->right = x;         q->up = r; x->up = r; y->left = p;         p->rank = 1; p->up = y; p->flag = 0;         p->bal = (short int)(s == NULL ? 0 : +1);         p->left = NULL; p->right = s;         if (s != NULL) s->up = p;      }skip: /* now the specified node [p] has at least one empty subtree;         go upstairs to the root and adjust the rank field of all nodes         affected by deletion */      q = p; f = q->up;      while (f != NULL)      {  if (q->flag == 0) f->rank--;         q = f; f = q->up;      }      /* delete the specified node from the tree */      f = p->up; flag = p->flag;      q = p->left != NULL ? p->left : p->right;      if (f == NULL)         tree->root = q;      else         if (flag == 0) f->left = q; else f->right = q;      if (q != NULL) q->up = f, q->flag = flag;      tree->size--;      /* go upstairs to the root and correct all subtrees affected by         deletion */      while (f != NULL)      {  if (flag == 0)         {  /* the height of the left subtree of [f] is decreased */            if (f->bal == 0)            {  f->bal = +1;               break;            }            if (f->bal < 0)               f->bal = 0;            else            {  f = rotate_subtree(tree, f);               if (f->bal < 0) break;            }            flag = f->flag; f = f->up;         }         else         {  /* the height of the right subtree of [f] is decreased */            if (f->bal == 0)            {  f->bal = -1;               break;            }            if (f->bal > 0)               f->bal = 0;            else            {  f = rotate_subtree(tree, f);               if (f->bal > 0) break;            }            flag = f->flag; f = f->up;         }      }      /* if the root has been reached, the height of the entire tree is         decreased */      if (f == NULL) tree->height--;      /* returns the deleted node to the memory pool */      dmp_free_atom(tree->pool, p, sizeof(AVLNODE));      return;}static AVLNODE *rotate_subtree(AVL *tree, AVLNODE *node){     /* restore balance of AVL subtree */      AVLNODE *f, *p, *q, *r, *x, *y;      xassert(node != NULL);      p = node;      if (p->bal < 0)      {  /* perform negative (left) rotation */         f = p->up; q = p->left; r = q->right;         if (q->bal <= 0)         {  /* perform single negative rotation */            if (f == NULL)               tree->root = q;            else               if (p->flag == 0) f->left = q; else f->right = q;            p->rank -= q->rank;            q->up = f; q->flag = p->flag; q->bal++; q->right = p;            p->up = q; p->flag = 1;            p->bal = (short int)(-q->bal); p->left = r;            if (r != NULL) r->up = p, r->flag = 0;            node = q;         }         else         {  /* perform double negative rotation */            x = r->left; y = r->right;            if (f == NULL)               tree->root = r;            else               if (p->flag == 0) f->left = r; else f->right = r;            p->rank -= (q->rank + r->rank);            r->rank += q->rank;            p->bal = (short int)(r->bal >= 0 ? 0 : +1);            q->bal = (short int)(r->bal <= 0 ? 0 : -1);            r->up = f; r->flag = p->flag; r->bal = 0;            r->left = q; r->right = p;            p->up = r; p->flag = 1; p->left = y;            q->up = r; q->flag = 0; q->right = x;            if (x != NULL) x->up = q, x->flag = 1;            if (y != NULL) y->up = p, y->flag = 0;            node = r;         }      }      else      {  /* perform positive (right) rotation */         f = p->up; q = p->right; r = q->left;         if (q->bal >= 0)         {  /* perform single positive rotation */            if (f == NULL)               tree->root = q;            else               if (p->flag == 0) f->left = q; else f->right = q;            q->rank += p->rank;            q->up = f; q->flag = p->flag; q->bal--; q->left = p;            p->up = q; p->flag = 0;            p->bal = (short int)(-q->bal); p->right = r;            if (r != NULL) r->up = p, r->flag = 1;            node = q;         }         else         {  /* perform double positive rotation */            x = r->left; y = r->right;            if (f == NULL)               tree->root = r;            else               if (p->flag == 0) f->left = r; else f->right = r;            q->rank -= r->rank;            r->rank += p->rank;            p->bal = (short int)(r->bal <= 0 ? 0 : -1);            q->bal = (short int)(r->bal >= 0 ? 0 : +1);            r->up = f; r->flag = p->flag; r->bal = 0;            r->left = p; r->right = q;            p->up = r; p->flag = 0; p->right = x;            q->up = r; q->flag = 1; q->left = y;            if (x != NULL) x->up = p, x->flag = 1;            if (y != NULL) y->up = q, y->flag = 0;            node = r;         }      }      return node;}void avl_delete_tree(AVL *tree){     /* delete AVL tree */      dmp_delete_pool(tree->pool);      xfree(tree);      return;}/* eof */

⌨️ 快捷键说明

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