二叉查找树 - C语言实现(摘自数据结构与算法分析 C语言描述)

来源:互联网 发布:淘宝美图软件 编辑:程序博客网 时间:2024/05/01 07:17

一、概述

        二叉树的一个重要的应用是它们在查找中的使用。使二叉树成为查找树的性质是,对于树中的每个结点X,它的左子树中所有关键字值小于X的关键值,而它的右子树中所有关键字大于X的关键值。在图1中,左边的树是二叉查找树,但右边的树则不是(想一想为什么)。



图1 两棵二叉树(只有左边的树是查找树)

二、实现

        因为二叉树最多有两个儿子,所以我们可以用指针直接指向它们。树节点的声明在结构上类似于双链表的声明,在声明中,一个节点就是由Key(关键字)信息加上两个指向其他节点的指针(Left和Right)组成的结构。
文件名:tree.h
[cpp] view plaincopyprint?
  1. #ifndef _Tree_H  
  2.   
  3. typedef int ElementType;  
  4.   
  5. struct TreeNode;  
  6. typedef struct TreeNode *Position;  
  7. typedef struct TreeNode *SearchTree;  
  8.   
  9. SearchTree MakeEmpty( SearchTree T );  
  10. Position Find( ElementType X, SearchTree T );  
  11. Position FindMin( SearchTree T );  
  12. Position FindMax( SearchTree T );  
  13. SearchTree Insert( ElementType X, SearchTree T );  
  14. SearchTree Delete( ElementType X, SearchTree T );  
  15. ElementType Retrieve( Position P );  
  16.   
  17. void PrintElement( SearchTree T );  
  18. void PreOrder( SearchTree T );  
  19. void InOrder( SearchTree T );  
  20. void PostOrder( SearchTree T );  
  21.   
  22. #endif /* Tree_H */  

