1. //my.h
  2. //定义两个数据类型,货物Goods,箱子Box
  3.  
  4. #include <vector>
  5. #include <cstddef>
  6. #include <iostream>
  7. struct Goods
  8. {
  9. int id;
  10. double weight;
  11. Goods(int i,double w):id(i),weight(w) { }
  12. ~Goods()
  13. { };
  14. };
  15.  
  16. struct Box
  17. {
  18. int id;
  19. std::vector<Goods*> vG;
  20. double space;
  21. Box(int i,double f,Goods* x = NULL)
  22. {
  23. id = i;
  24. space = f;
  25. if(x != NULL)
  26. vG.push_back(x);
  27. }
  28.  
  29. Box& operator-= (Goods& rhs)
  30. {
  31. space -= rhs.weight;
  32. vG.push_back(&rhs);
  33. return *this;
  34. }
  35.  
  36. Box(Box& rhs)
  37. {
  38. operator=(rhs);
  39. }
  40.  
  41. Box& operator= (const Box& rhs)
  42. {
  43. if(this == &rhs)
  44. return *this;
  45. id = rhs.id;
  46. space = rhs.space;
  47. vG = rhs.vG;
  48. return *this;
  49. }
  50.  
  51. ~Box()
  52. {
  53. int n = vG.size();
  54. for(int i = ; i < n; ++i)
  55. delete vG[i];
  56. }
  57.  
  58. };
  59.  
  60. bool operator< (const Box& lhs, const Box& rhs)
  61. {
  62. return (lhs.space < rhs.space);
  63. }
  64. bool operator== (const Box& lhs,const Box& rhs)
  65. {
  66. return (lhs.space == rhs.space && lhs.id == rhs.id);
  67. }
  68. bool operator<= (const Box& lhs,const Box& rhs)
  69. {
  70. return !(rhs < lhs);
  71. }
  72. bool operator> (const Box& lhs,int a)
  73. {
  74. return (lhs.space > a);
  75. }
  76. bool operator< (const Box& lhs,const Goods& rhs)
  77. {
  78. return (lhs.space < rhs.weight);
  79. }
  80. bool operator< (const Goods& lhs, const Box& rhs)
  81. {
  82. return (lhs.weight < rhs.space);
  83. }
  84. bool operator== (const Box& lhs,const Goods& rhs)
  85. {
  86. return (lhs.space == rhs.weight);
  87. }
  88.  
  89. std::ostream& operator<< (std::ostream& out,const Box& b)
  90. {
  91. out << "Box: " << b.id << std::endl;
  92. int n = b.vG.size();
  93. if( n > )
  94. {
  95. for(int i = ; i < n-; ++i)
  96. out << "\t" << b.vG[i]->id << " " << b.vG[i]->weight << std::endl;
  97. out << "\t" << b.vG[n-]->id << " " << b.vG[n-]->weight;
  98. }
  99. return out;
  100. }
  1. //avl.h
  2. //主体部分,建立一个AVL树,实现best fit
  3.  
  4. #include "my.h"
  5. #include <algorithm>
  6. //#include <utility>
  7.  
  8. template<class T,class V>
  9. class Avl
  10. {
  11. public:
  12. Avl():root(NULL),len() { }
  13. Avl(const Avl& rhs)
  14. {
  15. operator= (rhs);
  16. }
  17.  
  18. ~Avl()
  19. {
  20. makeEmpty();
  21. }
  22. void makeEmpty();
  23.  
  24. void insert( V* x); //GOODS
  25.  
  26. const Avl& operator= (const Avl& rhs)
  27. {
  28. if(this == &rhs)
  29. return *this;
  30. Avl temp(rhs);
  31. swap(*this,temp);
  32. return *this;
  33. }
  34.  
  35. void output()
  36. {
  37. for(int i = ; i < vT.size(); ++i)
  38. std::cout << *(vT[i]) << std::endl;
  39. output(root);
  40. }
  41. private:
  42. struct Node
  43. {
  44. T* element;
  45. Node *left;
  46. Node *right;
  47. int height;
  48.  
  49. Node(T* x,Node *lt,Node *rt,int h = )
  50. :element(x),left(lt),right(rt),height(h) { }
  51. ~Node()
  52. {
  53. delete element;
  54. element = NULL;
  55. }
  56. };
  57. Node *root;
  58. int len;
  59. std::vector<T*> vT;
  60.  
  61. int height(const Node* t) const
  62. { return t == NULL ? - : t->height; }
  63.  
  64. void insert(T* x, Node* &t); //BOX
  65. //void insert(V* x, Node* &t); //GOODS
  66. void remove(Node* p,Node* &t);
  67. void percolateDown(Node* t);
  68. Node* find(V* x,Node* t);
  69. Node* findmin(Node* t) const;
  70. Node* findmax(Node* t) const; //can't use const Node* t
  71. void rotateWithLeftChild(Node* & k2);
  72. void rotateWithRightChild(Node* & k2);
  73. void doubleWithLeftChild(Node* & k3);
  74. void doubleWithRightChild(Node* & k3);
  75. void makeEmpty(Node* & t);
  76. void output(Node* t)
  77. {
  78. if(t != NULL)
  79. {
  80. output(t->left);
  81. output(t->right);
  82. std::cout << *(t->element) << std::endl;
  83. }
  84. }
  85. };
  86.  
  87. template<class T,class V>
  88. void Avl<T,V>::insert(V* x)
  89. {
  90. Node* t = find(x,root);
  91. if(t != NULL)
  92. {
  93. *(t->element) -= *x;
  94. //t->element->insert(x);
  95. if(*(t->element) > 1e-)
  96. percolateDown(t);
  97. else
  98. {
  99. Node* p = t;
  100. if(t->right)
  101. p = findmin(t->right);
  102. else
  103. p = findmax(t->left);
  104. remove(p,root);
  105. swap(t->element,p->element);
  106. vT.push_back(p->element);
  107. }
  108. }
  109. else
  110. {
  111. T* b = new Box(len+,-x->weight,x);
  112. //b->insert(x);
  113. ++len;
  114. insert(b,root);
  115. }
  116.  
  117. }
  118.  
  119. template<class T,class V>
  120. void Avl<T,V>::remove(Node* p, Node* & t)
  121. {
  122. if(t == NULL)
  123. return;
  124. else if(*(p->element) < *(t->element))
  125. {
  126. remove(p,t->left);
  127. if(height(t->left) - height(t->right) == -)
  128. rotateWithRightChild(t);
  129.  
  130. }
  131. else if(*(t->element) < *(p->element))
  132. {
  133. remove(p,t->right);
  134. if(height(t->left) - height(t->right) == )
  135. rotateWithLeftChild(t);
  136. }
  137. else
  138. {
  139. t = t->left != NULL ? t->left : t->right;
  140. p->left = NULL;
  141. p->right = NULL;
  142. return;
  143. }
  144. t->height = max(height(t->left),height(t->right)) + ;
  145. }
  146.  
  147. template<class T,class V>
  148. void Avl<T,V>::insert(T* x, Node* &t)
  149. {
  150. if(t == NULL)
  151. t = new Node(x,NULL,NULL);
  152. else if( *x < *(t->element))
  153. {
  154. insert(x,t->left);
  155. if(height(t->left) - height(t->right) == )
  156. {
  157. if(*x < *(t->left->element))
  158. rotateWithLeftChild(t);
  159. else
  160. doubleWithLeftChild(t);
  161. }
  162. }
  163. else
  164. {
  165. insert(x,t->right);
  166. if(height(t->right) - height(t->left) == )
  167. {
  168. if( *(t->right->element) <= *x)
  169. rotateWithRightChild(t);
  170. else
  171. doubleWithRightChild(t);
  172. }
  173. }
  174. t->height = max(height(t->left),height(t->right)) + ;
  175. }
  176.  
  177. template<class T,class V>
  178. typename Avl<T,V>::Node* Avl<T,V>::find(V* x,Node* t)
  179. {
  180. Node* p = NULL;
  181. while(t != NULL)
  182. {
  183. if( *(t->element) < *x)
  184. {
  185. t = t->right;
  186. }
  187. else if( *x < *(t->element))
  188. {
  189. p = t;
  190. t = t->left;
  191. }
  192. else
  193. {
  194. p = t;
  195. break;
  196. }
  197. }
  198. return p;
  199. }
  200.  
  201. template<class T,class V>
  202. void Avl<T,V>::percolateDown(Node* t)
  203. {
  204. while(t->left != NULL || t->right != NULL)
  205. {
  206. if(t->left != NULL && (*(t->element) < *(t->left->element)))
  207. {
  208. swap(t->element,t->left->element);
  209. t = t->left;
  210. }
  211. else if(t->right != NULL && (*(t->right->element) < *(t->element)))
  212. {
  213. swap(t->element,t->right->element);
  214. t = t->right;
  215. }
  216. else
  217. break;
  218. }
  219. }
  220.  
  221. template<class T,class V>
  222. typename Avl<T,V>::Node* Avl<T,V>::findmin(Node* t) const //can't use const Node* t
  223. {
  224. if(t != NULL)
  225. while(t->left != NULL)
  226. t = t->left;
  227. return t;
  228. }
  229.  
  230. template<class T,class V>
  231. typename Avl<T,V>::Node* Avl<T,V>::findmax(Node* t) const
  232. {
  233. if(t != NULL)
  234. while(t->right != NULL)
  235. t = t->right;
  236. return t;
  237. }
  238.  
  239. template<class T,class V>
  240. void Avl<T,V>::rotateWithLeftChild(Node* & k2)
  241. {
  242. Node* k1 = k2->left;
  243. k2->left = k1->right;
  244. k1->right = k2;
  245. k2->height = max(height(k2->left),height(k2->right)) + ;
  246. k1->height = max(height(k1->left),k2->height) + ;
  247. k2 = k1;
  248. }
  249.  
  250. template<class T,class V>
  251. void Avl<T,V>::rotateWithRightChild(Node* & k2)
  252. {
  253. Node* k1 = k2->right;
  254. k2->right = k1->left;
  255. k1->left = k2;
  256. k2->height = max(height(k2->left),height(k2->right)) + ;
  257. k1->height = max(height(k1->left),k2->height) + ;
  258. k2 = k1;
  259. }
  260.  
  261. template<class T,class V>
  262. void Avl<T,V>::doubleWithLeftChild(Node* & k3)
  263. {
  264. rotateWithRightChild(k3->left);
  265. rotateWithLeftChild(k3);
  266. }
  267.  
  268. template<class T,class V>
  269. void Avl<T,V>::doubleWithRightChild(Node* & k3)
  270. {
  271. rotateWithLeftChild(k3->right);
  272. rotateWithRightChild(k3);
  273. }
  274.  
  275. template<class T,class V>
  276. void Avl<T,V>::makeEmpty()
  277. {
  278. makeEmpty(root);
  279. }
  280.  
  281. template<class T,class V>
  282. void Avl<T,V>::makeEmpty(Node* & t)
  283. {
  284. if(t != NULL)
  285. {
  286. makeEmpty(t->left);
  287. makeEmpty(t->right);
  288. delete t;
  289. }
  290. t = NULL;
  291. for(int i = ; i < vT.size(); ++i)
  292. delete vT[i];
  293. }
  1. //main.cpp
  2. /***********************************
  3. 装箱问题:利用AVL树
  4. 1、实现首次适配算法
  5. 2、实现最佳适配算法
  6. 作者:陈卫安
  7. 时间:2014-04-09
  8. ***********************************/
  9. #include "avl.h"
  10. //#include <iostream>
  11. using namespace std;
  12.  
  13. void inputGoods(vector<Goods*>& G)
  14. {
  15. double w;
  16. int i = ;
  17. Goods* p = NULL;
  18. while(cin)
  19. {
  20. cin >> w;
  21. p = new Goods(i,w);
  22. G.push_back(p);
  23. i++;
  24. }
  25. }
  26.  
  27. void FirstFit(Avl<Box,Goods>& boxtree,const vector<Goods*>& G)
  28. {
  29. for(int i = ; i < G.size(); i++)
  30. boxtree.insert(G[i]);
  31. }
  32.  
  33. int main()
  34. {
  35. Avl<Box,Goods> boxtree;
  36. vector<Goods*> G;
  37. inputGoods(G);
  38. FirstFit(boxtree,G);
  39. boxtree.output();
  40. return ;
  41. }

