算法练习五 红黑树上 实现了左旋转、右旋转、以及插入(转)

为了检验红黑树的正确性,这里的输入数组为 41 67 34 0 69 24 78 58 62 64 

最后的输出结果为:

62 黑

L[62] = 41 红

R[62] = 69 红

L[41] = 24 黑

R[41] = 58 黑

L[69] = 67 黑

R[69] = 79 黑

L[24] = 0   红

R[24] = 34 红

 

红黑树的节点

  1. #pragma once   
  2. #define RED 1   
  3. #define BLACK 2   
  4. class RBNode{  
  5. public:  
  6.         RBNode();  
  7. public:  
  8.     int key;  
  9.     RBNode* pParent;  
  10.     RBNode* pLeft;  
  11.     RBNode* pRight;  
  12.     int color;  
  13. };  
  14. //左旋转   
  15. void LeftRotate(RBNode** proot, RBNode* x, RBNode* pguardNode);  
  16. //右旋转   
  17. void RightRotate(RBNode** root, RBNode* x, RBNode* pguardNode);  
  18. //插入   
  19. void RBInsert(RBNode** proot,RBNode* pnode, RBNode* pguardNode);  
  20. //插入修正   
  21. void RBInsertFixup(RBNode** proot, RBNode* x, RBNode* pguardNode);  
  22. //中序遍历   
  23. void InorderTreeWalk(RBNode* proot, RBNode* pguardNode);  
  24. //采用中序遍历递归的方法在树中寻找一个元素   
  25. void FindNodeInBSTree(RBNode* proot, int key, RBNode** pnode,RBNode* pguardNode);  
 

 

