找回密码
 欢迎注册
查看: 8197|回复: 2

[提问] 红黑树删除操作的疑问

[复制链接]
发表于 2010-1-11 20:00:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
我照着<算法导论>上关于红黑树删除操作的伪代码编写了一个红黑树删除操作,但是测试的时候发现一直出现指针为空操作的异常,算法是完全照着书上的,不知道是书上的算法有问题还是怎么回事.
以下是红黑树的相关代码:
  1. #define and &&
  2. #define or ||
  3. #define NIL NULL
  4. class Node
  5. {
  6. public:
  7.         int key;
  8.         Node* left;   //左孩子
  9.         Node* right;  //右孩子
  10.         Node* parent; //父节点
  11. //        int item;
  12.         int color;
  13.         Node()
  14.         {
  15.                 left=NIL;
  16.                 right=NIL;
  17.                 parent=NIL;
  18.                 color=-1;
  19.         }
  20.         Node(int key)
  21.         {
  22.                 this->key=key;
  23.                 left=NIL;
  24.                 right=NIL;
  25.                 parent=NIL;
  26.                 color=-1;
  27.         }
  28. };
  29. class RedBlackTree
  30. {
  31. public:
  32.         Node *root;
  33.                      Node* Successor(Node* node);
  34.         void Insert(Node* node);
  35.         void LeftRotate(Node* node);
  36.         void RightRotate(Node* node);
  37.         Node* Delete(Node* node);
  38.         void InsertFixUp(Node* node);
  39.         void DeleteFixUp(Node *node);
  40.         Node* Search(int key);
  41.         int getNodeNum()
  42.         {
  43.                 return totalNodes;
  44.         }
  45.         RedBlackTree()
  46.         {
  47.                 root=NIL;
  48.         }
  49. };
