利用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:结构介绍 ...
随机推荐
- IOS AutoLayout 文章
开始iOS 7中自动布局教程(一) 开始iOS 7中自动布局教程(二) 代码的方式自动布局 自动布局时计算Cell高度
- iOS开发——语法篇&swift经典语法总结
swift经典语法总结 1:函数 1.1 func funcNmae()->(){} 这样就定义了一个函数,它的参数为空,返回值为空,如果有参数和返回值直接写在两个括号里就可以了 1.2 参数需 ...
- jQuery訪问属性,绝对定位
一. jQuery訪问属性 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- oc-01
//#ifndef __OCDay01__aa__ //#define __OCDay01__aa__ //这2行是预编译指令,防止include的时候重复包含操作(a包含b,b又包含了a) #inc ...
- unix fopen和fopen_s用法的比较
在定义FILE * fp 之后,fopen的用法是: fp = fopen(filename,"w").而对于fopen_s来说,还得定义另外一个变量errno_t err,然后e ...
- Eclipse对printf()不能输出到控制台的解决方法
方案1: 在main 语句中加一条 setbuf(stdout,NULL); 这个即可. 在ecplise下使用cdt开发c程序,发现运行后终端没有输出,停止后会输出,通过在main中添加 setbu ...
- 小白日记3:kali渗透测试之被动信息收集(二)-dig、whios、dnsenum、fierce
一.DIG linux下查询域名解析有两种选择,nslookup或者dig.Dig(Domain Information Groper)是一个在类Unix命令行模式下查询DNS包括NS记录,A记录,M ...
- poj2299解题报告(归并排序求逆序数)
POJ 2299,题目链接http://poj.org/problem?id=2299 题意: 给出长度为n的序列,每次只能交换相邻的两个元素,问至少要交换几次才使得该序列为递增序列. 思路: 其实就 ...
- Android(java)学习笔记85:案例拨号程序
手机拨号程序:(只有程序代码) package cn.itcast.phone; import android.app.Activity; import android.content.Intent; ...
- ip 子网掩码 网关 DNS
这一篇文章也很好: 原文引用于: http://www.cnblogs.com/jiqing9006/p/3365939.html 内外网ip: IP地址: IPv4地址分为A.B.C.D.E五类, ...