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

一、概述

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


二叉查找树 - C语言实现(摘自数据结构与算法分析 C语言描述)_第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

你可能感兴趣的:(数据结构,c,算法,null,insert,语言)