//my.h
//定义两个数据类型,货物Goods,箱子Box #include <vector>
#include <cstddef>
#include <iostream>
struct Goods
{
int id;
double weight;
Goods(int i,double w):id(i),weight(w) { }
~Goods()
{ };
}; struct Box
{
int id;
std::vector<Goods*> vG;
double space;
Box(int i,double f,Goods* x = NULL)
{
id = i;
space = f;
if(x != NULL)
vG.push_back(x);
} Box& operator-= (Goods& rhs)
{
space -= rhs.weight;
vG.push_back(&rhs);
return *this;
} Box(Box& rhs)
{
operator=(rhs);
} Box& operator= (const Box& rhs)
{
if(this == &rhs)
return *this;
id = rhs.id;
space = rhs.space;
vG = rhs.vG;
return *this;
} ~Box()
{
int n = vG.size();
for(int i = ; i < n; ++i)
delete vG[i];
} }; bool operator< (const Box& lhs, const Box& rhs)
{
return (lhs.space < rhs.space);
}
bool operator== (const Box& lhs,const Box& rhs)
{
return (lhs.space == rhs.space && lhs.id == rhs.id);
}
bool operator<= (const Box& lhs,const Box& rhs)
{
return !(rhs < lhs);
}
bool operator> (const Box& lhs,int a)
{
return (lhs.space > a);
}
bool operator< (const Box& lhs,const Goods& rhs)
{
return (lhs.space < rhs.weight);
}
bool operator< (const Goods& lhs, const Box& rhs)
{
return (lhs.weight < rhs.space);
}
bool operator== (const Box& lhs,const Goods& rhs)
{
return (lhs.space == rhs.weight);
} std::ostream& operator<< (std::ostream& out,const Box& b)
{
out << "Box: " << b.id << std::endl;
int n = b.vG.size();
if( n > )
{
for(int i = ; i < n-; ++i)
out << "\t" << b.vG[i]->id << " " << b.vG[i]->weight << std::endl;
out << "\t" << b.vG[n-]->id << " " << b.vG[n-]->weight;
}
return out;
}
 //avl.h
//主体部分,建立一个AVL树,实现best fit #include "my.h"
#include <algorithm>
//#include <utility> template<class T,class V>
class Avl
{
public:
Avl():root(NULL),len() { }
Avl(const Avl& rhs)
{
operator= (rhs);
} ~Avl()
{
makeEmpty();
}
void makeEmpty(); void insert( V* x); //GOODS const Avl& operator= (const Avl& rhs)
{
if(this == &rhs)
return *this;
Avl temp(rhs);
swap(*this,temp);
return *this;
} void output()
{
for(int i = ; i < vT.size(); ++i)
std::cout << *(vT[i]) << std::endl;
output(root);
}
private:
struct Node
{
T* element;
Node *left;
Node *right;
int height; Node(T* x,Node *lt,Node *rt,int h = )
:element(x),left(lt),right(rt),height(h) { }
~Node()
{
delete element;
element = NULL;
}
};
Node *root;
int len;
std::vector<T*> vT; int height(const Node* t) const
{ return t == NULL ? - : t->height; } void insert(T* x, Node* &t); //BOX
//void insert(V* x, Node* &t); //GOODS
void remove(Node* p,Node* &t);
void percolateDown(Node* t);
Node* find(V* x,Node* t);
Node* findmin(Node* t) const;
Node* findmax(Node* t) const; //can't use const Node* t
void rotateWithLeftChild(Node* & k2);
void rotateWithRightChild(Node* & k2);
void doubleWithLeftChild(Node* & k3);
void doubleWithRightChild(Node* & k3);
void makeEmpty(Node* & t);
void output(Node* t)
{
if(t != NULL)
{
output(t->left);
output(t->right);
std::cout << *(t->element) << std::endl;
}
}
}; template<class T,class V>
void Avl<T,V>::insert(V* x)
{
Node* t = find(x,root);
if(t != NULL)
{
*(t->element) -= *x;
//t->element->insert(x);
if(*(t->element) > 1e-)
percolateDown(t);
else
{
Node* p = t;
if(t->right)
p = findmin(t->right);
else
p = findmax(t->left);
remove(p,root);
swap(t->element,p->element);
vT.push_back(p->element);
}
}
else
{
T* b = new Box(len+,-x->weight,x);
//b->insert(x);
++len;
insert(b,root);
} } template<class T,class V>
void Avl<T,V>::remove(Node* p, Node* & t)
{
if(t == NULL)
return;
else if(*(p->element) < *(t->element))
{
remove(p,t->left);
if(height(t->left) - height(t->right) == -)
rotateWithRightChild(t); }
else if(*(t->element) < *(p->element))
{
remove(p,t->right);
if(height(t->left) - height(t->right) == )
rotateWithLeftChild(t);
}
else
{
t = t->left != NULL ? t->left : t->right;
p->left = NULL;
p->right = NULL;
return;
}
t->height = max(height(t->left),height(t->right)) + ;
} template<class T,class V>
void Avl<T,V>::insert(T* x, Node* &t)
{
if(t == NULL)
t = new Node(x,NULL,NULL);
else if( *x < *(t->element))
{
insert(x,t->left);
if(height(t->left) - height(t->right) == )
{
if(*x < *(t->left->element))
rotateWithLeftChild(t);
else
doubleWithLeftChild(t);
}
}
else
{
insert(x,t->right);
if(height(t->right) - height(t->left) == )
{
if( *(t->right->element) <= *x)
rotateWithRightChild(t);
else
doubleWithRightChild(t);
}
}
t->height = max(height(t->left),height(t->right)) + ;
} template<class T,class V>
typename Avl<T,V>::Node* Avl<T,V>::find(V* x,Node* t)
{
Node* p = NULL;
while(t != NULL)
{
if( *(t->element) < *x)
{
t = t->right;
}
else if( *x < *(t->element))
{
p = t;
t = t->left;
}
else
{
p = t;
break;
}
}
return p;
} template<class T,class V>
void Avl<T,V>::percolateDown(Node* t)
{
while(t->left != NULL || t->right != NULL)
{
if(t->left != NULL && (*(t->element) < *(t->left->element)))
{
swap(t->element,t->left->element);
t = t->left;
}
else if(t->right != NULL && (*(t->right->element) < *(t->element)))
{
swap(t->element,t->right->element);
t = t->right;
}
else
break;
}
} template<class T,class V>
typename Avl<T,V>::Node* Avl<T,V>::findmin(Node* t) const //can't use const Node* t
{
if(t != NULL)
while(t->left != NULL)
t = t->left;
return t;
} template<class T,class V>
typename Avl<T,V>::Node* Avl<T,V>::findmax(Node* t) const
{
if(t != NULL)
while(t->right != NULL)
t = t->right;
return t;
} template<class T,class V>
void Avl<T,V>::rotateWithLeftChild(Node* & k2)
{
Node* k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2->height = max(height(k2->left),height(k2->right)) + ;
k1->height = max(height(k1->left),k2->height) + ;
k2 = k1;
} template<class T,class V>
void Avl<T,V>::rotateWithRightChild(Node* & k2)
{
Node* k1 = k2->right;
k2->right = k1->left;
k1->left = k2;
k2->height = max(height(k2->left),height(k2->right)) + ;
k1->height = max(height(k1->left),k2->height) + ;
k2 = k1;
} template<class T,class V>
void Avl<T,V>::doubleWithLeftChild(Node* & k3)
{
rotateWithRightChild(k3->left);
rotateWithLeftChild(k3);
} template<class T,class V>
void Avl<T,V>::doubleWithRightChild(Node* & k3)
{
rotateWithLeftChild(k3->right);
rotateWithRightChild(k3);
} template<class T,class V>
void Avl<T,V>::makeEmpty()
{
makeEmpty(root);
} template<class T,class V>
void Avl<T,V>::makeEmpty(Node* & t)
{
if(t != NULL)
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
t = NULL;
for(int i = ; i < vT.size(); ++i)
delete vT[i];
}
 //main.cpp
/***********************************
装箱问题:利用AVL树
1、实现首次适配算法
2、实现最佳适配算法
作者:陈卫安
时间:2014-04-09
***********************************/
#include "avl.h"
//#include <iostream>
using namespace std; void inputGoods(vector<Goods*>& G)
{
double w;
int i = ;
Goods* p = NULL;
while(cin)
{
cin >> w;
p = new Goods(i,w);
G.push_back(p);
i++;
}
} void FirstFit(Avl<Box,Goods>& boxtree,const vector<Goods*>& G)
{
for(int i = ; i < G.size(); i++)
boxtree.insert(G[i]);
} int main()
{
Avl<Box,Goods> boxtree;
vector<Goods*> G;
inputGoods(G);
FirstFit(boxtree,G);
boxtree.output();
return ;
}

思路:

  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. CircleDisplay

    https://github.com/PhilJay/CircleDisplay

  2. ios开发——面试篇(一)

    面试篇之内存管理与多线程 简述OC中内存管理机制.­­­­­与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为 ...

  3. 华为 真机当作测试机 打开log开关

    拨号界面输入*#*#2846579#*#*进入测试模式,点击"pyojectmeu"-点击第三个-"后台设置"-进入了之后-点击第2个-"log设置& ...

  4. 通过缓存数据库结果提高PHP性能(转)

    众所周知,缓存数据库查询的结果可以显著缩短脚本执行时间,并最大限度地减少数据库服务器上的负载.如果要处理的数据基本上是静态的,则该技术将非常有效.这是因为对远程数据库的许多数据请求最终可以从本地缓存得 ...

  5. centosx64位寄存器

    [root@monitor ~]# uname -aLinux monitor 2.6.32-431.23.3.el6.x86_64 #1 SMP Thu Jul 31 17:20:51 UTC 20 ...

  6. Debian 7 64位安装 wine

    一.安装 1. # apt-get install wine 安装完后在终端里运行wine: # wine 会弹出一个对话框: This is the wine64-bin helper packag ...

  7. 通过 Session 操纵对象

    Session 接口是 Hibernate 向应用程序提供的操纵数据库的最主要的接口, 它提供了基本的保存, 更新, 删除和加载 Java 对象的方法. Session 具有一个缓存, 位于缓存中的对 ...

  8. scrapy yield Request

    import scrapy from myproject.items import MyItem class MySpider(scrapy.Spider): name = ’example.com’ ...

  9. [转]Oracle hang分析

    hanganalyze是ORACLE的一款性能诊断工具,这个款工具是从oracle 8.0.6开始可用,在oracle数据库出现严重的性能问题的时候它可以帮助你定位问题所在. 1.首先说说hangan ...

  10. github/hexo搭建个人博客几个问题总结

    问题一:hexo ERROR Deployer not found: github or hexo ERROR Deployer not found: git npm install hexo-dep ...