1 //my.h 2 //定义两个数据类型,货物Goods,箱子Box 3 4 #include <vector> 5 #include <cstddef> 7 #include <iostream> 8 struct Goods 9 { 10 int id; 11 double weight; 12 Goods(int i,double w):id(i),weight(w) { } 13 ~Goods() 14 { }; 15 }; 16 17 struct Box 18 { 19 int id; 20 std::vector<Goods*> vG; 21 double space; 22 Box(int i,double f,Goods* x = NULL) 23 { 24 id = i; 25 space = f; 26 if(x != NULL) 27 vG.push_back(x); 28 } 29 30 Box& operator-= (Goods& rhs) 31 { 32 space -= rhs.weight; 33 vG.push_back(&rhs); 34 return *this; 35 }
42 Box(Box& rhs) 43 { 44 operator=(rhs); 45 } 46 47 48 Box& operator= (const Box& rhs) 49 { 50 if(this == &rhs) 51 return *this; 52 id = rhs.id; 53 space = rhs.space; 54 vG = rhs.vG; 55 return *this; 56 } 57 58 ~Box() 59 { 60 int n = vG.size(); 61 for(int i = 0; i < n; ++i) 62 delete vG[i]; 63 } 64 65 }; 66 67 bool operator< (const Box& lhs, const Box& rhs) 68 { 69 return (lhs.space < rhs.space); 70 } 71 bool operator== (const Box& lhs,const Box& rhs) 72 { 73 return (lhs.space == rhs.space && lhs.id == rhs.id); 74 } 75 bool operator<= (const Box& lhs,const Box& rhs) 76 { 77 return !(rhs < lhs); 78 } 79 bool operator> (const Box& lhs,int a) 80 { 81 return (lhs.space > a); 82 } 83 bool operator< (const Box& lhs,const Goods& rhs) 84 { 85 return (lhs.space < rhs.weight); 86 } 87 bool operator< (const Goods& lhs, const Box& rhs) 88 { 89 return (lhs.weight < rhs.space); 90 } 91 bool operator== (const Box& lhs,const Goods& rhs) 92 { 93 return (lhs.space == rhs.weight); 94 } 95 96 std::ostream& operator<< (std::ostream& out,const Box& b) 97 { 98 out << "Box: " << b.id << std::endl; 99 int n = b.vG.size(); 100 if( n > 0) 101 { 102 for(int i = 0; i < n-1; ++i) 103 out << "\t" << b.vG[i]->id << " " << b.vG[i]->weight << std::endl; 104 out << "\t" << b.vG[n-1]->id << " " << b.vG[n-1]->weight; 105 } 106 return out; 107 }
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(0) { } 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 = 0; 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 = 0) 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 ? -1 : 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-5) 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+1,1-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) == -2) 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) == 2) 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)) + 1; 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) == 2) 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) == 2) 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)) + 1; 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)) + 1; 246 k1->height = max(height(k1->left),k2->height) + 1; 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)) + 1; 257 k1->height = max(height(k1->left),k2->height) + 1; 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 = 0; 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 = 0; 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 = 0; 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 0; 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限制,表明这是一个类型成员。