+ -
当前位置:首页 → 问答吧 → C++实现的avl树模板类源代码

C++实现的avl树模板类源代码

时间:2010-09-11

来源:互联网

业余时间没事自己实现了个avl树的C++模板类,留着平时用。在这里公开,供大家参考。
断断续续的写了挺长时间,主要是自己动力不足。

实现代码:
  1. /*
  2. *AVL_TREE
  3. *完成了添加、删除、查找节点功能。
  4. *author:lysde
  5. *date:2010-9-9
  6. *Email: [email protected]
  7. *参考资料:http://sjjg.js.zwu.edu.cn/SFXX/chazhao/chazhao7.3.2.html
  8. *免责:作者不对代码做任何担保。遵循apache授权许可。
  9. */
  10. #include <iostream>

  11. /* Instruction
  12. * The tree's base level is 1.
  13. * When inserting a node to the tree,if the node value
  14. * is already in the tree then return true and do nothing.
  15. * 中序遍历树需要回调函数
  16. *
  17. */


  18. template<class T>
  19. class avl_tree
  20. {
  21. public:
  22.         struct node
  23.         {
  24.                 node(T d) {data = d; lc = rc = prnt = NULL; LL = RL = L = 0;}
  25.                 T        data;
  26.                 int        LL,RL,L; // left level,right level,self level.
  27.                 node *lc,*rc,*prnt;
  28.         };

  29. public:
  30.         avl_tree()
  31.         {
  32.                 root = NULL;
  33.                 size = 0;
  34.         }

  35.         ~avl_tree()
  36.         {
  37.                 if(root)
  38.                 {
  39.                         //delete all the nodes.
  40.                         del_subtree(root);
  41.                 }
  42.         }
  43.         //Any question please send email: [email protected]
  44.         //If there exists the node return true,else return false.
  45.         node * search(T data)
  46.         {
  47.                 bool flag = false;
  48.                 node *ntmp = NULL;
  49.                 if(!root)
  50.                         return false;
  51.                 ntmp = root;
  52.                 while(ntmp != NULL && !flag)
  53.                 {
  54.                         if(data == ntmp->data)
  55.                         {
  56.                                 flag=true;
  57.                         }
  58.                         else if(data < ntmp->data)
  59.                         {
  60.                                 ntmp = ntmp->lc;
  61.                         }
  62.                         else
  63.                         {
  64.                                 ntmp = ntmp->rc;
  65.                         }
  66.                 }
  67.                 if(flag)
  68.                         return ntmp;
  69.                 else
  70.                         return NULL;
  71.         }

  72.         //If insert the node successfully return true,else return false.
  73.         bool insert(T data)
  74.         {
  75.                 if(!root)
  76.                 {
  77.                         root = new node(data);
  78.                         root->LL = root->RL = 0;
  79.                         root->L = 1;
  80.                         size++;
  81.                         return true;
  82.                 }
  83.                 //There is a data in the tree.
  84.         //        if(search(data)) return true;
  85.                
  86.                 node *n, *parent=NULL, *ntmp, *child;
  87.                 //Find a position to insert the data in the tree.
  88.                 ntmp = root;
  89.                 bool flag = false;
  90.                 while(ntmp != NULL && !flag)
  91.                 {
  92.                         if(data == ntmp->data)
  93.                         {
  94.                                 flag=true;
  95.                         }
  96.                         else if(data < ntmp->data)
  97.                         {
  98.                                 parent = ntmp;
  99.                                 ntmp = ntmp->lc;
  100.                         }
  101.                         else
  102.                         {
  103.                                 parent = ntmp;
  104.                                 ntmp = ntmp->rc;
  105.                         }
  106.                 }
  107.                 if(flag)
  108.                 {
  109.                         //size++;
  110.                         return true;
  111.                 }
  112.                
  113.                 //Inssert the node.
  114.                 if(ntmp == NULL)
  115.                 {
  116.                         n = new node(data);
  117.                         if(data < parent->data)
  118.                         {
  119.                                 parent->lc = n;
  120.                                 n->prnt = parent;
  121.                                 n->L = parent->L + 1;
  122.                         }
  123.                         else
  124.                         {
  125.                                 parent->rc = n;
  126.                                 n->prnt = parent;
  127.                                 n->L = parent->L + 1;
  128.                         }
  129.                 }
  130.                
  131.                 //Modify all notes' level info.
  132.                 adjust_gene_up(n);
  133.                
  134.                 //Find what model this is.
  135.                 //Ajust the tree to keep it balance.
  136.                 node        *subroot = NULL;
  137.                 ntmp = n->prnt;
  138.                 child = n;
  139.                 while(ntmp->prnt != NULL)
  140.                 {
  141.                         if(ntmp->prnt->LL - ntmp->prnt->RL >= 2 )  // left level - right level > 2
  142.                         {
  143.                                 //LL or LR
  144.                                 if(ntmp->lc == child)
  145.                                 {
  146.                                         //LL
  147.                                         subroot = balancell(child);
  148.                                 }
  149.                                 else
  150.                                 {
  151.                                         //LR
  152.                                         subroot = balancelr(child);
  153.                                        
  154.                                 }
  155.                                 break;       
  156.                         }
  157.                         else if(ntmp->prnt->LL - ntmp->prnt->RL <= -2)
  158.                         {
  159.                                 //RL or RR
  160.                                 if(ntmp->lc == child)
  161.                                 {
  162.                                         //RL
  163.                                         subroot = balancerl(child);
  164.                                 }
  165.                                 else
  166.                                 {
  167.                                         //RR
  168.                                         subroot = balancerr(child);
  169.                                 }
  170.                                 break;                       
  171.                         }
  172.                         child = ntmp;
  173.                         ntmp = ntmp->prnt;
  174.                 }
  175.                 //下面调整最小不平衡树的level信息 及 与该最小不平衡树相关的节点的level 信息。
  176.                 // Adjust the level information.
  177.                 if(subroot)
  178.                 {
  179.                         if(subroot == root)
  180.                                 adjust_level_previous(subroot,0);
  181.                         else
  182.                                 adjust_level_previous(subroot,subroot->prnt->L);
  183.                         adjust_gene_down(subroot);
  184.                         adjust_gene_up(subroot);
  185.                 }
  186.                 size++;
  187.                 return true;
  188.         }

  189.         //If delete the node successfully return true,else return false.
  190.         bool del(T data)
  191.         {
  192.                 //删除后,使用左侧最大值(或右侧最小值)代替被删除值的位置。我们采用左侧最大值。
  193.                 //然后调整该子树的平衡及整棵树的平衡。
  194.                 node * n, *np = NULL, *nn, *nnp = NULL;
  195.                 if( (n = search(data)) == NULL)
  196.                         return false;
  197.                 //
  198.                 if(root == n) //被删结点为root。
  199.                 {
  200.                         if(n->lc == NULL) //左子树不存在
  201.                         {
  202.                                 root = n->rc;
  203.                                 if(n->rc != NULL)
  204.                                 {
  205.                                         root->prnt = NULL;
  206.                                 }
  207.                                 //nnp = nn = root;
  208.                                 nnp = NULL;

  209.                         }
  210.                         else  //存在左子树
  211.                         {
  212.                                 //找到左子树中的最大值
  213.                                 nnp = n;
  214.                                 nn = nnp->lc;
  215.                                 while(nn->rc != NULL)
  216.                                 {
  217.                                         nnp = nn;
  218.                                         nn = nnp->rc;
  219.                                 }

  220.                                 if(nnp == n)
  221.                                 {
  222.                                         root = nn;
  223.                                         root->prnt = NULL;
  224.                                         root->rc = n->rc;
  225.                                         if(n->rc != NULL)
  226.                                                 n->rc->prnt = nn;
  227.                                         nnp = root;
  228.                                 }
  229.                                 else
  230.                                 {
  231.                                         //Left subtree.
  232.                                         root = nn;
  233.                                         root->prnt = NULL;

  234.                                         nnp->rc = nn->lc;
  235.                                         if(nn->lc != NULL)
  236.                                                 nn->lc->prnt = nnp;

  237.                                         nn->lc = n->lc;
  238.                                         n->lc->prnt = nn;
  239.                                         nn->rc = n->rc;
  240.                                         if(n->rc != NULL)
  241.                                                 n->rc->prnt = nn;
  242.                                 }
  243.                         }
  244.                 }
  245.                 else //被删结点为非root。
  246.                 {
  247.                         np = n->prnt;

  248.                         if(n->lc == NULL) //左子树不存在
  249.                         {
  250.                                 if(np->lc == n)
  251.                                 {
  252.                                         np->lc = n->rc;
  253.                                 }
  254.                                 else
  255.                                 {
  256.                                         np->rc = n->rc;
  257.                                 }
  258.                                 if(n->rc != NULL)
  259.                                         n->rc->prnt = np;
  260.                                 nnp = np;
  261.                         }
  262.                         else  //存在左子树
  263.                         {
  264.                                 //找到左子树中的最大值
  265.                                 nnp = n;
  266.                                 nn = nnp->lc;
  267.                                 while(nn->rc != NULL)
  268.                                 {
  269.                                         nnp = nn;
  270.                                         nn = nnp->rc;
  271.                                 }

  272.                                 if(nnp == n)
  273.                                 {
  274.                                         //Left subtree.
  275.                                         if(np->lc == n)
  276.                                         {
  277.                                                 np->lc = nn;
  278.                                         }
  279.                                         else  //Right subtree.
  280.                                         {
  281.                                                 np->rc = nn;
  282.                                         }
  283.                                         nn->prnt = np;
  284.                                         nn->rc = n->rc;
  285.                                         if(n->rc != NULL)
  286.                                                 n->rc->prnt = nn;
  287.                                         nnp = nn;
  288.                                 }
  289.                                 else
  290.                                 {
  291.                                         //Left subtree.
  292.                                         if(np->lc == n)
  293.                                         {
  294.                                                 np->lc = nn;
  295.                                         }
  296.                                         else  //Right subtree.
  297.                                         {
  298.                                                 np->rc = nn;
  299.                                         }
  300.                                         nn->prnt = np;
  301.                                         nnp->rc = nn->lc;
  302.                                         if(nn->lc != NULL)
  303.                                                 nn->lc->prnt = nnp;

  304.                                         nn->lc = n->lc;
  305.                                         n->lc->prnt = nn;
  306.                                         nn->rc = n->rc;
  307.                                         if(n->rc != NULL)
  308.                                                 n->rc->prnt = nn;
  309.                                 }
  310.                         }
  311.                 }
  312.                 delete n;
  313.                 size--;
  314.                
  315.                 //调整树的平衡及各结点的level信息
  316.                 node * subroot;
  317.                 while(nnp != NULL)
  318.                 {
  319.                         adjust_level_previous(root,0);
  320.                         adjust_gene_down(root);
  321.                         adjust_gene_up(root);

  322.                         if(nnp->LL - nnp->RL >= 2)
  323.                         {
  324.                                 //LL or LR
  325.                                 if(nnp->lc->LL - nnp->lc->RL >= 0)
  326.                                 {
  327.                                         //LL
  328.                                         //subroot = balancell(nnp->lc->lc);
  329.                                         nnp = balancell(nnp->lc->lc);
  330.                                 }
  331.                                 else
  332.                                 {
  333.                                         //LR
  334.                                         nnp = balancelr(nnp->lc->rc);
  335.                                 }
  336.                         }
  337.                         else if(nnp->LL - nnp->RL <= -2)
  338.                         {
  339.                                 //RR or RL
  340.                                 if(nnp->rc->LL - nnp->rc->RL <= 0)
  341.                                 {
  342.                                         //RR
  343.                                         nnp = balancerr(nnp->rc->rc);
  344.                                 }
  345.                                 else
  346.                                 {
  347.                                         //RL
  348.                                         nnp = balancerl(nnp->rc->lc);
  349.                                 }
  350.                         }
  351.                         if(nnp!= NULL)
  352.                                 nnp = nnp->prnt;
  353.                 }

  354.                 adjust_level_previous(root,0);
  355.                 adjust_gene_down(root);
  356.                 adjust_gene_up(root);

  357.                 return true;
  358.         }

  359.         typedef void (*outfunc)(const node *);
  360.         void mt(outfunc fnc) {midorder_travel(root,fnc);}

  361.         long height() const
  362.         {
  363.                 long high;
  364.                 high = root->LL >= root->RL? root->LL : root->RL;
  365.                 high ++;
  366.                 return high;
  367.         }

  368.         int  get_size() { return size;}
  369.         node * search(const node *n) { return search(n->data);};
  370.         node *get_root_data() { return root; }
  371.         node *min_node()
  372.         {
  373.                 node * t,*tp = NULL;
  374.                 t = root;
  375.                 while(t)
  376.                 {
  377.                         tp = t;
  378.                         t = t->lc;
  379.                 }
  380.                 return tp;
  381.         }
  382.         node *max_node()
  383.         {
  384.                 node * t,*tp = NULL;
  385.                 t = root;
  386.                 while(t)
  387.                 {
  388.                         tp = t;
  389.                         t = t->rc;
  390.                 }
  391.                 return tp;
  392.         }
  393. protected:
  394.         avl_tree(const avl_tree &);
  395.         avl_tree & operator=(const avl_tree&);
  396.         node * balancell(node *n)  //Return the root of the subtree.
  397.         {
  398.                 node * np,*npp,*nppp,*mr;
  399.                 //LL
  400.                 if(!n)
  401.                         return NULL;
  402.                 np = n ->prnt;
  403.                 npp = np->prnt;
  404.                 nppp = np->prnt->prnt;
  405.                
  406.                 //旋转
  407.                 //Rotate
  408.                 np->prnt = nppp;
  409.                 if(nppp != NULL)
  410.                 {
  411.                         if(nppp->lc == npp)
  412.                         {
  413.                                 nppp->lc = np;
  414.                                
  415.                         }
  416.                         else
  417.                         {
  418.                                 nppp->rc = np;
  419.                         }
  420.                 }
  421.                 else
  422.                 {
  423.                         root = np;
  424.                 }
  425.                 mr = np;
  426.                 if(np->rc == NULL)
  427.                 {
  428.                         np->rc = npp;
  429.                         np->prnt = npp->prnt;
  430.                         npp->prnt = np;
  431.                         npp->lc = NULL;
  432.                 }
  433.                 else
  434.                 {
  435.                         npp->lc = np->rc;
  436.                         np->prnt = npp->prnt;
  437.                         np->rc->prnt = npp;
  438.                         np->rc = npp;
  439.                         npp->prnt = np;
  440.                 }
  441.                 return mr;
  442.         }

  443.         node * balancelr(node *n)  //Return the root of the subtree.
  444.         {
  445.                 if(!n)
  446.                         return NULL;
  447.                 node * np,*npp,*nppp;
  448.                 //LR
  449.                 np = n ->prnt;
  450.                 npp = np->prnt;
  451.                 nppp = np->prnt->prnt;
  452.                
  453.                 //旋转
  454.                 //Rotate
  455.                 n->prnt = npp;
  456.                 if(n->lc != NULL)
  457.                 {
  458.                         n->lc->prnt = np;
  459.                         np->rc = n->lc;
  460.                 }
  461.                 else
  462.                         np->rc = NULL;
  463.                 n->lc = np;
  464.                 np->prnt = n;
  465.                 npp->lc = n;
  466.                 return balancell(n->lc);
  467.         }

  468.         node * balancerr(node *n)  //Return the root of the subtree.
  469.         {
  470.                 if(!n)
  471.                         return NULL;
  472.                 node * np,*npp,*nppp,*mr;
  473.                 //RR
  474.                 np = n ->prnt;
  475.                 npp = np->prnt;
  476.                 nppp = np->prnt->prnt;
  477.                
  478.                 //旋转
  479.                 //Rotate
  480.                 np->prnt = nppp;
  481.                 if(nppp != NULL)
  482.                 {
  483.                         if(nppp->rc == npp)
  484.                         {
  485.                                 nppp->rc = np;
  486.                                
  487.                         }
  488.                         else
  489.                         {
  490.                                 nppp->lc = np;
  491.                         }
  492.                 }
  493.                 else
  494.                 {
  495.                         root = np;
  496.                 }
  497.                 mr = np;
  498.                 if(np->lc == NULL)
  499.                 {
  500.                         np->lc = npp;
  501.                         np->prnt = npp->prnt;
  502.                         npp->prnt = np;
  503.                         npp->rc = NULL;
  504.                 }
  505.                 else
  506.                 {
  507.                         npp->rc = np->lc;
  508.                         np->prnt = npp->prnt;
  509.                         np->lc->prnt = npp;
  510.                         np->lc = npp;
  511.                         npp->prnt = np;
  512.                 }
  513.                 return mr;
  514.         }

  515.         node * balancerl(node *n)  //Return the root of the subtree.
  516.         {
  517.                 if(!n)
  518.                         return NULL;
  519.                 node * np,*npp,*nppp;
  520.                 //LR
  521.                 np = n ->prnt;
  522.                 npp = np->prnt;
  523.                 nppp = np->prnt->prnt;
  524.                
  525.                 //旋转
  526.                 //Rotate
  527.                 n->prnt = npp;
  528.                 if(n->rc != NULL)
  529.                 {
  530.                         n->rc->prnt = np;
  531.                         np->lc = n->rc;
  532.                 }
  533.                 else
  534.                         np->lc = NULL;
  535.                                        

  536.                 n->rc = np;
  537.                 np->prnt = n;
  538.                 npp->rc = n;
  539.                 return balancerr(n->rc);
  540.         }
  541.        
  542.         //n is the leaf that is just inserted or the subtree root.
  543.         void adjust_gene_up(node *n)  //Adjuest the tree level info from the new tree leaf.
  544.         {
  545.                 if(!n)
  546.                         return;
  547.                 node *ntmp = n;
  548.                 while(ntmp != NULL && ntmp->prnt != NULL)
  549.                 {
  550.                         if(ntmp->data < ntmp->prnt->data)
  551.                         {
  552.                                 ntmp->prnt->LL = ntmp->LL >= ntmp->RL?ntmp->LL:ntmp->RL;
  553.                                 ntmp->prnt->LL+=1;
  554.                         }
  555.                         else
  556.                         {
  557.                                 ntmp->prnt->RL = ntmp->LL >= ntmp->RL?ntmp->LL:ntmp->RL;
  558.                                 ntmp->prnt->RL+=1;
  559.                         }
  560.                         ntmp = ntmp->prnt;
  561.                 }
  562.         }

  563.         void adjust_level_previous(node *n,int prnt_level)
  564.         {
  565.                 if(!n)
  566.                         return;
  567.                 n->L = prnt_level + 1;
  568.                 if(n->lc != NULL)
  569.                 {
  570.                         adjust_level_previous(n->lc,n->L);
  571.                 }
  572.                 //else if(n->rc != NULL)
  573.                 if(n->rc != NULL)
  574.                 {
  575.                         adjust_level_previous(n->rc,n->L);
  576.                 }
  577.         }

  578.         void adjust_gene_down(node *n)
  579.         {
  580.                 if(!n)
  581.                         return;

  582.                 if(n->lc != NULL)
  583.                 {
  584.                         adjust_gene_down(n->lc);
  585.                 }

  586.                 if(n->rc != NULL)
  587.                 {
  588.                         adjust_gene_down(n->rc);
  589.                 }

  590.                 if(n->lc == NULL)
  591.                 {
  592.                         n->LL = 0;
  593.                 }
  594.                 else
  595.                 {
  596.                         n->LL = n->lc->LL >= n->lc->RL ? n->lc->LL : n->lc->RL;
  597.                         n->LL+=1;
  598.                 }

  599.                 if(n->rc == NULL)
  600.                 {
  601.                         n->RL = 0;
  602.                 }
  603.                 else
  604.                 {
  605.                         n->RL = n->rc->LL >= n->rc->RL?n->rc->LL:n->rc->RL;
  606.                         n->RL+=1;
  607.                 }
  608.         }

  609.         void del_subtree(node *n)
  610.         {
  611.                 if(!n)
  612.                         return;
  613.                 if(n->lc != NULL)
  614.                 {
  615.                         del_subtree(n->lc);
  616.                 }
  617.                 if(n->rc != NULL)
  618.                 {
  619.                         del_subtree(n->rc);
  620.                 }
  621.                 delete n;       
  622.         }


  623.         void midorder_travel(const node *n,outfunc fun)const
  624.         {
  625.                 if(!n)
  626.                         return;
  627.                 if(n->lc != NULL)
  628.                 {
  629.                         midorder_travel(n->lc,fun);
  630.                 }

  631.                 (*fun)(n);

  632.                 if(n->rc != NULL)
  633.                 {
  634.                         midorder_travel(n->rc,fun);
  635.                 }
  636.         }
  637.        
  638.         node        *root;
  639.         int        size;
  640. };