主要函数实现

 

  1. // RBTRee.cpp : 定义控制台应用程序的入口点。   
  2. //   
  3. #include "stdafx.h"   
  4. #include "rbnode.h"   
  5. #include<iostream>   
  6. #include<stdlib.h>   
  7. #include<time.h>   
  8. #include<queue>   
  9. using namespace std;  
  10. #define random(x) (rand()%x)   
  11. //一层一层遍历其中的元素   
  12. void LayerOrder(RBNode* proot,RBNode* pguardNode);  
  13. // The Main Method   
  14. int _tmain(int argc, _TCHAR* argv[])  
  15. {  
  16.     int num = 10;  
  17.     cout << "请输入需要排序数组的长度,数组将随机生成:" <<endl;  
  18.     cin >> num;  
  19.     int* ary =  new int[num];  
  20.     //srand( (int)time( 0 ) );   
  21.     for ( int x=0; x<num; x++ )  
  22.     {  
  23.         ary[x] = random(100);  
  24.         cout << ary[x] << endl;  
  25.     }  
  26.     //先生成一个不一定符合规则的红黑树,试试与二叉查找树相比修改后的插入方法是否正确   
  27.     RBNode* proot = NULL;  
  28.     RBNode* pguardNode = new RBNode();  
  29.     pguardNode->key = 111;  
  30.     pguardNode->color = BLACK;  
  31.       
  32.     for ( int x=0; x<num; x++)  
  33.     {  
  34.         RBNode* pnode = new RBNode();  
  35.         pnode->key = ary[x];  
  36.         RBInsert( &proot, pnode, pguardNode );  
  37.     }  
  38.     //逐层输出   
  39.     cout << "逐层输出" << endl;  
  40.     LayerOrder( proot, pguardNode );  
  41.     //中序遍历输出   
  42.     /*cout << "中序遍历" << endl; 
  43.     InorderTreeWalk( proot, pguardNode );*/  
  44.       
  45.     //int nkey;   
  46.     //cout << "选择一个数" << endl;   
  47.     //cin >> nkey;   
  48.     //RBNode* pfindNode = NULL;   
  49.     //FindNodeInBSTree( proot, nkey, &pfindNode,pguardNode);   
  50.     //int LorR;   
  51.     //cout << "左旋转输入1,右旋转输入2" << endl;   
  52.     //cin >> LorR;   
  53.     //if ( LorR == 1 )   
  54.     //{   
  55.     //  LeftRotate( &proot, pfindNode, pguardNode );       
  56.     //}   
  57.     //else   
  58.     //{   
  59.     //  RightRotate( &proot, pfindNode, pguardNode );   
  60.     //}   
  61.     //cout << "旋转完成" << endl;   
  62.     InorderTreeWalk( proot, pguardNode );   
  63.     //LayerOrder( proot, pguardNode );   
  64.     system("pause");  
  65.     delete[] ary;  
  66.     return 0;  
  67. }  
  68.   
  69. //   
  70. void LayerOrder(RBNode* proot,RBNode* pguardNode)  
  71. {  
  72.     //借用队列进行输出   
  73.     std::queue<RBNode*> rbQueue;  
  74.     rbQueue.push( proot );  
  75.     while ( !rbQueue.empty() )  
  76.     {  
  77.         RBNode* p = rbQueue.front();  
  78.         rbQueue.pop();  
  79.         if ( p->pLeft != pguardNode )  
  80.         {  
  81.             rbQueue.push( p->pLeft );  
  82.         }  
  83.         if ( p->pRight != pguardNode )  
  84.         {  
  85.             rbQueue.push( p->pRight );  
  86.         }  
  87.         cout << "key=" << p->key << "color=" << p->color << endl;  
  88.     }  
  89.       
  90. }  
  91. //左旋转   
  92. void LeftRotate(RBNode** proot, RBNode* px, RBNode* pguardNode)  
  93. {  
  94.     //叶子节点不存在左旋还是右旋   
  95.     if ( px->pLeft == pguardNode && px->pRight == pguardNode )  
  96.     {  
  97.         return;  
  98.     }  
  99.     RBNode* y = px->pRight;  //向左旋转,需要找到px的右子树   
  100.       
  101.     //将原先px的右子树修改指向y的左子树   
  102.     px->pRight = y->pLeft;       
  103.     if ( y->pLeft != pguardNode )  
  104.     {  
  105.         y->pLeft->pParent = px;   //将y的左子树的父指针指向px   
  106.     }  
  107.     //修改px的父节点与px的联系,将y的父节点指向px,然后将px的父节点的子树指针指向y   
  108.     y->pParent = px->pParent;  
  109.     if ( px->pParent == pguardNode )  
  110.     {  
  111.         *proot = y;  
  112.     }  
  113.     else  
  114.     {  
  115.         if ( px == px->pParent->pLeft )  
  116.         {  
  117.             px->pParent->pLeft  = y;  
  118.         }  
  119.         else  
  120.         {  
  121.             px->pParent->pRight = y;  
  122.         }  
  123.     }  
  124.       
  125.     //重新建立px 与 y的子父关系   
  126.     y->pLeft = px;  
  127.     px->pParent = y;  
  128. }  
  129. //右旋转   
  130. void RightRotate(RBNode** proot, RBNode* px, RBNode* pguardNode)  
  131. {  
  132.     RBNode* y = px->pLeft;  
  133.     //修改y的右子树   
  134.     px->pLeft = y->pRight;  
  135.     if ( y->pRight != pguardNode )  
  136.     {  
  137.         y->pRight->pParent = px;  
  138.     }  
  139.     //修改px的父指针   
  140.     y->pParent = px->pParent;  
  141.     if ( px->pParent == pguardNode )  
  142.     {  
  143.         *proot = y;  
  144.     }  
  145.     else  
  146.     {  
  147.         if ( px == px->pParent->pLeft )  
  148.         {  
  149.             px->pParent->pLeft = y;  
  150.         }  
  151.         else  
  152.         {  
  153.             px->pParent->pRight = y;  
  154.         }  
  155.     }  
  156.     //重新建立px与y的子父关系   
  157.     y->pRight = px;  
  158.     px->pParent = y;  
  159. }  
  160. //中序遍历   
  161. void InorderTreeWalk(RBNode* proot, RBNode* pguardNode)  
  162. {  
  163.     if ( proot != pguardNode && proot != NULL)  
  164.     {  
  165.         InorderTreeWalk( proot->pLeft, pguardNode );  
  166.         cout << "key=" << proot->key << "/t" << "color=";  
  167.         proot->color == RED ? cout << "red" : cout << "black";  
  168.         cout << endl;  
  169.         InorderTreeWalk( proot->pRight, pguardNode );  
  170.     }  
  171. }  
  172. //采用中序遍历递归的方法在树中寻找一个元素   
  173. void FindNodeInBSTree(RBNode* x, int key, RBNode** pnode,RBNode* pguardNode)  
  174. {  
  175.     if ( x != NULL && *pnode == NULL && x != pguardNode  )  
  176.     {  
  177.           
  178.         //cout << "In Left"<< endl;   
  179.         FindNodeInBSTree( x->pLeft, key, pnode,pguardNode);  
  180.         //cout << "Out Left"<< endl;   
  181.           
  182.         //cout << x->key << endl;   
  183.         if ( x->key == key )  
  184.         {  
  185.             *pnode = x;  
  186.             //cout << "===========" << x->key << "============" << endl;   
  187.             return;  
  188.         }  
  189.           
  190.         //cout << "In Right"<< endl;   
  191.         FindNodeInBSTree( x->pRight, key, pnode, pguardNode);  
  192.         //cout << "Out Right"<< endl;   
  193.     }  
  194. }  
  195. //插入   
  196. void RBInsert(RBNode** proot,RBNode* pnode, RBNode* pguardNode)  
  197. {  
  198.     RBNode* y = pguardNode;  
  199.     RBNode* x = *proot;  
  200.     while ( x != pguardNode && x!= NULL )   
  201.     {  
  202.         y = x;  
  203.         if ( pnode->key < x->key)  
  204.         {  
  205.             x = x->pLeft;  
  206.         }  
  207.         else  
  208.         {  
  209.             x = x->pRight;  
  210.         }  
  211.     }  
  212.     pnode->pParent = y;  
  213.     if ( y == pguardNode )  
  214.     {  
  215.         *proot = pnode;  
  216.     }  
  217.     else  
  218.     {  
  219.         if ( pnode->key < y->key )  
  220.         {  
  221.             y->pLeft = pnode;  
  222.         }  
  223.         else  
  224.         {  
  225.             y->pRight = pnode;  
  226.         }  
  227.     }  
  228.     pnode->pLeft = pguardNode;  
  229.     pnode->pRight = pguardNode;  
  230.     pnode->color = RED;  
  231.     RBInsertFixup( proot, pnode, pguardNode );  
  232. }  
  233. //插入修正   
  234. void RBInsertFixup(RBNode** proot, RBNode* x, RBNode* pguardNode)  
  235. {  
  236.     while ( x->pParent->color == RED )  
  237.     {  
  238.         //x的父节点 == x的祖父节点的左子树   
  239.         if ( x->pParent == x->pParent->pParent->pLeft )  
  240.         {  
  241.             RBNode* y = x->pParent->pParent->pRight;  
  242.             if ( y->color == RED )  
  243.             {  
  244.                 x->pParent->color = BLACK;  
  245.                 y->color = BLACK;  
  246.                 x->pParent->pParent->color = RED;  
  247.                 x = x->pParent->pParent;  
  248.             }  
  249.             else  
  250.             {  
  251.                 if ( x == x->pParent->pRight )  
  252.                 {  
  253.                     x = x->pParent;  
  254.                     LeftRotate(proot,x,pguardNode);  
  255.                 }  
  256.                 x->pParent->color = BLACK;  
  257.                 x->pParent->pParent->color = RED;  
  258.                 RightRotate(proot,x->pParent->pParent, pguardNode);  
  259.             }  
  260.         }//end if x的父节点 == x的祖父节点的左子树   
  261.         else// else x的父节点 == x的祖父节点的右子树   
  262.         {  
  263.             RBNode* y = x->pParent->pParent->pLeft;  
  264.             if ( y->color == RED )  
  265.             {  
  266.                 x->pParent->color = BLACK;  
  267.                 y->color = BLACK;  
  268.                 x->pParent->pParent->color = RED;  
  269.                 x = x->pParent->pParent;  
  270.             }  
  271.             else  
  272.             {  
  273.                 if ( x == x->pParent->pLeft )  
  274.                 {  
  275.                     x = x->pParent;  
  276.                     RightRotate(proot,x,pguardNode);  
  277.                 }  
  278.                 x->pParent->color = BLACK;  
  279.                 x->pParent->pParent->color = RED;  
  280.                 LeftRotate(proot,x->pParent->pParent, pguardNode);  
  281.             }  
  282.           
  283.         }  
  284.     }//end while loop   
  285.     (*proot)->color = BLACK;  
  286. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值