您的位置:首页 > 理论基础 > 数据结构算法

排序二叉树的实现和我的一个数据结构设计

2016-12-31 09:52 176 查看
一。基本概念
二叉排序树又称二叉搜索树,即在树的任何一个结点,都满足左子树小于根,根小于右子树。排序二叉树可以作为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<名字,索引号>的方式也是可以的。

还有一个优点是可以比较方便的查找到最大和最小值。

缺点:

不能插入重复的数据。

缺点:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