用二叉查找树实现持久动态集合
2014-06-29 10:45
323 查看
a) 从根结点到待插入结点的这条路径上的所有结点都需要改变。
b)代码如下:
//13-1持久动态集合 #include <iostream> #include <time.h> using namespace std; #define LEN sizeof(struct Tree) #define m 10//栈的最大容纳空间可以调整 struct Tree { int key; struct Tree*lchild; struct Tree*rchild; }; //非递归的插入函数 struct Tree*PERSISTENT_TREE_INSERT(struct Tree*&root,struct Tree*z) {//只要是注释都是与12章插入函数不同之处。 struct Tree*y=NULL; struct Tree*x=root; struct Tree*root1=NULL,*p=NULL,*p2=NULL;//p为当前新树T’的当前结点。p2为原树T中等于当前结点p->key的值的父结点。 while (x) { y=new struct Tree[LEN]; y->key=x->key;//复制原树T的结点值。 if (root->key==x->key) { p=root1=y;//设置新的复制后的根结点。 } else if (z->key<p2->key) { p->lchild=y;//设置复制后的新树T’的当前结点的左右孩子 p->rchild=p2->rchild; p=p->lchild;//更新新树当前结点。 } else { p->rchild=y; p->lchild=p2->lchild; p=p->rchild; } p2=x; if (z->key<p2->key) x=x->lchild; else x=x->rchild; } y->lchild=y->rchild=NULL;//找到且复制待插入结点的父结点后,把复制后的新父结点左右孩子置空。 if (y==NULL) { root=z; } else if(z->key<y->key) { y->lchild=z; } else y->rchild=z; z->lchild=z->rchild=NULL; return root1; } //非递归的插入函数 void ITERATIVE_TREE_INSERT(struct Tree*&root,struct Tree*z) { struct Tree*y=NULL; struct Tree*x=root; while (x) { y=x; if (z->key<x->key) x=x->lchild; else x=x->rchild; } if (y==NULL) { root=z; } else if(z->key<y->key) { y->lchild=z; } else y->rchild=z; z->lchild=z->rchild=NULL; } //中序遍历 void InOderTraverse(struct Tree *p) { if (p) { InOderTraverse(p->lchild); cout<<p->key<<" "; InOderTraverse(p->rchild); } } void main() { int array[6]={4,3,8,2,7,10}; //int array[10]={5,3,8,2,4,7,10,6,9,11}; int i=0; struct Tree*root=NULL; struct Tree*z=new struct Tree[LEN]; z->key=array[i++];//20 ITERATIVE_TREE_INSERT(root,z); while (i!=6) { z=new struct Tree[LEN]; z->key=array[i++]; ITERATIVE_TREE_INSERT(root,z); } z=new struct Tree[LEN]; z->key=5;//12 struct Tree*root1=PERSISTENT_TREE_INSERT(root,z); InOderTraverse(root);//原树T cout<<endl; InOderTraverse(root1);//新树T’ cout<<endl;
c)时间就是a部分所说的路径上的所有结点,这个结点数量等于树高。而空间上又和新分配结点数成正比,所以时间空间都为O(h).
d)由于增加了父结点,那么需要复制整棵树,为什么呢? 比如题目中的二叉树图所给例子,结点3和4,如果在调用新插入函数时,不对结点3也就是旧结点复制,那么新树T’中的结点3的父结点就会指向旧树中结点4,而不是新树中的结点4,查看结点地址就会明白。所以需要的时间就是Ω(n),在不是必须引入父指针时,最好不要使用它,以免增加时间空间上的工作量。
e)用红黑树实现持久动态集合,又要求最坏时间为O(lgn),那么就不能有父结点,根据13,3-6题目知可以通过辅助栈来实现不带父指针的红黑树,这样就能满足题意。
相关文章推荐
- 持久动态集合的二叉查找树实现
- 算法导论-13-1-持久动态集合
- 算法导论 第13章 13-1 持久动态集合
- 算法导论-13-1-持久动态集合
- 算法导论-13-1-持久动态集合
- Java动态获取某个接口下所有的实现类对象集合
- 通过数组实现类似于集合的功能(包含动态扩容、前平移、后平移、增删改查)
- Java动态获取某个接口下所有的实现类对象集合
- 用jQuery实现遍历集合中的文本动态隐藏消失
- 算法导论-13-1-持久动态集合
- C#中使用BindingList 绑定DataGridView 可以实现动态绑定,优与List<T>集合的绑定
- Java动态获取某个接口下所有的实现类对象集合
- {在Delphi中实现动态字幕}
- 简单实现Crystal Report的动态加载
- 利用动态创建自动化接口实现VB的函数指针调用
- 在.NET中利用FORMULA ONE实现动态报表技术(三)
- C#下实现动态系统托盘图标
- 如何在VC中实现动态菜单
- .net中实现运行时从字符串动态创建对象
- 使用反射在NET中实现动态工厂(第一部分)