zoukankan      html  css  js  c++  java
  • 排序二叉树的实现和我的一个数据结构设计

    一。基本概念

    二叉排序树又称二叉搜索树,即在树的任何一个结点,都满足左子树小于根,根小于右子树。排序二叉树可以作为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<名字,索引号>的方式也是可以的。

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

    缺点:

    不能插入重复的数据。

    缺点:

  • 相关阅读:
    Good Bye 2014 B. New Year Permutation(floyd )
    hdu 5147 Sequence II (树状数组 求逆序数)
    POJ 1696 Space Ant (极角排序)
    POJ 2398 Toy Storage (叉积判断点和线段的关系)
    hdu 2897 邂逅明下 (简单巴什博弈)
    poj 1410 Intersection (判断线段与矩形相交 判线段相交)
    HDU 3400 Line belt (三分嵌套)
    Codeforces Round #279 (Div. 2) C. Hacking Cypher (大数取余)
    Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings (容斥原理)
    hdu 1576 A/B (求逆元)
  • 原文地址:https://www.cnblogs.com/fox7nights/p/2319665.html
Copyright © 2011-2022 走看看