文件名:tree.c
[cpp] view plaincopyprint?
  1. #include "fatal.h"  
  2. #include "tree.h"  
  3.   
  4. struct TreeNode  
  5. {  
  6.     ElementType Element;  
  7.     SearchTree Left;  
  8.     SearchTree Right;  
  9. };  
  10.   
  11. SearchTree   
  12. MakeEmpty( SearchTree T )  
  13. {  
  14.     if ( T != NULL )  
  15.     {  
  16.         MakeEmpty( T->Left );  
  17.         MakeEmpty( T->Right );  
  18.         free( T );  
  19.     }  
  20.     return NULL;  
  21. }  
  22.   
  23. Position  
  24. Find( ElementType X, SearchTree T )  
  25. {  
  26.     if ( T == NULL )  
  27.         return NULL;  
  28.     if ( X < T->Element )  
  29.         return Find( X, T->Left );  
  30.     else  
  31.     if ( X > T->Element )  
  32.         return Find( X, T->Right );  
  33.     else   
  34.         return T;  
  35. }  
  36.   
  37. /* 对二叉查找树的FindMin的递归实现 */  
  38. Position  
  39. FindMin( SearchTree T )  
  40. {  
  41.     if ( T == NULL )  
  42.         return NULL;  
  43.     else  
  44.     if ( T->Left  == NULL )  
  45.         return T;  
  46.     else  
  47.         return FindMin( T->Left );  
  48. }  
  49.   
  50. /* 对二叉查找树的FindMax的非递归实现 */  
  51. Position  
  52. FindMax( SearchTree T )  
  53. {  
  54.     if ( T != NULL )  
  55.         while( T->Right != NULL )  
  56.             T = T->Right;  
  57.   
  58.     return T;  
  59. }  
  60.   
  61. SearchTree  
  62. Insert( ElementType X, SearchTree T )  
  63. {  
  64.     if ( T == NULL )  
  65.     {  
  66.         /* Create and return a one-node tree */  
  67.         T = malloc( sizeofstruct TreeNode ) );  
  68.         if ( T== NULL )  
  69.             FatalError( "Out of space!!!" );  
  70.         else  
  71.         {  
  72.             T->Element = X;  
  73.             T->Left = T->Right = NULL;  
  74.         }  
  75.     }  
  76.     else  
  77.     if ( X < T->Element )  
  78.         T->Left = Insert( X, T->Left );  
  79.     else  
  80.     if ( X > T->Element )  
  81.         T->Right = Insert( X, T->Right );  
  82.     /* Else X is in the tree already;we'll do nothing */  
  83.   
  84.     return T; /* Do not forget this line!!! */  
  85. }  
  86.   
  87. SearchTree  
  88. Delete( ElementType X, SearchTree T )  
  89. {  
  90.     Position TmpCell;  
  91.   
  92.     if ( T == NULL)  
  93.         Error( "Element not found" );  
  94.     else  
  95.     if ( X < T->Element ) /* Go left */  
  96.         T->Left = Delete( X, T->Left );  
  97.     else  
  98.     if ( X > T->Element ) /* Go Right */  
  99.         T->Right = Delete( X, T->Left );  
  100.     else /* Found element to be deleted */  
  101.     if ( T->Left && T->Right ) /*Two children */  
  102.     {  
  103.         /* Replace with smallest in right subtree */  
  104.         TmpCell = FindMin( T->Right );  
  105.         T->Element = TmpCell->Element;  
  106.         T->Right = Delete( T->Element, T->Right );  
  107.     }  
  108.     else /* One or zero children */  
  109.     {  
  110.         TmpCell = T;  
  111.         if ( T->Left == NULL) /* Also handles 0 children */  
  112.             T = T->Right;  
  113.         else if ( T->Right == NULL )  
  114.             T = T->Left;  
  115.         free( TmpCell );  
  116.     }  
  117.   
  118.     return T;  
  119. }  
  120.   
  121. ElementType   
  122. Retrieve( Position P )  
  123. {  
  124.     return P->Element;  
  125. }  
  126.   
  127. void   
  128. PrintElement( SearchTree T )  
  129. {  
  130.     printf( "%3d ", Retrieve( T ) );  
  131. }  
  132.   
  133. void   
  134. PreOrder( SearchTree T )  
  135. {  
  136.     if (T != NULL )  
  137.     {  
  138.         PrintElement( T );  
  139.         PreOrder( T->Left );  
  140.         PreOrder( T->Right );  
  141.     }     
  142. }  
  143.   
  144. void   
  145. InOrder( SearchTree T )  
  146. {  
  147.     if (T != NULL )  
  148.     {  
  149.         InOrder( T->Left );  
  150.         PrintElement( T );  
  151.         InOrder( T->Right );  
  152.     }  
  153.       
  154. }  
  155.   
  156. void   
  157. PostOrder( SearchTree T )  
  158. {  
  159.     if ( T != NULL )  
  160.     {  
  161.         PostOrder( T->Left );  
  162.         PostOrder( T->Right );  
  163.         PrintElement( T );  
  164.     }  
  165. }  

文件名:main.c
[cpp] view plaincopyprint?
  1. #include "tree.h"  
  2. #include <stdio.h>  
  3.   
  4. int main()  
  5. {  
  6.     SearchTree T = NULL;  
  7.     int i, j, m, n;  
  8.     ElementType tmp;  
  9.     printf( "Number of Elements:" );  
  10.     scanf( "%d", &n );  
  11.     for ( i = 0; i < n; i++)  
  12.     {  
  13.         scanf( "%d", &tmp );  
  14.         T = Insert( tmp, T );  
  15.     }  
  16.         printf( "\nPreOrder :" );  
  17.         PreOrder( T );  
  18.     printf( "\nInOrder  :" );  
  19.     InOrder( T );  
  20.     printf( "\nPostOrder:" );  
  21.     PostOrder( T );  
  22.         printf( "\n" );  
  23.     return 0;  
  24. }  

附录:上述代码中用到了Error、FatalError等函数,其实现如下(即fatal.h文件):
[cpp] view plaincopyprint?
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. #define Error( Str )        FatalError( Str )  
  5. #define FatalError( Str )   fprintf( stderr, "%s\n", Str ), exit( 1 )
0 0