利用AVL树实现搬箱问题的best fit策略
//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策略的更多相关文章
- 【数据结构与算法Python版学习笔记】树——平衡二叉搜索树(AVL树)
定义 能够在key插入时一直保持平衡的二叉查找树: AVL树 利用AVL树实现ADT Map, 基本上与BST的实现相同,不同之处仅在于二叉树的生成与维护过程 平衡因子 AVL树的实现中, 需要对每个 ...
- 数据结构图文解析之:AVL树详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由
03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...
- 二叉树-二叉查找树-AVL树-遍历
一.二叉树 定义:每个节点都不能有多于两个的儿子的树. 二叉树节点声明: struct treeNode { elementType element; treeNode * left; treeNod ...
- 我的新发现:AVL树旋转的一个特性
关于AVL树旋转的代码网络上铺天盖地. 一些经典的实现方法如下: AVLTree SingleLeftRotation(AVLTree A) { AVLTree B = A->left; A-& ...
- 红黑树和AVL树的实现与比较-----算法导论
一.问题描述 实现3种树中的两种:红黑树,AVL树,Treap树 二.算法原理 (1)红黑树 红黑树是一种二叉查找树,但在每个结点上增加一个存储位表示结点的颜色,可以是red或black.红黑树满足以 ...
- AVL树(平衡二叉查找树)
首先要说AVL树,我们就必须先说二叉查找树,先介绍二叉查找树的一些特性,然后我们再来说平衡树的一些特性,结合这些特性,然后来介绍AVL树. 一.二叉查找树 1.二叉树查找树的相关特征定义 二叉树查找树 ...
- 单例模式,堆,BST,AVL树,红黑树
单例模式 第一种(懒汉,线程不安全): public class Singleton { private static Singleton instance; private Singleton () ...
- AVL树(Java实现)
AVL树基本介绍 AVL树是一种自平衡的二叉查找树,在AVL树中任何节点的两个子树的高度差不能超过1.就是相当于在二叉搜索树的基础上,在插入和删除时进行了平衡处理. 不平衡的四种情况 LL:结构介绍 ...
随机推荐
- ListView 文件重命名
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Control ...
- EDIT Ini写Ini配置
EDIT Ini写Ini配置 uses IniFiles; {$R *.dfm} function IniFileName:string; begin Result:=ExtractFil ...
- iOS开发——语法&高级Block练习
高级Block练习 一 .最简单的block使用 使用block的三个步骤:1.定义block变量 2.创建block代码块 3.调用block匿名函数 定义一个block的构成包括:返回值,bloc ...
- ABAP FIELD-SYMBOLS 有大作用- 将没有可改参数的增强出口变得也能改主程序的值了
看下图代码: report z_xul_test2 中 定义了 全局变量 G_DATA1 , 分别调用了 z_xul_tes1 中的 form 和 function zbapi_test , 这两 ...
- oc-04-类的声明和实现
//main.m //10-[掌握]类的声明和实现 //.h为类的声明,.m为类的实现,+表示类方法静态方法,-表示对象方法..h文件中的方法都是public不能更改的.变量3中访问域:public, ...
- ant脚本打jar包 自动获取时间以及项目svn版本号
1.关键代码,获取时间 <tstamp> <format property="touch.time" pattern="yyyy/MM/dd hh:mm ...
- RDDTest.scala
/** * Created by root on 9/7/15. */ import org.apache.spark.SparkContext import org.apache.spark.Spa ...
- C#并行编程 (Barrier,CountdownEvent,ManualResetEventSlim,SemaphoreSlim,SpinLock,SpinWait )
背景 有时候必须访问变量.实例.方法.属性或者结构体,而这些并没有准备好用于并发访问,或者有时候需要执行部分代码,而这些代码必须单独运行,这是不得不通过将任务分解的方式让它们独立运行. 当任务和线程要 ...
- Helpers\PHPMailer
Helpers\PHPMailer PHPMailer is a third party class for sending emails, Full docs are available athtt ...
- BUG: GetDC() ReleaseDC()引起的内存泄漏
调用CWnd::GetDC函数跟CWnd::ReleaseDC函数的代码运行时,会出现 4 个字节的内存泄漏. Microsoft 已经确认这是在本文开头部分列出的 Microsoft 产品中的缺陷. ...