相关问题:(利用链表实现可合并堆) 可合并堆支持以下操作:MAKE-HEAP(创建一个空的可合并堆),INSERT,MAXIMUM,EXTRACT-MAX和UNION。说明在下列前提下如何用链表实现可合并堆。试着使各操作尽可能高效。分析每个操作按动态集合规模的运行时间。
由于对于堆操作需要查找父结点,以及左右孩子结点,所以本程序中用到了非递归非辅助栈的遍历与查找操作,它需要O(nlgn)时间,
a.链表已排序。
INSERT:尽管链表已排序。但是由于插入时,需要查找其父结点,所以运行时间也要O(nlgn)
MAXIMUM:因为已经排序,所以我们直接返回根结点即可找到最大值。
EXTRACT-MAX:删除时,涉及到了第一个结点(根结点)和最后一个结点(最小值结点),由于没有保存最后一个结点,所以又要进行查询操作,这样时间还是O(nlgn)时间,
UNION:用遍历树形链表的方法进行循环将第一颗树的结点插入到第二颗树中,那么总的运行时间为O((n^2)lgn).
b.链表未排序。
需要说明的就是MAXIMUM函数运行时间达到了O(n),因为在查询最大值前,要进行建堆操作。其他操作都一样。
c.链表未排序,且待合并的动态集合是不想交的。
不相交,就是没有相同元素,省略了对相同数据进行可合并堆的各种操作。
以下代码展示了链表未排序时的可合并堆的各项操作。
#include <iostream>
using namespace std;
#define LEN sizeof(struct Tree)
int heap_size1=0, heap_size2=0;;
#define Print 0
#define search 1
struct Tree*head1=NULL;
struct Tree*head2=NULL;
struct Tree
{
int key;
int num;
struct Tree*lchild;
struct Tree*rchild;
struct Tree*parent;
};
void Make_heap(struct Tree*&p)
{
p=NULL;
}
int PARENT(int i)
{
return i/2;
}
int LEFT(int i)
{
return 2*i;
}
int RIGHT(int i)
{
return 2*i+1;
}
void create(struct Tree **p,int flag)
{
static struct Tree *head=NULL;
static struct Tree *p1