利用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:结构介绍 ...
随机推荐
- GLSL实现Glow效果 [转]
http://blog.csdn.net/a3070173/archive/2008/11/04/3220940.aspx Glow即辉光效果现在已成为3D图形中一个引人注目的特效.本文主要介绍如何使 ...
- Delphi 多文件拖放获取路径示例
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ...
- Unable to automatically debug "XXXXX“
I solved this issue by going to C:\Program Files\Microsoft VisualStudio10.0\Common7\IDE then running ...
- android146 360 病毒查杀
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- Cordova 3.0 + Eclipse 开发流程
cd d:\cordova\projectscordova create HelloWorld com.example.helloworld HelloWorldcd HelloWorldcordov ...
- 1050. String Subtraction (20)
this problem is from PAT, which website is http://pat.zju.edu.cn/contests/pat-a-practise/1050. firs ...
- start.s中的.balignl 16,0xdeadbeef
转载:http://blog.csdn.net/l_thread/article/details/6020036 开始看start.s中的代码,又一句.balignl 16,0xdeadbeef,不知 ...
- Python 字典排序
思路是把字典转为列表后再排序 d={'z':1,'y':2,'x':3} # 字典 s=d.items() # [('y', 2), ('x', 3), ('z', 1)] 列表 s.sort() # ...
- The Story of self Parameter in Python, Demystified
转自:http://www.programiz.com/article/python-self-why If you have been programming in Python (in obj ...
- python(6)-logging 日志模块
logging的日志分为5个级别分别为debug(), info(), warning(), error(), critical() 先来看一下简单的代码: logging.basicConfig(f ...