排序二叉树的实现和我的一个数据结构设计
2016-12-31 09:52
176 查看
一。基本概念
二叉排序树又称二叉搜索树,即在树的任何一个结点,都满足左子树小于根,根小于右子树。排序二叉树可以作为Map的关键码。主要的作用是快速的查找(相当于二分法)
二。基本算法
1.查找
查找时,首先和根结点对比,若相等,则查找成功。若大于根,则再向右子树查找;如果小于根,则向根的左子树查找;依次类推,直到查找成功或者遇到空结点。
2.插入
找到要插入的位置,类似于上面查找的方式,将新结点插入到查找到的左子树或者右子树。
3.删除
1.当要删除结点不存在左子树,直接将要删除结点的右子树赋给要删除点的父结点的相应子结点
2.当要删除的结点存在左子树,在此结点的左子树中,查找到关键码最大的一个结点r,将r的右指针指要要删除点的右子树,用要删除点的左子树代替要删除点
三。具体代码
声明
View Code
实现
View Code
四。我的新设计
1.使用一个顺序结构存储(比如数组)实际对象 假设叫做list
2.使用一个二叉排序树tree存储list中存储的元素(每个元素是一个对象)的指针或者引用。
3.每次对list添加,删除时,对tree都要做相应的操作
优点:
相当于实现了一个简单的map,可以使用两种方式定位数据对象。比如游戏中存储玩家类,大部分时间是通过id取得玩家对象的,即通过list(索引号)的方式,但同时也可能存在使用名字取得玩家对象的情况,可以把名字存在tree中。tree只是list的一个数据映射,耗费较少的内存。当然,直接使用map<名字,索引号>的方式也是可以的。
还有一个优点是可以比较方便的查找到最大和最小值。
缺点:
不能插入重复的数据。
缺点:
二叉排序树又称二叉搜索树,即在树的任何一个结点,都满足左子树小于根,根小于右子树。排序二叉树可以作为Map的关键码。主要的作用是快速的查找(相当于二分法)
二。基本算法
1.查找
查找时,首先和根结点对比,若相等,则查找成功。若大于根,则再向右子树查找;如果小于根,则向根的左子树查找;依次类推,直到查找成功或者遇到空结点。
2.插入
找到要插入的位置,类似于上面查找的方式,将新结点插入到查找到的左子树或者右子树。
3.删除
1.当要删除结点不存在左子树,直接将要删除结点的右子树赋给要删除点的父结点的相应子结点
2.当要删除的结点存在左子树,在此结点的左子树中,查找到关键码最大的一个结点r,将r的右指针指要要删除点的右子树,用要删除点的左子树代替要删除点
三。具体代码
声明
View Code
1 template<class KEY> 2 class BinSearchTree 3 { 4 public: 5 BinSearchTree(KEY k) 6 { 7 llink = NULL; 8 rlink = NULL; 9 key = k; 10 } 11 public: 12 KEY key; 13 BinSearchTree* llink; 14 BinSearchTree* rlink; 15 16 17 int search(KEY key,BinSearchTree<KEY>** position); 18 int insert(KEY key); 19 int delete_node(KEY key); 20 };
实现
View Code
1 template<class KEY> 2 int BinSearchTree<KEY>::search(KEY key,BinSearchTree<KEY>** pos) 3 { 4 BinSearchTree* p = this; 5 6 7 while(p){ 8 *pos = p; 9 if(p->key == key){ 10 *pos = p; 11 return 1; 12 } 13 else if(p->key > key ){ 14 p = p->llink; 15 } 16 else{ 17 p = p->rlink; 18 } 19 } 20 21 return 0; 22 } 23 template<class KEY> 24 int BinSearchTree<KEY>::insert(KEY key) 25 { 26 BinSearchTree* pos = NULL; 27 if(search(key,&pos) == 1){ 28 return -1;//查找到相同的key 29 } 30 BinSearchTree* p = new BinSearchTree(key); 31 //如果pos null,说明是空树 32 if(!pos){ 33 pos = p; 34 } 35 else if( pos->key > key ){ 36 pos->llink = p; 37 } 38 else{ 39 pos->rlink = p; 40 } 41 42 return 0; 43 } 44 template<class KEY> 45 int BinSearchTree<KEY>::delete_node(KEY key) 46 { 47 BinSearchTree* p = this; //需要查找的结点 48 BinSearchTree* parent = NULL; //要查找的点的父结点 49 50 while(p){ 51 if( key == p->key ){ 52 break; 53 } 54 parent = p;//在向下个结点遍历前,将本结点设置为父结点 55 56 if( key > p->key ){ 57 p = p->rlink; 58 } 59 else{ 60 p = p->llink; 61 } 62 } 63 if( !p ){ 64 return -1; 65 } 66 67 //1.如果没有左子树,则直接被删除结点用右子树代替 68 if(!p->llink){ 69 if(parent->llink == p){ 70 parent->llink = p->rlink; 71 } 72 else if(parent->rlink == p){ 73 parent->rlink = p->rlink; 74 } 75 delete p; 76 return 0; 77 } 78 //2.如果有有左子树,则找到左子树里最大的结点,将其右子树设置成要查找的子树的右子树。并将欲查找的子树用它的左子树代替 79 BinSearchTree* r = NULL;//r为要查找的结点的左子树的最远端右子树 80 r = p->llink; 81 while(r->rlink)r = r->rlink; 82 83 r->rlink = p->rlink; 84 85 if(parent->llink == p){ 86 parent->llink = p->llink; 87 } 88 else if(parent->rlink == p){ 89 parent->rlink = p->llink; 90 } 91 92 93 }
四。我的新设计
1.使用一个顺序结构存储(比如数组)实际对象 假设叫做list
2.使用一个二叉排序树tree存储list中存储的元素(每个元素是一个对象)的指针或者引用。
3.每次对list添加,删除时,对tree都要做相应的操作
优点:
相当于实现了一个简单的map,可以使用两种方式定位数据对象。比如游戏中存储玩家类,大部分时间是通过id取得玩家对象的,即通过list(索引号)的方式,但同时也可能存在使用名字取得玩家对象的情况,可以把名字存在tree中。tree只是list的一个数据映射,耗费较少的内存。当然,直接使用map<名字,索引号>的方式也是可以的。
还有一个优点是可以比较方便的查找到最大和最小值。
缺点:
不能插入重复的数据。
缺点:
相关文章推荐
- 算法与数据结构题目的 PHP 实现:栈和队列 设计一个有 getMin 功能的栈
- 如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算)
- 如果系统要使用超大整数(超过long长度范围),请你设计一个数据结构来存储这种超大型数字以及设计一种算法来实现超大整数加法运算
- 一个真正符合中国国情的工作流设计参考(包括PHP实现)
- 一个表达式计算案例的设计和实现
- 一个真正符合中国国情的工作流设计参考(包括PHP实现)
- 动态语言和虚拟机实现, 暨介绍一下我设计的一个新型的动态语言(1)
- 一个真正符合中国国情的工作流设计参考(包括PHP实现)
- 设计、实现一个 Asp.Net 应用的通用数据存取层
- 一个真正符合中国国情的工作流设计参考(包括PHP实现)
- 一个真正符合中国国情的工作流设计参考(包括PHP实现)
- 一个真正符合中国国情的工作流设计参考(包括PHP实现)
- state设计模式学习, 一个C++的实现
- [构思]设计&实现一个执行Excel的Import&Export操作的类
- 一个典型的嵌入式系统设计和实现
- 我的本科毕业设计(非水文,设计了一个新算法):一种字符编码猜测工具的实现方法
- 一个表达式计算案例的设计和实现!〈转贴〉
- 一个在线交易市场方案的设计与实现
- 一个真正符合中国国情的工作流设计参考(包括PHP实现)
- 一个真正符合中国国情的工作流设计参考(包括PHP实现)