zoukankan      html  css  js  c++  java
  • 二叉树操作

    二叉树操作

    实验目的

    实现如下二叉树操作,Input:1-n的数组

    (1)通过插入操作建立二叉树

    (2)实现查找、最大/小关键字查询

    (3)从1到n的依次删除

    实验原理

    二叉搜索树上的基本操作所花费的时间与这棵树的高度成正比。二叉搜索树可以使用一个链表数据结构来表示,其中每个结点都是一个对象。每个结点包含属性key,left,right,p,它们分别指向结点的关键字,左孩子,右孩子和双亲。如果某个孩子结点和父亲结点不存在,则相应属性值为NIL。

    二叉搜索树中关键字满足二叉搜索树性质:设x是二叉搜索树中的一个结点,如果y是x左子树中的一个结点,那么y.key <= x.key;如果y是x右子树中的一个结点,那么y.key >= x.key。

    实验过程

    (一)插入法建立二叉树

    要将一个新值v插入到一棵二叉搜索数T中,需要调用过程TREE-INSERT。该过程以结点z作为输入,其中z.key = v, z.left = NIL, z.right = NIL。

    TREE-INSERT(T, z)

    1 y = NIL

    2 x = T.root

    3 while x != NIL

    4     y = x

    5     if z.key < x.key

    6          x = x.left

    7     else x = x.right

    8 z.p = y

    9 if y == NIL

    10       T.root = z

    11 elseif z.key < y.key

    12       y.left = z

    13 else y.right = z

    (二)实现查找、最大/小关键字查询

    查找:输入一个指向树根的指针和一个关键字k,如果这个结点存在,TREE-SEARCH返回一个指向关键字k的节点的指针;否则返回NIL。

    TREE-SEARCH(x, k)

    1 if x == NIL or k == x.key

    2    return x

    3 if k < x.key

    4    return TREE-SEARCH(x.left, k)

    5 else return TREE-SEARCH(x.right, k)

    最大关键字元素和最小关键字元素:通过从树根开始沿着left孩子指针直到遇到一个NIL,返回一个指向在以给定结点x为根的子树中的最小元素的指针;通过从树根开始沿着right孩子指针直到遇到一个NIL,返回一个指向在以给定结点x为根的子树中的最小元素的指针。

    TREE-MINIMUM(x)

    1 while x.left != NIL

    2    x = x.left

    3 return x

    TREE-MAXIMUM(x)

    1 while x.right != NIL

    2    x = x.right

    3 return x

    (三)实现删除

    从一棵二叉搜索树T中删除一个结点z的整个策略分为三种基本情况:

    1)如果z没有孩子结点,那么只是简单地将它删除,并修改它的父结点,孩子结点指向NIL;

    2)如果z只有一个孩子,那么将这个孩子提升到树中z的位置上,用z的孩子来替换z;

    3)如果z有两个孩子,那么先找到z的后继结点y,如果y是z的右孩子,那么用y替换z,并仅留下y的右孩子;如果,y位于z的右子树中但并不是z的右孩子,先用y的右孩子替换y,然后再用y替换z;

    定义一个过程TRANSPLANT,它是用另一棵子树替换一棵子树并成为其双亲的孩子结点:

    TRANSPLANT(T, u, v)

    1 if u.p == NIL

    2    T.root = v

    3 elseif u == u.p.left

    4    u.p.left = v

    5 else u.p.right = v

    6 if v != NIL

    7    v.p = u.p

    TREE-DELETE(T, z)

    1 if z.left == NIL

    2    TRANSPLANT(T, z, z.right)

    3 elseif z.right == NIL

    4    TRANSPLANT(T, z, z.left)

    5 else y = TREE-MINIMUM(z.right)

    6    if y.p != z

    7        TRANSPLANT(T, y, y.right)

    8        y.right = z.right

    9        y.right.p = y

    10   TRANSPLANT(T, z, y)

    11   y.left = z.left

    12   y.left.p = y

    实验总结

    (一)二叉搜索树优点在于,在树上的基本操作与这棵树的高度成正比:对于一棵有n个结点的完全二叉树,在树上操作的最坏运行时间是Θ(lgn)。然而,如果树是一条n个结点组成的线性链,那么同样的操作就要花费Θ(n)的最坏运行时间。

    (二)针对在构建树的过程中,出现最坏情况导致线性链的发生,可采取几种处理方式:可通过随机构建二叉搜索树;还可以设计二叉树的变体,即红黑树,红黑树的树高为O(lgn);还可以使用B树。

    (三)二叉搜索树是学习树的基础,为了充分利用二叉搜索树的优点,避免二叉树的最坏情况,从而研究出来了红黑树和B树。

    附录(代码)

      1 #include <stdio.h>
      2 
      3 #include <stdlib.h>
      4 
      5  
      6 
      7 typedef struct node *tree_pointer;
      8 
      9 typedef struct node{
     10 
     11     int key;
     12 
     13     tree_pointerp;
     14 
     15     tree_pointerleft;
     16 
     17     tree_pointerright;
     18 
     19 } *tree_pointer;
     20 
     21  
     22 
     23 void tree_insert(tree_pointer z);
     24 
     25 void print_tree(tree_pointer T_root, int n);
     26 
     27 void transplant(tree_pointer T_root, tree_pointer u,tree_pointer v);
     28 
     29 void tree_delete(tree_pointer T_root, tree_pointer z);
     30 
     31 struct node * creat_node(int key);
     32 
     33 struct node * tree_search(tree_pointer T_root, intkey);
     34 
     35 struct node * tree_minimum(tree_pointer T_root);
     36 
     37 struct node * tree_maximum(tree_pointer T_root);
     38 
     39 int get_tree_height(tree_pointer T_root);
     40 
     41  
     42 
     43 tree_pointer T_Root = NULL;
     44 
     45  
     46 
     47 int main(){
     48 
     49    
     50 
     51     inti,key,node_number,tree_height,search_key,delete_key;
     52 
     53    
     54 
     55     tree_pointernew=NULL;
     56 
     57     tree_pointersearch_result;
     58 
     59     tree_pointerminimum;
     60 
     61     tree_pointermaximum;
     62 
     63     tree_pointerdelete;
     64 
     65  
     66 
     67     printf("pleaseinput the number of nodes:");
     68 
     69     scanf("%d",&node_number);
     70 
     71     for(i = 0; i< node_number; i++ ){
     72 
     73        printf("inputthe key:");
     74 
     75        scanf("%d",&key);
     76 
     77        new =creat_node(key);
     78 
     79        tree_insert(new);
     80 
     81        tree_height= get_tree_height(T_Root);
     82 
     83        print_tree(T_Root,tree_height);
     84 
     85     }
     86 
     87     printf("thefinal tree:
    ");
     88 
     89     tree_height =get_tree_height(T_Root);
     90 
     91     print_tree(T_Root,tree_height);
     92 
     93    
     94 
     95     printf("
    ");
     96 
     97     minimum =tree_minimum(T_Root);
     98 
     99     maximum =tree_maximum(T_Root);
    100 
    101     printf("Inthis tree, the minimum number is:");
    102 
    103     printf("%d
    ",minimum->key);
    104 
    105     printf("Inthis tree, the maximum number is:");
    106 
    107     printf("%d
    ",maximum->key);
    108 
    109  
    110 
    111     printf("
    ");
    112 
    113     printf("whichkey do you want to search?
    please input it:");
    114 
    115     scanf("%d",&search_key);
    116 
    117     printf("thesearching result: ");
    118 
    119     search_result= tree_search(T_Root, search_key);
    120 
    121     printf("(%p)and this (%p) refers to %d
    ",search_result,search_result,search_result->key);
    122 
    123    
    124 
    125     printf("
    ");
    126 
    127     printf("pleaseinput the node that you want to delete:");
    128 
    129     scanf("%d",&delete_key);
    130 
    131     printf("delete_key= %d
    ",delete_key);
    132 
    133     delete =tree_search(T_Root, delete_key);
    134 
    135     printf("wewill delete:(%p) and it refers to %d
    ", delete,delete->key);
    136 
    137     printf("deletethe node and print the tree:
    ");
    138 
    139     tree_delete(T_Root,delete);
    140 
    141     tree_height =get_tree_height(T_Root);
    142 
    143     print_tree(T_Root,tree_height);
    144 
    145     return 0;
    146 
    147 }
    148 
    149  
    150 
    151 void tree_insert(tree_pointer z){
    152 
    153     tree_pointerx;
    154 
    155     tree_pointery = NULL;
    156 
    157     x = T_Root;
    158 
    159    
    160 
    161     while(x !=NULL){
    162 
    163        y = x;
    164 
    165        if(z->key< x->key)
    166 
    167            x =x->left;
    168 
    169        else
    170 
    171            x =x->right;
    172 
    173     }
    174 
    175     z->p = y;
    176 
    177     if(y == NULL)
    178 
    179        T_Root   = z;
    180 
    181     elseif(z->key < y->key)
    182 
    183        y->left  = z;
    184 
    185     else
    186 
    187        y->right= z;
    188 
    189    
    190 
    191 }
    192 
    193  
    194 
    195 void print_tree(tree_pointer T_root, int n){
    196 
    197     int i;
    198 
    199     if(T_root ==NULL)
    200 
    201        return;
    202 
    203     print_tree(T_root->right,n-1);
    204 
    205  
    206 
    207     for(i = 0; i< n-1; i++)
    208 
    209        printf("   ");
    210 
    211     if(n > 0){
    212 
    213        printf("---");
    214 
    215        printf("%d
    ",T_root->key);
    216 
    217     }
    218 
    219    
    220 
    221     print_tree(T_root->left,n-1);
    222 
    223 }
    224 
    225  
    226 
    227 struct node * creat_node(int key){
    228 
    229     tree_pointernew;
    230 
    231     new = (structnode *)malloc(sizeof(struct node));
    232 
    233     new->key   = key;
    234 
    235     return new;
    236 
    237 }
    238 
    239  
    240 
    241 int get_tree_height(tree_pointer T_root){
    242 
    243     if(!T_root)
    244 
    245        return 0;
    246 
    247     intleft_height,right_height;
    248 
    249     left_height  = get_tree_height(T_root->left);
    250 
    251     right_height= get_tree_height(T_root->right);
    252 
    253     return(left_height < right_height)?(right_height+1):(left_height+1);
    254 
    255 }
    256 
    257  
    258 
    259 struct node * tree_search(tree_pointer T_root, intkey){
    260 
    261     while((T_root!= NULL) && (key != T_root->key)){
    262 
    263        if(key< T_root->key)
    264 
    265            T_root= T_root->left;
    266 
    267        else
    268 
    269            T_root= T_root->right;
    270 
    271     }
    272 
    273     returnT_root;
    274 
    275 }
    276 
    277  
    278 
    279 struct node * tree_minimum(tree_pointer T_root){
    280 
    281     while(T_root->left!= NULL)
    282 
    283        T_root =T_root->left;
    284 
    285     returnT_root;
    286 
    287 }
    288 
    289  
    290 
    291 struct node * tree_maximum(tree_pointer T_root){
    292 
    293     while(T_root->right!= NULL)
    294 
    295        T_root =T_root->right;
    296 
    297     returnT_root;
    298 
    299 }
    300 
    301  
    302 
    303 void transplant(tree_pointer T_root, tree_pointer u,tree_pointer v){
    304 
    305     if(u->p ==NULL)
    306 
    307        T_root =v;
    308 
    309     else if(u ==u->p->left)
    310 
    311        u->p->left  = v;
    312 
    313     else
    314 
    315        u->p->right= v;
    316 
    317     if(v != NULL)
    318 
    319        v->p =u->p;
    320 
    321 }
    322 
    323  
    324 
    325 void tree_delete(tree_pointer T_root, tree_pointer z){
    326 
    327     tree_pointery=NULL;
    328 
    329  
    330 
    331     if(z->left== NULL)
    332 
    333        transplant(T_root,z , z->right);
    334 
    335     elseif(z->right == NULL)
    336 
    337        transplant(T_root,z , z->left);
    338 
    339     else{
    340 
    341        y =tree_minimum(z->right);
    342 
    343        if(y->p!= z){
    344 
    345            transplant(T_root,y , y->right);
    346 
    347            y->right    = z->right;
    348 
    349            y->right->p= y;
    350 
    351        }
    352 
    353         transplant(T_root, z , y);
    354 
    355        y->left    = z->left;
    356 
    357        y->left->p= y;
    358 
    359     }
    360 
    361 }
    View Code
    说明:所有内容仅做学习记录
  • 相关阅读:
    实现毛玻璃效果
    iOS-调用系统的短信和发送邮件功能,实现短信分享和邮件分享
    集成环信
    HTTP 方法:GET 对比 POST
    虚拟DOM
    javascript的回调函数 同步 异步
    jQuery中的Deferred和promise
    web性能
    JSONP
    java
  • 原文地址:https://www.cnblogs.com/jayinnn/p/9559359.html
Copyright © 2011-2022 走看看