复制代码
树的相关操作
  1. Node* RedBlackTree::Successor(Node* node)
  2. {
  3.         Node* x=node;
  4.         Node* y;
  5.         if(node->right!=NIL)
  6.                 return Minimum(node->right);
  7.         y=x->parent;
  8.         while(y!=NIL and x==y->right)
  9.         {
  10.                 x=y;
  11.                 y=y->parent;
  12.         }
  13.         return y;
  14. }
  15. Node* RedBlackTree::Search(int key)
  16. {
  17.         Node* x=root;
  18.         while((x!=NIL) and (x->key!=key))
  19.         {
  20.                 if(key<x->key)
  21.                         x=x->left;
  22.                 else
  23.                         x=x->right;
  24.         }
  25.         return x;
  26. }
  27. void RedBlackTree::LeftRotate(Node* node)
  28. {
  29.         Node* x=node;
  30.         Node* y=node->right;
  31.         if(x->right!=NIL and y!=NIL)
  32.                 x->right=y->left;//Turn y's left subtree into x's subtree
  33.         if(y!=NIL and y->left!=NIL)
  34.                 y->left->parent=x;
  35.         if(y!=NIL)
  36.                 y->parent=x->parent;//Link x's parent to y
  37.        
  38.         if(x->parent==NIL)
  39.                 root=y;
  40.         else
  41.         {
  42.                 if(x==x->parent->left)
  43.                         x->parent->left=y;
  44.                 else x->parent->right=y;
  45.         }
  46.         y->left=x;
  47.         x->parent=y;
  48. }
  49. void RedBlackTree::RightRotate(Node* node)
  50. {
  51.         Node* y=node;
  52.         Node* x=node->left;
  53.         y->left=x->right;
  54.         if(x->right!=NIL)
  55.                 x->right->parent=y;
  56.         x->parent=y->parent;
  57.         if(y->parent==NIL)
  58.                 root=x;
  59.         else
  60.         {
  61.                 if(y==y->parent->left)
  62.                         y->parent->left=x;
  63.                 else y->parent->right=x;
  64.         }
  65.         x->right=y;
  66.         y->parent=x;
  67. }
  68. void RedBlackTree::Insert(Node* node)
  69. {
  70.         Node* x=root;
  71.         Node* y=NIL;
  72.         while(x!=NIL)
  73.         {
  74.                 y=x;
  75.                 if(node->key<x->key)
  76.                         x=x->left;
  77.                 else x=x->right;
  78.         }
  79.         node->parent=y;
  80.         if(y==NIL)
  81.                 root=node;
  82.         else
  83.         {
  84.                 if(node->key<y->key)
  85.                         y->left=node;
  86.                 else y->right=node;
  87.         }
  88.         node->left=NIL;
  89.         node->right=NIL;
  90.         node->color=RED;
  91.         InsertFixUp(node);
  92.         totalNodes++;
  93. }

  94. void RedBlackTree::InsertFixUp(Node* node)
  95. {
  96.         Node* z=node;
  97.         Node* y;
  98.         while(z->parent!=NIL and z->parent->color==RED)
  99.         {
  100.                 if(z->parent==z->parent->parent->left)
  101.                 {
  102.                         y=z->parent->parent->right;
  103.                         if(y!=NIL and y->color==RED)
  104.                         {
  105.                                 z->parent->color=BLACK;
  106.                                 y->color=BLACK;
  107.                                 z->parent->parent->color=RED;
  108.                                 z=z->parent->parent;
  109.                         }
  110.                         else
  111.                         {
  112.                                 if(z==z->parent->right)
  113.                                 {
  114.                                         z=z->parent;
  115.                                         LeftRotate(z);
  116.                                 }
  117.                                 z->parent->color=BLACK;
  118.                                 z->parent->parent->color=RED;
  119.                                 RightRotate(z->parent->parent);
  120.                         }
  121.                 }
  122.                 else
  123.                 {
  124.                         y=z->parent->parent->left;
  125.                         if(y!=NIL and y->color==RED)
  126.                         {
  127.                                 z->parent->color=BLACK;
  128.                                 y->color=BLACK;
  129.                                 z->parent->parent->color=RED;
  130.                                 z=z->parent->parent;
  131.                         }
  132.                         else
  133.                         {
  134.                                 if(z==z->parent->left)
  135.                                 {
  136.                                         z=z->parent;
  137.                                         RightRotate(z);
  138.                                 }
  139.                                 z->parent->color=BLACK;
  140.                                 z->parent->parent->color=RED;
  141.                                 LeftRotate(z->parent->parent);
  142.                         }
  143.                 }
  144.         }
  145.         root->color=BLACK;
  146. }

  147. Node* RedBlackTree::Delete(Node* node)
  148. {
  149.         Node* z=node;
  150.         Node* x;
  151.         Node* y;
  152.         if(z->left==NIL or z->right==NIL)
  153.                 y=z;
  154.         else y=Successor(z);
  155.         if(y->left!=NIL)
  156.                 x=y->left;
  157.         else x=y->right;
  158.         if(x!=NIL)
  159.                 x->parent=y->parent;
  160.         if(y->parent==NIL)
  161.                 root=x;
  162.         else
  163.         {
  164.                 if(y==y->parent->left)
  165.                         y->parent->left=x;
  166.                 else y->parent->right=x;
  167.         }
  168.         if(y!=z)
  169.         {
  170.                 z->key=y->key;
  171.                 z->color=y->color;
  172.                 //copy y's satellite data into z
  173.         }
  174.         if(y->color==BLACK)
  175.                 DeleteFixUp(x);
  176.         totalNodes--;
  177.         return y;
  178. }

  179. void RedBlackTree::DeleteFixUp(Node* node)
  180. {
  181.         Node* x=node;
  182.         Node* w;
  183.         while(x!=root and x->color==BLACK)
  184.         {
  185.                 if(x==x->parent->left)
  186.                 {
  187.                         w=x->parent->right;
  188.                         if(w->color==RED)
  189.                         {
  190.                                 w->color=BLACK;
  191.                                 x->parent->color=RED;
  192.                                 LeftRotate(x->parent);
  193.                                 w=x->parent->right;
  194.                         }
  195.                         if(w->left->color==BLACK and w->right->color==BLACK)
  196.                         {
  197.                                 w->color=RED;
  198.                                 x=x->parent;
  199.                         }
  200.                         else
  201.                         {
  202.                                 if(w->right->color==BLACK)
  203.                                 {
  204.                                         w->left->color=BLACK;
  205.                                         w->color=RED;
  206.                                         RightRotate(w);
  207.                                         w=x->parent->right;
  208.                                 }
  209.                                 w->color=x->parent->color;
  210.                                 x->parent->color=BLACK;
  211.                                 w->right->color=BLACK;
  212.                                 LeftRotate(x->parent);
  213.                                 x=root;
  214.                         }
  215.                 }
  216.                 else
  217.                 {
  218.                         w=x->parent->left;
  219.                         if(w->color==RED)
  220.                         {
  221.                                 w->color=BLACK;
  222.                                 x->parent->color=RED;
  223.                                 RightRotate(x->parent);
  224.                                 w=x->parent->left;
  225.                         }
  226.                         if(w->right->color==BLACK and w->left->color==BLACK)
  227.                         {
  228.                                 w->color=RED;
  229.                                 x=x->parent;
  230.                         }
  231.                         else
  232.                         {
  233.                                 if(w->left->color==BLACK)
  234.                                 {
  235.                                         w->right->color=BLACK;
  236.                                         w->color=RED;
  237.                                         LeftRotate(w);
  238.                                         w=x->parent->left;
  239.                                 }
  240.                                 w->color=x->parent->color;
  241.                                 x->parent->color=BLACK;
  242.                                 w->left->color=BLACK;
  243.                                 RightRotate(x->parent);
  244.                                 x=root;
  245.                         }
  246.                 }
  247.                 x->color=BLACK;
  248.         }
  249. }
复制代码
测试函数:
  1. void main()
  2. {
  3.         Node *node[100];
  4.         Node *x;
  5.         RedBlackTree t;
  6.         //BinarySearchTree t;
  7.        
  8.         int key[]={5,3,8,2,4,7,9,1,6,10};
  9.         int i,j,k;
  10.         int n=sizeof(key)/sizeof(*key);

  11.         for(i=0;i<n;i++)
  12.         {
  13.                 node[i]=new Node(key[i]);
  14.                 t.Insert(node[i]);
  15.                
  16.         }
  17.         printf("root->key=%d\n",t.root->key);
  18.         printf("\n");//i=0;
  19.         for(i=0;i<n;i++)
  20.         {
  21.                 x=t.Delete(t.Search(i+1));
  22.                 printf("delete key=%d\n",x->key);
  23.                 printf("root->key=%d\n",t.root->key);
  24.                 printf("\n\n");
  25.         }
  26. }
复制代码
每次运行循环进行了两次就出现了异常,通过Debug发现在第2轮循环DeleteFixUp操作中node为空指针,由此出现了异常.以上的DeleteFixUp是照着书上编的, 估计伪代码也有问题, 不知道如何改正
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-1-11 20:03:36 | 显示全部楼层
昨天在测试Insert操作时也出现了同样的情况,但是今天重新运行昨天的代码却又没有问题了.但是Delete操作一直有问题.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-1-11 20:35:35 | 显示全部楼层
以下是仅能正常输出的部分,由于输出树形结构的代码很长,所以这里给出的代码仅输出根结点
bug.PNG
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-19 05:34 , Processed in 0.060731 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表