思路:

  1、当树为空时,建立一个新节点(即开辟一个新箱子);

  2、若不为空,寻找最适合的节点(箱子),space =  1 - weight,然后下滤到合适位置;

  3、若箱子容量为0,从树中删除该节点(箱子),存到数组。

  4、若没有找到能够容下该货品的节点(箱子),开辟一个箱子,插入到树里。

编程时遇到的一些问题:

  1、函数形参Node* 前面不能加cosnt,如果加了const,只能传递const类型的数据指针作为实参。这点和传值Node& 不一样,const Node& 表示即可以传const类型的数据,也可以传非const类似的数据。

  2、Node* find()  返回一个类里面定义的数据类型,这是一个类型成员,类似vector<int>::size_type,需要在返回类型前面加类限定符,

  改为 typename Avl<T,V>::Node*  find()  ;需要在前面加typename限制,表明这是一个类型成员。

利用AVL树实现搬箱问题的best fit策略的更多相关文章

  1. 【数据结构与算法Python版学习笔记】树——平衡二叉搜索树(AVL树)

    定义 能够在key插入时一直保持平衡的二叉查找树: AVL树 利用AVL树实现ADT Map, 基本上与BST的实现相同,不同之处仅在于二叉树的生成与维护过程 平衡因子 AVL树的实现中, 需要对每个 ...

  2. 数据结构图文解析之:AVL树详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  3. PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由

    03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...

  4. 二叉树-二叉查找树-AVL树-遍历

    一.二叉树 定义:每个节点都不能有多于两个的儿子的树. 二叉树节点声明: struct treeNode { elementType element; treeNode * left; treeNod ...

  5. 我的新发现:AVL树旋转的一个特性

    关于AVL树旋转的代码网络上铺天盖地. 一些经典的实现方法如下: AVLTree SingleLeftRotation(AVLTree A) { AVLTree B = A->left; A-& ...

  6. 红黑树和AVL树的实现与比较-----算法导论

    一.问题描述 实现3种树中的两种:红黑树,AVL树,Treap树 二.算法原理 (1)红黑树 红黑树是一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是red或black.红黑树满足以 ...

  7. AVL树(平衡二叉查找树)

    首先要说AVL树,我们就必须先说二叉查找树,先介绍二叉查找树的一些特性,然后我们再来说平衡树的一些特性,结合这些特性,然后来介绍AVL树. 一.二叉查找树 1.二叉树查找树的相关特征定义 二叉树查找树 ...

  8. 单例模式,堆,BST,AVL树,红黑树

    单例模式 第一种(懒汉,线程不安全): public class Singleton { private static Singleton instance; private Singleton () ...

  9. AVL树(Java实现)

    AVL树基本介绍 AVL树是一种自平衡的二叉查找树,在AVL树中任何节点的两个子树的高度差不能超过1.就是相当于在二叉搜索树的基础上,在插入和删除时进行了平衡处理. 不平衡的四种情况 LL:结构介绍 ...

随机推荐

  1. IOS AutoLayout 文章

    开始iOS 7中自动布局教程(一) 开始iOS 7中自动布局教程(二) 代码的方式自动布局 自动布局时计算Cell高度

  2. iOS开发——语法篇&swift经典语法总结

    swift经典语法总结 1:函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如果有参数和返回值直接写在两个括号里就可以了 1.2 参数需 ...

  3. jQuery訪问属性,绝对定位

    一. jQuery訪问属性 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  4. oc-01

    //#ifndef __OCDay01__aa__ //#define __OCDay01__aa__ //这2行是预编译指令,防止include的时候重复包含操作(a包含b,b又包含了a) #inc ...

  5. unix fopen和fopen_s用法的比较

    在定义FILE * fp 之后,fopen的用法是: fp = fopen(filename,"w").而对于fopen_s来说,还得定义另外一个变量errno_t err,然后e ...

  6. Eclipse对printf()不能输出到控制台的解决方法

    方案1: 在main 语句中加一条 setbuf(stdout,NULL); 这个即可. 在ecplise下使用cdt开发c程序,发现运行后终端没有输出,停止后会输出,通过在main中添加 setbu ...

  7. 小白日记3:kali渗透测试之被动信息收集(二)-dig、whios、dnsenum、fierce

    一.DIG linux下查询域名解析有两种选择,nslookup或者dig.Dig(Domain Information Groper)是一个在类Unix命令行模式下查询DNS包括NS记录,A记录,M ...

  8. poj2299解题报告(归并排序求逆序数)

    POJ 2299,题目链接http://poj.org/problem?id=2299 题意: 给出长度为n的序列,每次只能交换相邻的两个元素,问至少要交换几次才使得该序列为递增序列. 思路: 其实就 ...

  9. Android(java)学习笔记85:案例拨号程序

    手机拨号程序:(只有程序代码) package cn.itcast.phone; import android.app.Activity; import android.content.Intent; ...

  10. ip 子网掩码 网关 DNS

    这一篇文章也很好: 原文引用于:  http://www.cnblogs.com/jiqing9006/p/3365939.html 内外网ip: IP地址: IPv4地址分为A.B.C.D.E五类, ...