二项队列
时间:2022-04-22
本文章向大家介绍二项队列,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
二项队列是 堆序 的集合,也叫 森林。其中每一种形式都有约束。
二项树Bk由一个带有儿子的B0,B1,B2...组成,高度为k的二项树 恰好有2^k个结点。每一种高度只能出现一次...因此,只有1,2,4,8...等结点数目的二项树
deleteMin操作需要快速的找出跟的所有子树的能力,因此需要一般树的表示方法:
每个结点的儿子都在一个链表中,而且每个结点都有一个指向它的第一个儿子的指针。
二项树的每一个结点包括:数据,第一个儿子,以及右兄弟
下面是二项队列类构架及结点定义:
1 template <typename Comparable>
2 class BinomialQueue
3 {
4 public:
5 BinomialQueue();
6 BinomialQueue(const Comparable & item);
7 BinomialQueue(const BinomialQueue & rhs);
8 ~BinomialQueue();
9
10 bool isEmpty() const;
11 const Comparable & findMin() const;
12
13 void insert(const Comparable & x);
14 void deleteMin();
15 void deleteMin(Comparable & minItem);
16
17 void makeEmpty();
18 void merge(BinomialQueue & rhs);
19
20 const BinomialQueue & operator=(const BinomialQueue & rhs);
21 private:
22 struct BinomialNode
23 {
24 Comparable element;
25 BinomiaNode *leftChild;
26 BinomialNode *nextSibling;
27
28 BinomialNode(const Comparable & theElement,BinomialNode *lt,BinomialNode *rt)
29 :element(theElement),leftChild(lt),rightChild(rt)
30 {
31 }
32 };
33
34 enum{DEFAULT_TREES = 1};
35
36 int currentSize;
37 vector<BinomialNode *> const;
38 int capacity() const;
39 BinomialNode * combineTrees(BinomialNode *t1,BinomialNode *t2);
40 void makeEmpty(BinomialNode * & t);
41 BinomialNode * clone(BinomialNode *t) const;
42 };
合并同样大小的两棵树二项树的例程:
1 BinomialNode * combineTrees(BinomialNode *t1,BinomialNode *t2)
2 {
3 if(t2->element < t1->element)
4 return combineTrees(t2,t1);
5 t1->nextSibling = t1->leftChild;
6 t1->leftChild = t2;
7 return t1;
8 }
合并两个优先队列的例程:
1 void merge(BinomialQueue & rhs)
2 {
3 if(this==&rhs)
4 return;
5 currentSize += rhs.currentSize;
6 if(currentSize > capacity())
7 {
8 int oldNumTrees = theTrees.size();
9 int newNumTrees = max(theTrees.size(),rhs.theTrees.size())+1;
10 theTrees.resize(newNumTrees);
11 for(int i = oldNumTrees; i<newNumTrees; i++)
12 theTrees[i] = NULL;
13 }
14 BinomialNode *carry = NULL;
15 for(int i=0,j=1; j<=currentSize; i++,j*=2)
16 {
17 BinomialNode *t1 = theTrees[i];
18 BinomialNode *t2 = i < rhs.theTrees.size()? rhs.theTrees[i]:NULL;
19
20 int whichCase = t1 == NULL ? 0 : 1;
21 whichCase += t2 == NULL? 0 : 2;
22 whichCase += carry == NULL? 0 : 4;
23
24 switch(whichCase)
25 {
26 case 0:
27 case 1:
28 break;
29 case 2:
30 theTrees[i] = t2;
31 rhs.theTrees[i] = NULL;
32 break;
33 case 4:
34 theTrees[i] = carry;
35 carry = NULL;
36 break;
37 case 3:
38 carry = combineTrees(t1,t2);
39 theTrees[i] = rhs.theTrees[i] = NULL;
40 break;
41 case 5:
42 carry = combineTrees(t1,carry);
43 theTrees[i] = NULL;
44 break;
45 case 6:
46 carry = combineTrees(t2,carry);
47 rhs.theTrees[i] = NULL;
48 break;
49 case 7:
50 theTrees[i] = carry;
51 carry = combineTrees(t1,t2);
52 rhs.theTrees[i] = NULL;
53 break;
54 }
55 }
56 for(int k = 0; k < rhs.theTrees.size(); k++)
57 rhs.theTrees[k] = NULL;
58 rhs.currentSize = 0;
59 }
deleteMin程序:
1 void deleteMin(Comparable & minItem)
2 {
3 if(isEmpty())
4 throw UnderflowException();
5 int minIndex = findMinIndex();
6 minItem = theTrees[minIndex]->element;
7
8 BinomialNode *oldRoot = theTrees[minIndex];
9 BinomialNode *deletedTree = oldRoot->leftChild;
10 delete oldRoot;
11
12 BinomialQueue deletedQueue;
13 deletedQueue.theTrees.resize(minIndex+1);
14 deletedQueue.currentSize = (1<<minIndex)-1;
15 for(int j = minIndex -1 ;j >= 0 ; j--)
16 {
17 deletedQueue.theTrees[ j ] = deletedTree;
18 deletedTree = deletedTree->nextSibling;
19 deletedQueue.theTrees[ j ]->nextSibling = NULL;
20 }
21
22 theTrees[minIndex] = NULL;
23 currentSize -= deletedQueue.currentSize + 1;
24
25 merge(deletedQueue);
26 }
27 int findMinIndex() const
28 {
29 int i;
30 int minIndex;
31
32 for( i = 0; theTrees[i] === NULL;i++)
33 ;
34 for(minIndex = i; i < theTrees.size();i++)
35 if(theTrees[i] != NULL && theTrees[i]->element < theTrees[minIndex]->element)
36 minIndex = i;
37
38 return minIndex;
39 }
- 《Redis设计与实现》读书笔记(二十九) ——Redis集群执行命令与重新分片
- 如何使用C语言的面向对象
- 《Redis设计与实现》读书笔记(三十) ——Redis集群节点复制与故障转移
- 掌握一点儿统计学
- 高通HAL层之bmp18x.cpp
- Oracle 数据库之最:你见过最高的 SQL Version 是多少?
- Android 子activity关闭 向父activity传值
- 《Redis设计与实现》读书笔记(三十一) ——Redis集群消息类型
- 统计学中的相关性分析
- 《Redis设计与实现》读书笔记(三十二) ——Redis事务设计与实现
- 收藏一个简洁的PHP可逆加密函数
- 《Redis设计与实现》读书笔记(三十二) ——Redis集发布订阅设计与实现
- Android点击EditText文本框之外任何地方隐藏键盘的解决办法
- Spark 1.4为DataFrame新增的统计与数学函数
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ESP8266烧入nodemcu简易教程
- 搭建简易的物联网服务端和客户端-STM32(一)
- 搭建简易的物联网服务端和客户端-Nodejs_net(二)
- 搭建简易的物联网服务端和客户端-Nodejs_mysql(三)
- 搭建简易的物联网服务端和客户端-net+mysql(四)
- 搭建简易的物联网服务端和客户端-Nodejs_express服务(六)
- TF中Placement的最后一道防线——Placer
- 搭建简易的物联网服务端和客户端-ECharts数据显示(七)
- 搭建简易的物联网服务端和客户端-整合(八)
- 搭建简易的物联网服务端和客户端-Maibu显示(九)
- 搭建简易的物联网服务端和客户端-DCloud手机端(十)
- 整理了一份 Docker系统知识,从安装到熟练操作看这篇就够
- 搭建简易的物联网服务端和客户端-第一次增补(十一)
- 搭建简易的物联网服务端和客户端-第二次增补(十二)
- 使用jest进行单元测试