学着写了一个二叉搜索数,大部分是按照书本上的思路写的,有抄袭嫌疑,不过所有代码都是我手打的,且在写的过程中是不看书的,调试过程中对照了一下书。这个树只能存储不同的元素值,即元素的值不能相同,由于树的自相似性,在写的过程中用到了大量的递归,一直觉得递归很难理解,能写递归的都是大神,今天在资料的帮助下也写了一点递归,感觉对递归的理解上升了一点,还是那句话,书读百页不如手打一行。
BinarySearchTree.h
/************************************
*二叉查找树
*作者:JK
*日期:2014-08-11
*************************************/
#ifndef _BINARY_SEARCH_TREE_HEADER_H_
#define _BINARY_SEARCH_TREE_HEADER_H_
struct TreeNode;
typedef struct TreeNode* Position;
typedef struct TreeNode* SearchTree;
typedef int ElemType;
struct TreeNode
{
ElemType elem; // 元素
SearchTree left; // 左子树
SearchTree right; // 右子树
};
SearchTree InitTree(SearchTree T);
SearchTree MakeEmpty(SearchTree T);
Position Find(ElemType E, SearchTree T);
Position FindMin(SearchTree T);
Position FindMax(SearchTree T);
SearchTree Insert(ElemType E, SearchTree T);
SearchTree Delete(ElemType E, SearchTree T);
ElemType Retrieve(Position P);
#endif
BinarySearchTree.c
#include <assert.h>
#include <stddef.h>
#include "BinarySearchTree.h"
/***************************************
*功能:初始化,将指向根的指针设置位NULL
*参数:T:待初始化的树
*返回值:初始后后的树
****************************************/
SearchTree InitTree(SearchTree T)
{
T = NULL;
return T;
}
/********************************
*功能:采用递归方法清空一个二叉查找树
*参数:T:待清空的树
*返回值:返回NULL
*********************************/
SearchTree MakeEmpty(SearchTree T)
{
if (T != NULL)
{
MakeEmpty(T->left);
MakeEmpty(T->right);
free(T);
}
return NULL;
}
/********************************
*功能:在树中查找元素大小与E相等的元素位置
*参数:E:待查参数,T:待查的树
*返回值:成功返回位置,失败返回NULL
*********************************/
Position Find(ElemType E, SearchTree T)
{
if (T == NULL)
{
return NULL;
}
if (E < T->elem)
{
return Find(E, T->left);
}
else if (E > T->elem)
{
return Find(E, T->right);
}
return T;
}
/********************************
*功能:查找树中的最大值
*参数:T:待查的树
*返回值:成功返回位置,失败返回NULL
*********************************/
Position FindMax(SearchTree T)
{
if (T != NULL)
{
while (T->right != NULL)
{
T = T->right;
}
return T;
}
return NULL;
}
/********************************
*功能:查找树中的最大值(递归实现)
*参数:T:待查的树
*返回值:成功返回位置,失败返回NULL
*********************************/
/*
Position FindMax(SearchTree T)
{
if (T == NULL)
{
return NULL;
}
else if (T->right == NULL)
{
return T;
}
else
{
return FindMax(T->right);
}
}
*/
/********************************
*功能:查找树中的最小值
*参数:T:待查的树
*返回值:成功返回位置,失败返回NULL
*********************************/
Position FindMin(SearchTree T)
{
if (T != NULL)
{
while(T->left != NULL)
{
T = T->left;
}
return T;
}
return NULL;
}
/********************************
*功能:查找树中的最小值(递归实现)
*参数:T:待查的树
*返回值:成功返回位置,失败返回NULL
*********************************/
/*
Position FindMin(SearchTree T)
{
if (T == NULL)
{
return NULL;
}
else if (T->left == NULL);
{
return T;
}
else
{
return FindMin(T->left);
}
}
*/
/********************************
*功能:插入元素(递归实现),元素都插在了叶上
*参数:E:待插入的元素值;T:待插入的树
*返回值:返回该树
*********************************/
SearchTree Insert(ElemType E, SearchTree T)
{
if (T == NULL)
{
T = malloc(sizeof(struct TreeNode));
assert(T != NULL);
T->elem = E;
T->right = NULL;
T->left = NULL;
}
else if (E < T->elem)
{
T->left = Insert(E, T->left);
}
else if (E > T->elem)
{
T->right = Insert(E, T->right);
}
return T;
}
/********************************
*功能:删除元素(递归实现)
*参数:E:待删除的元素值;T:待删除值的树
*返回值:返回该树
*********************************/
SearchTree Delete(ElemType E, SearchTree T)
{
Position tmpPos;
if (T == NULL)
{
printf("element not found\n");
}
else if (E < T->elem)
{
T->left = Delete(E, T->left);// 到左边删
}
else if (E > T->elem)
{
T->right = Delete(E, T->right);// 到右边删
}
else if (T->left && T->right)// 找到该元素且有两个儿子
{
tmpPos = FindMin(T->right);// 找到该元素右子树的最小值
T->elem = tmpPos->elem;// 将需要删除的值替换位右子树中的最小值
T->right = Delete(T->elem, T->right);// 删除右子树中的最小值
}
else// 找到该元素且只有一个或没有儿子
{
tmpPos = T;
if (T->left == NULL)
{
T = T->right;
}
else if (T->right == NULL)
{
T = T->right;
}
free(tmpPos);
}
return T;
}
/***********************************************
*功能:获取节点上的元素值
*参数:P:指向节点的指针
*返回值:元素值,为了防止警告,P是NULL时返回零
***********************************************/
ElemType Retrieve(Position P)
{
if (P != NULL)
{
return P->elem;
}
printf("retrieve failed, NULL pointer\n");
return 0;
}
测试主函数main.c
#include <stdio.h>
#include <stdlib.h>
#include "BinaryTree.h"
int main()
{
printf("Hello world JK!\n");
SearchTree myTree = InitTree(myTree);
myTree = Insert(50, myTree);// 根
// 随机插入50个0~99之间元素
int i = 0;
for (i = 0; i < 50; ++i)
{
myTree = Insert(rand()%100, myTree);
}
// 插入40
myTree = Insert(40, myTree);
// 查找40
Position p = Find(40, myTree);
int elemValue = Retrieve(p);
printf("find 40:%d\n", elemValue);
// 寻找最大值
p = FindMax(myTree);
elemValue = Retrieve(p);
printf("Max element:%d\n", elemValue);
// 寻找最小值
p = FindMin(myTree);
elemValue = Retrieve(p);
printf("Min element:%d\n", elemValue);
// 删除元素
myTree = Delete(30, myTree);
// 清空
myTree = MakeEmpty(myTree);
return 0;
}
测试结果: