//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. 【Android】利用服务Service创建标题栏通知

    创建标题栏通知的核心代码 public void CreateInform() { //定义一个PendingIntent,当用户点击通知时,跳转到某个Activity(也可以发送广播等) Inten ...

  2. ios开发——实用技术篇OC篇&获取设备唯一标识

    获取设备唯一标识 WWDC 2013已经闭幕,IOS7 Beta随即发布,界面之难看无以言表...,简直就是山寨Android. 更让IOS程序猿悲催的是,设备唯一标识的MAC Address在IOS ...

  3. 《RESTful Web Services》第三章 设计表述

    3.1 如何使用实体头来注解表述     表述不仅仅是以某种格式序列化后的数据,它是一连串字节加上用于描述那些字节的元数据.     Content-Type,用于描述表述类型.这个标头告诉接收方如何 ...

  4. log4net的应用

    1.下载log4net 2编写log4net的配置文件 <?xml version="1.0" encoding="utf-8" ?> <co ...

  5. JSONP(处理跨域问题)

    Ajax直接请求普通文件存在跨域无权限访问的问题 凡是拥有"src"这个属性的标签都拥有跨域的能力,比如<script>.<img>.<iframe& ...

  6. B - Plane of Tanks: Pro

    Description Vasya has been playing Plane of Tanks with his friends the whole year. Now it is time to ...

  7. 远程管理之VNC

    远程管理的基本概念 ①RDP(remote desktop protocol)协议 远程桌面协议,我们常用的windows操作系统就是的远程桌面管理就是基于该协议的,更多有关RDP协议的可以查看百度百 ...

  8. 如何删除C/C++源代码中的注释

    具体代码: #include <stdlib.h>  #include <stdio.h>  //删除注释  void commentFilter(FILE* sourceFi ...

  9. TensorFlow学习之运行label_image实例

    前段时间,搞了搞编译label_image中cc的实例,最后终于搞定...但想在IDE中编译还没成功,继续摸索中. 现分享一下,探究过程,欢迎叨扰,交流. 个人地址:http://home.cnblo ...

  10. LeetCode 342

    Power of Four Given an integer (signed 32 bits), write a function to check whether it is a power of ...