鱼C论坛

 找回密码
 立即注册
查看: 2416|回复: 0

小甲鱼来看看AVL树的问题

[复制链接]
发表于 2014-6-29 19:51:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

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

x
我按你的教程敲的代码(虽然是C++的),测试正常,不过我前序遍历树时,根据遍历结果画出来的树不是AVL树,求解决
  1. #ifndef AVL_H_INCLUDED
  2. #define AVL_H_INCLUDED

  3. #include <memory>
  4. #include <initializer_list>
  5. #include <iostream>


  6. template <class Type>
  7. class AVL{
  8.     enum BF{RH = -1, EH, LH};

  9.     struct BiTreeNode {
  10.         Type _data;
  11.         BF _bf;
  12.         std::shared_ptr<BiTreeNode> _lChild;
  13.         std::shared_ptr<BiTreeNode> _rChild;
  14.     };

  15.     typedef std::shared_ptr<BiTreeNode> Tree;

  16. public:
  17.     typedef size_t size_type;
  18.     typedef Type value_type;
  19.     typedef value_type& reference;
  20.     typedef const reference const_reference;

  21.     AVL(const AVL<Type>&) = delete;
  22.     AVL<Type>& operator=(const AVL<Type>&) = delete;

  23.     AVL() = default;
  24.     AVL(const std::initializer_list<Type>& li) : AVL(li.begin(), li.end()) {}
  25.     template <class In> AVL(In first, In last);

  26.     AVL<Type>& push(const Type&);
  27. //    AVL<Type>& pop(const Type&);
  28.     bool find(const Type&)const;
  29.     size_type size()const { return _size; }
  30.     bool empty()const { return _size == 0; }
  31.     const_reference root() const { return _root ->_data; }
  32.     void show()const { show(_root); }

  33. private:
  34.     bool push(Tree& root, const Type&, bool& taller);
  35.     void left_balance(Tree& root);
  36.     void left_rotate(Tree& root); // 左旋操作
  37.     void right_balance(Tree& root);
  38.     void right_rotate(Tree& root); // 右旋操作
  39.     bool find(const Tree&, const Type&)const;
  40.     void show(const Tree&)const;

  41.     Tree _root;
  42.     size_type _size = 0;
  43. };

  44. template <class Type>
  45. bool AVL<Type>::push(Tree& root, const Type& item, bool& taller)
  46. {
  47.     if (!root) {
  48.         root = std::make_shared<BiTreeNode>();
  49.         root ->_bf = EH;
  50.         root ->_data = item;
  51.         taller = true;
  52.         ++_size;
  53.     }
  54.     else if (item == root ->_data)
  55.         return taller = false;
  56.     else if (item < root ->_data) {

  57.         if (!push(root ->_lChild, item, taller))
  58.             return false;

  59.         if (taller) { // 树的高度增加了
  60.             switch (root ->_bf) {

  61.             case LH: // 未插入时左子树比右子树高
  62.                      // 形成不平衡局面
  63.                 left_balance(root); // 调整
  64.                 taller = false; // 平衡后树的高度不增加
  65.                 break;

  66.             case EH: // 未插入时树左右一样高
  67.                 root ->_bf = LH; // 插入后左子树比右子树高
  68.                 taller = true; // 树的高度增加了
  69.                 break;

  70.             case RH: // 未插入时右子树高
  71.                 root ->_bf = EH; // 插入后左右子树一样高
  72.                 taller = false; // 树的高度未增加
  73.                 break;
  74.             }
  75.         }
  76.         else { // 没有成功地插入左子树

  77.             if (!push(root ->_rChild, item, taller))
  78.                 return false;

  79.             if (taller) {
  80.                 switch (root ->_bf) {

  81.                 case LH:
  82.                     root ->_bf = EH;
  83.                     taller = false;
  84.                     break;

  85.                 case EH:
  86.                     root ->_bf = RH;
  87.                     taller = true;
  88.                     break;

  89.                 case RH:
  90.                     right_balance(root);
  91.                     taller = false;
  92.                     break;
  93.                 }
  94.             }
  95.         }
  96.     }
  97.     else {
  98.         if (!push(root ->_rChild, item, taller))
  99.             return false;

  100.         if (taller) {
  101.             switch (root ->_bf) {

  102.             case LH:
  103.                 root ->_bf = EH;
  104.                 taller = false;
  105.                 break;

  106.             case EH:
  107.                 root ->_bf = RH;
  108.                 taller = true;
  109.                 break;

  110.                 case RH:
  111.                 right_balance(root);
  112.                 taller = false;
  113.                 break;
  114.                 }
  115.             }
  116.         else {
  117.         if (!push(root ->_lChild, item, taller))
  118.             return false;

  119.         if (taller) {
  120.             switch (root ->_bf) {

  121.             case LH:

  122.                 left_balance(root);
  123.                 taller = false;
  124.                 break;

  125.             case EH:
  126.                 root ->_bf = LH;
  127.                 taller = true;
  128.                 break;

  129.             case RH:
  130.                 root ->_bf = EH;
  131.                 taller = false;
  132.                 break;
  133.                 }
  134.             }
  135.         }
  136.     }
  137.     return false;
  138. }

  139. template <class Type>
  140. void AVL<Type>::left_balance(Tree& root)
  141. {
  142.     Tree l = root ->_lChild, lr;

  143.     switch (l ->_bf) {

  144.     case LH: // 若左子树比右子树高
  145.         root ->_bf = l ->_bf = EH;
  146.         right_rotate(root); // 右旋
  147.         break;

  148.     case RH:
  149.         lr = l ->_rChild;

  150.         switch (lr ->_bf) {

  151.         case LH:
  152.             root ->_bf = RH;
  153.             l ->_bf = EH;
  154.             break;

  155.         case EH:
  156.             root ->_bf = l ->_bf = EH;
  157.             break;

  158.         case RH:
  159.             root ->_bf = EH;
  160.             l ->_bf = LH;
  161.             break;
  162.         }
  163.         lr ->_bf = EH;
  164.         left_rotate(root ->_lChild); // 双旋处理
  165.         right_rotate(root);

  166.         break;
  167.     }
  168. }

  169. template <class Type>
  170. void AVL<Type>::right_rotate(Tree& root)
  171. {
  172.     Tree l = root ->_lChild;

  173.     root ->_lChild = l ->_rChild;
  174.     l ->_rChild = root;
  175.     root = l;
  176. }

  177. template <class Type>
  178. void AVL<Type>::left_rotate(Tree& root)
  179. {
  180.     Tree r = root ->_rChild;

  181.     root ->_rChild = r ->_lChild;
  182.     r ->_lChild = root;
  183.     root = r;
  184. }

  185. template <class Type>
  186. void AVL<Type>::right_balance(Tree& root)
  187. {
  188.     Tree l = root ->_lChild, lr;

  189.     switch (l ->_bf) {

  190.     case RH:// 若右子树比左子树高
  191.         root ->_bf = l ->_bf = EH;
  192.         left_rotate(root);
  193.         break;

  194.     case LH:
  195.         lr = l ->_rChild;

  196.         switch (lr ->_bf) {

  197.         case LH:
  198.             root ->_bf = RH;
  199.             l ->_bf = EH;
  200.             break;

  201.         case EH:
  202.             root ->_bf = l ->_bf = EH;
  203.             break;

  204.         case RH:
  205.             root ->_bf = EH;
  206.             l ->_bf = LH;
  207.             break;
  208.         }
  209.         lr ->_bf = EH;
  210.         right_rotate(root ->_rChild); // 双旋处理
  211.         left_rotate(root);

  212.         break;
  213.     }
  214. }

  215. template <class Type>
  216. AVL<Type>& AVL<Type>::push(const Type& item)
  217. {
  218.     bool taller;
  219.     push(_root, item, taller);
  220.     return *this;
  221. }


  222. template <class Type>
  223. template <class In>
  224. AVL<Type>::AVL(In first, In last)
  225. {
  226.     while (first != last)
  227.         push(*first++);
  228. }

  229. template <class Type>
  230. bool AVL<Type>::find(const Type& item)const
  231. {
  232.     return find(_root, item);
  233. }

  234. template <class Type>
  235. bool AVL<Type>::find(const Tree& root, const Type& item)const
  236. {
  237.     if (root) {
  238.         if (root ->_data == item)
  239.             return true;
  240.         if (item < root ->_data)
  241.             return find(root ->_lChild, item);
  242.         else
  243.             return find(root ->_rChild, item);
  244.     }

  245.     return false;
  246. }

  247. template <class Type>
  248. void AVL<Type>::show(const Tree& root)const
  249. {
  250.     if (root) {
  251.         std::cout << "root:\n";
  252.         std::cout << root ->_data << '\n';


  253.         std::cout << "lChild:\n";
  254.         show(root ->_lChild);

  255.         if (root == _root)
  256.             std::cout << "真*根节点";

  257.         std::cout << "rChild:\n";
  258.         show(root ->_rChild);

  259.         if (!root ->_lChild && !root ->_rChild)
  260.             std::cout << "*************************\n";
  261.     }
  262. }

  263. #endif // AVL_H_INCLUDED
复制代码
测试代码
  1. #include "AVL.h"
  2. #include <iostream>

  3. int main()
  4. {
  5.     AVL<int> avl {5,7,8,9,3,0,1,2,4,1,5};

  6.     std::cout << "size: " << avl.size() << "\nfind(5) = " << avl.find(5) << "\nfind(1) = " << avl.find(1)
  7.     << "\nfind(8) = " << avl.find(8) << "\nfind(10) = " << avl.find(10) << "\nfind(0) = " << avl.find(0)
  8.     << "\nfind(4) = " << avl.find(4) << "\nfind(3) = " << avl.find(3) << "\nfind(2) = " << avl.find(2) << "\nfind(7) = "
  9.     << avl.find(7) << "\nfind(9) = " << avl.find(9) << "\n";
  10.     avl.show();
  11.     avl.push(10);
  12.     std::cout << "\nfind(10) = " << avl.find(10) << "\n";
  13.     return 0;
  14. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 20:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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