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

一、概述

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



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

二、实现

因为二叉树最多有两个儿子,所以我们可以用指针直接指向它们。树节点的声明在结构上类似于双链表的声明,在声明中,一个节点就是由Key(关键字)信息加上两个指向其他节点的指针(Left和Right)组成的结构。
文件名:tree.h
#ifndef _Tree_H typedef int ElementType; struct TreeNode; typedef struct TreeNode *Position; typedef struct TreeNode *SearchTree; SearchTree MakeEmpty( SearchTree T ); Position Find( ElementType X, SearchTree T ); Position FindMin( SearchTree T ); Position FindMax( SearchTree T ); SearchTree Insert( ElementType X, SearchTree T ); SearchTree Delete( ElementType X, SearchTree T ); ElementType Retrieve( Position P ); void PrintElement( SearchTree T ); void PreOrder( SearchTree T ); void InOrder( SearchTree T ); void PostOrder( SearchTree T ); #endif /* Tree_H */
文件名:tree.c
#include "fatal.h" #include "tree.h" struct TreeNode { ElementType Element; SearchTree Left; SearchTree Right; }; SearchTree MakeEmpty( SearchTree T ) { if ( T != NULL ) { MakeEmpty( T->Left ); MakeEmpty( T->Right ); free( T ); } return NULL; } Position Find( ElementType X, SearchTree T ) { if ( T == NULL ) return NULL; if ( X < T->Element ) return Find( X, T->Left ); else if ( X > T->Element ) return Find( X, T->Right ); else return T; } /* 对二叉查找树的FindMin的递归实现 */ Position FindMin( SearchTree T ) { if ( T == NULL ) return NULL; else if ( T->Left == NULL ) return T; else return FindMin( T->Left ); } /* 对二叉查找树的FindMax的非递归实现 */ Position FindMax( SearchTree T ) { if ( T != NULL ) while( T->Right != NULL ) T = T->Right; return T; } SearchTree Insert( ElementType X, SearchTree T ) { if ( T == NULL ) { /* Create and return a one-node tree */ T = malloc( sizeof( struct TreeNode ) ); if ( T== NULL ) FatalError( "Out of space!!!" ); else { T->Element = X; T->Left = T->Right = NULL; } } else if ( X < T->Element ) T->Left = Insert( X, T->Left ); else if ( X > T->Element ) T->Right = Insert( X, T->Right ); /* Else X is in the tree already;we'll do nothing */ return T; /* Do not forget this line!!! */ } SearchTree Delete( ElementType X, SearchTree T ) { Position TmpCell; if ( T == NULL) Error( "Element not found" ); else if ( X < T->Element ) /* Go left */ T->Left = Delete( X, T->Left ); else if ( X > T->Element ) /* Go Right */ T->Right = Delete( X, T->Left ); else /* Found element to be deleted */ if ( T->Left && T->Right ) /*Two children */ { /* Replace with smallest in right subtree */ TmpCell = FindMin( T->Right ); T->Element = TmpCell->Element; T->Right = Delete( T->Element, T->Right ); } else /* One or zero children */ { TmpCell = T; if ( T->Left == NULL) /* Also handles 0 children */ T = T->Right; else if ( T->Right == NULL ) T = T->Left; free( TmpCell ); } return T; } ElementType Retrieve( Position P ) { return P->Element; } void PrintElement( SearchTree T ) { printf( "%3d ", Retrieve( T ) ); } void PreOrder( SearchTree T ) { if (T != NULL ) { PrintElement( T ); PreOrder( T->Left ); PreOrder( T->Right ); } } void InOrder( SearchTree T ) { if (T != NULL ) { InOrder( T->Left ); PrintElement( T ); InOrder( T->Right ); } } void PostOrder( SearchTree T ) { if ( T != NULL ) { PostOrder( T->Left ); PostOrder( T->Right ); PrintElement( T ); } }
文件名:main.c
#include "tree.h" #include <stdio.h> int main() { SearchTree T = NULL; int i, j, m, n; ElementType tmp; printf( "Number of Elements:" ); scanf( "%d", &n ); for ( i = 0; i < n; i++) { scanf( "%d", &tmp ); T = Insert( tmp, T ); } printf( "\nPreOrder :" ); PreOrder( T ); printf( "\nInOrder :" ); InOrder( T ); printf( "\nPostOrder:" ); PostOrder( T ); printf( "\n" ); return 0; }
附录:上述代码中用到了Error、FatalError等函数,其实现如下(即fatal.h文件):
#include <stdio.h> #include <stdlib.h> #define Error( Str ) FatalError( Str ) #define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
备注:本文摘自《数据结构与算法分析 C语言描述 Mark Allen Weiss著》,代码经gcc编译测试通过。

附件下载:http://download.csdn.net/detail/shuxiao9058/4212427#tree_20120401.tar.gz

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值