复制代码
AVL树模板类的使用方法,只验证过int、long类型。
  1. //编译方法: g++ test_avl_tree.cpp -o avl
  2. //linux、solaris 验证通过

  3. #include "avl_tree_normal.hpp"
  4. #include <unistd.h>
  5. #include <stdlib.h>
  6. #include <time.h>

  7. #include <iostream>
  8. #include <string>

  9. #define         RANGE                4096
  10. #define  DELRANGE        2048

  11. using namespace std;

  12. void print_value(const avl_tree<long>::node * tn)
  13. {
  14.         static int counter = 0;
  15.         cout << tn->data << "(" << tn->LL - tn->RL << ") ";

  16.         if(counter%4 == 0)
  17.                 cout << endl;
  18.         counter ++;
  19. }
  20. int main()
  21. {
  22.         avl_tree<long> tree;
  23.         avl_tree<long>::node * tn;


  24.         srand(time(NULL));

  25.         for(int i = 0; i < RANGE * 2; i++)
  26.         {
  27.                 int t = rand()%RANGE;
  28.                 tree.insert(t);
  29.         }
  30.        
  31.         tree.mt(print_value);
  32.         cout << endl;
  33.         cout << "tree height: " << tree.height() << endl;
  34.         cout << "Tree size: " << tree.get_size() << endl;
  35.         tn = tree.get_root_data();
  36.         if(tn)
  37.                 cout << "root data: " << tn->data << endl;
  38.         else
  39.                 cout << "root data: " << -99 << endl;
  40.         cout << endl;
  41.         sleep(3);

  42.         cout << "delete list:" << endl;
  43.         for(int i = 0; i < DELRANGE; i++)
  44.         {
  45.                 int t = rand()%RANGE;
  46.                 cout << t << " ";
  47.                 tree.del(t);
  48.         }
  49.         cout << endl;

  50.         cout << "tree height: " << tree.height() << endl;
  51.         cout << "Tree size: " << tree.get_size() << endl;
  52.         tn = tree.get_root_data();
  53.         if(tn)
  54.                 cout << "root data: " << tn->data << endl;
  55.         else
  56.                 cout << "root data: " << -99 << endl;
  57.         tree.mt(print_value);
  58.         cout << endl;

  59.         cout << "tree height: " << tree.height() << endl;
  60.         cout << "Tree size: " << tree.get_size() << endl;
  61.         tn = tree.get_root_data();
  62.         if(tn)
  63.                 cout << "root data: " << tn->data << endl;
  64.         else
  65.                 cout << "root data: " << -99 << endl;
  66.         tn = tree.min_node();
  67.         if(tn)
  68.                 cout << "Minimum data: " << tn->data << endl;
  69.         else
  70.                 cout << "Minimum data: " << -99 << endl;
  71.         tn = tree.max_node();
  72.         if(tn)
  73.                 cout << "Maximum data: " << tn->data << endl;
  74.         else
  75.                 cout << "Maximum data: " << -99 << endl;
  76. }
复制代码

作者: lysde   发布时间: 2010-09-11

avl树啊,标记下, 代码太长了。。

作者: pengjianbokobe   发布时间: 2010-09-11

太长了,拿2分,顺便留下记号,多谢多谢

作者: starzhestarzhe   发布时间: 2010-09-11

相关阅读 更多