您的位置:首页 > 理论基础 > 数据结构算法

【数据结构与算法基础】二叉查找树 / Binary Search Tree

2011-04-14 21:04 891 查看
所有原创文章转载请注明作者及链接
// blackboycpp(AT)gmail.com
// QQ群: 135202158








/********************************************************************
	File: 		BinarySearchTree.h	
	Author:		blackboy  blackboycpp@gmail.com
	Purpose:	二叉查找树, C实现,不支持重复元素。
                使用递归的好例子。
	Created:	2011-04-11
	Modified:	2011-04-11   19:15
*********************************************************************/

#ifndef  __BINARY_SEARCH_TREE_H__
#define  __BINARY_SEARCH_TREE_H__

typedef int ElementType;
struct _TreeNode;
typedef struct _TreeNode TreeNode;
typedef TreeNode*  Position;
typedef TreeNode*  SearchTree;

struct _TreeNode
{
    ElementType  Val;
    SearchTree   Left;
    SearchTree   Right;
};

//////////////////////////////////////////////////////////////////////////

SearchTree  MakeEmpty(SearchTree);
Position    Find(ElementType, SearchTree);
Position    FindMin(SearchTree);
Position    FindMax(SearchTree);
SearchTree  Insert(ElementType, SearchTree);
SearchTree  Delete(ElementType, SearchTree);
ElementType GetAt(Position);
void        InOrder(SearchTree);    // 中序遍历

#endif








#include <stdlib.h>
#include <stdio.h>
#include "BinarySearchTree.h"

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->Val)
        return Find(X, T->Left);
    else if(X > T->Val)
        return Find(X, T->Right);
    else   // 递归终止条件
        return T;
}

Position    FindMin(SearchTree T)
{
    if(T == NULL)
        return NULL;
    else if(T->Left == NULL)
        return T;
    else
        return FindMin(T->Left);
}

Position    FindMax(SearchTree T)
{
    if(T == NULL)
        return NULL;
    else if(T->Right == NULL)
        return T;
    else
        return FindMax(T->Right);
    // 非递归实现
    /*
    if(T != NULL)
    {
        while(T->Right != NULL)
        {
            T = T->Right;
        }
    }
    return T;
    */
}

SearchTree  Insert(ElementType X, SearchTree T)
{
    if(T == NULL)   // 递归终止条件
    {
        T = (SearchTree)malloc(sizeof(TreeNode));
        T->Left = T->Right = NULL;
        T->Val = X;
    }
    else if(X < T->Val)
    {
        T->Left = Insert(X, T->Left);
    }
    else if(X > T->Val)
    {
        T->Right = Insert(X, T->Right);
    }
    // else: 重复元素,不考虑。
    return T;
}

// 搜索并删除右子树中最小的节点。
// D: 要删除的节点;T:递归用的树,初始值为D的右子树。
// 注意:此函数被调用时,D必有左、右两个儿子。
static SearchTree  DeleteRightMin(SearchTree D, SearchTree T)
{   
    Position Temp;
    // 最小节点必定没有左儿子
    if(T->Left == NULL)
    {
        Temp = T;
        D->Val = T->Val;
        T = T->Right;
        free(Temp);
    }
    else
        T->Left = DeleteRightMin(D, T->Left);   // 很关键,且容易出错
    return T;
}

SearchTree  Delete(ElementType X, SearchTree T)
{
    Position Temp;
    if(T == NULL)   // 空树
        return NULL;
    else if(X < T->Val)
        T->Left = Delete(X, T->Left);
    else if(X > T->Val)
        T->Right = Delete(X, T->Right);
    else if(T->Left && T->Right)   // 两个儿子
    {
        T->Right = DeleteRightMin(T, T->Right);
        // 也可以如下实现,但效率较低,因为遍历了两遍右子树
        /*
        Temp = FindMin(T->Right);
        T->Val = Temp->Val;
        T->Right = Delete(T->Val, T->Right);
        */
    }
    else    // 单个儿子
    {
        Temp = T;
        if(T->Left == NULL)
            T = T->Right;
        else if(T->Right == NULL)
            T = T->Left;
        free(Temp);
    }
    return T;
}

ElementType GetAt(Position Pos)
{
    return Pos->Val;
}

// 中序遍历,输出节点值
void InOrder(SearchTree T)
{
    if(T == NULL)   return;
    InOrder(T->Left);
    printf("%d ", T->Val);
    InOrder(T->Right);
}








#include <stdlib.h>
#include <stdio.h>
#include "BinarySearchTree.h"

int main()
{
    SearchTree  Tree = NULL;
    Position Pos = NULL;
    
    Tree = Insert(5, Tree);
    Tree = Insert(2, Tree);
    Tree = Insert(8, Tree);
    Tree = Insert(1, Tree);
    Tree = Insert(3, Tree);
    Tree = Insert(6, Tree);
    Tree = Insert(4, Tree);

    InOrder(Tree);
    printf("/n");

    Pos = Find(3, Tree);
    printf("Find 3: %d/n", GetAt(Pos));
    Pos = FindMax(Tree);
    printf("FindMax: %d/n", GetAt(Pos));
    Pos = FindMin(Tree);
    printf("FindMin: %d/n", GetAt(Pos));

    // 删除单儿子节点
    Tree = Delete(3, Tree);
    InOrder(Tree);
    printf("/n");

    Tree = Insert(3, Tree);
    // 删除双儿子节点
    Tree = Delete(2, Tree);
    InOrder(Tree);
    printf("/n");

    // 删除根节点
    Tree = Delete(5, Tree);
    InOrder(Tree);
    printf("/n");

    Tree = MakeEmpty(Tree);
    InOrder(Tree);
    printf("/n");

	Tree = MakeEmpty(Tree);

    system("PAUSE");
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: