/**************************************************************
* Dynamic Search Table
* --Binary Sort Tree
*
* Author: Yannis Zhao
* Date: 2014-8-18
*
**************************************************************/
#include <stdio.h>
#include <malloc.h>
typedef struct
{
char stu_num[9];
char stu_name[21];
unsigned short stu_age;
}Student;
typedef Student DataType;
typedef unsigned long KeyType;
typedef struct
{
KeyType key;
DataType data;
}ElemType;
typedef struct BSTNode
{
ElemType e;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
#define EQ(a,b) (a==b)
#define LQ(a,b) (a<=b)
#define LT(a,b) (a<b)
#define TRUE 1
#define FALSE 0
void InitBSTree(BSTree tree)
{
tree=NULL;
}
void DestroyBSTree(BSTree* tree)
{
if(tree)/* Not empty */
{
if((*tree)->lchild)//Left child not null
DestroyBSTree(&(*tree)->lchild);
if((*tree)->rchild)//Right child not null
DestroyBSTree(&(*tree)->rchild);
free(*tree);/* Free memory */
*tree=NULL;/* Set null pointer */
}
}
/* InOrderTraverse: Get a sorted series of BST */
void InOrderTraverseBSTree(BSTree tree,void(*Visit)(ElemType*))/* Start node seen as the root node */
{
if(tree)
{
InOrderTraverseBSTree(tree->lchild,Visit);/* Left child */
Visit(&tree->e);/* Root */
InOrderTraverseBSTree(tree->rchild,Visit);/* Right child */
}
}
BSTNode* SearchBSTNode(BSTNode* node_ptr,KeyType key)
{
if(!node_ptr || EQ(key,node_ptr->e.key))
return node_ptr;
else if(LT(key,node_ptr->e.key))
return SearchBSTNode(node_ptr->lchild,key);
else
return SearchBSTNode(node_ptr->rchild,key);
}
int SearchBSTree(BSTree tree,KeyType key,BSTNode* parent,BSTree *p) /* 算法9.5(b) */
{
if(!tree)/* Empty tree */
{
*p=parent;/* Point to parent, at first time the whole tree is empty, the parent node doesn't exist,
so p point to NULL, and then the parent point to root of each subtree */
return FALSE;
}
else if(EQ(key,tree->e.key))/* Succ */
{
*p=tree;/* p point to the found element */
return TRUE;
}
else if(LT(key,tree->e.key))/* Less than, search in the left subtree */
{
return SearchBSTree(tree->lchild,key,tree,p);
}
else/* More than, search in the left subtree */
return SearchBSTree(tree->rchild,key,tree,p);
}
int InsertBSTree(BSTree* tree, ElemType *e)
{
BSTree p=NULL;/* Record last accessed node */
BSTNode *node=NULL;
if(!SearchBSTree(*tree,e->key,NULL,&p))/* Not found */
{
/* Create a new node and then insert into the BST */
node=(BSTNode*)malloc(sizeof(BSTNode));
node->e=*e;
node->lchild=NULL;
node->rchild=NULL;
if(!p)/* Empty tree */
*tree=node;
else if(LT(e->key,p->e.key))/* Less than */
p->lchild=node;
else/* More than */
p->rchild=node;
return TRUE;
}
else/* Element has already exist, won't be inserted. */
return FALSE;
}
void Delete(BSTree *p)/* 算法来自 高一凡《数据结构》--算法实现及解析 */
{
BSTree q,s;
if(!(*p)->rchild) /* p的右子树空则只需重接它的左子树(待删结点是叶子也走此分支) */
{
q=*p;
*p=(*p)->lchild;
free(q);
}
else if(!(*p)->lchild) /* p的左子树空,只需重接它的右子树 */
{
q=*p;
*p=(*p)->rchild;
free(q);
}
else /* p的左右子树均不空 */
{
q=*p;
s=(*p)->lchild;
while(s->rchild) /* 转左,然后向右到尽头(找待删结点的前驱) */
{
q=s;
s=s->rchild;
}
(*p)->e=s->e; /* s指向被删结点的"前驱"(将被删结点前驱的值取代被删结点的值) */
if(q!=*p) /* 情况1 */
q->rchild=s->lchild; /* 重接*q的右子树 */
else /* 情况2 */
q->lchild=s->lchild; /* 重接*q的左子树 */
free(s);
}
}
int DeleteBSTree(BSTree *tree,KeyType key)
{
if(!*tree)
return FALSE;
else
{
if(EQ(key,(*tree)->e.key))/* Matches */
Delete(tree);/* Delete node */
else if(LT(key,(*tree)->e.key))/* Less than */
DeleteBSTree(&(*tree)->lchild,key);
else/* More than */
DeleteBSTree(&(*tree)->rchild,key);
return TRUE;
}
}
void Print(ElemType* e)/* Print element information */
{
printf("%5d\t",e->key);
printf("%s\t",e->data.stu_num);
printf("%20s\t",e->data.stu_name);
printf("%3d",e->data.stu_age);
printf("\n");
}
int main(int argc,char** argv)
{
BSTree tree=NULL;
BSTNode *node=NULL;
ElemType *elem=NULL;
Student stu1={"12000001","Tom",22};
InitBSTree(tree);
printf("Insert some records:\n");
elem=(ElemType*)malloc(sizeof(ElemType));
elem->key=1;
elem->data=stu1;
InsertBSTree(&tree,elem);
elem->key=2;
InsertBSTree(&tree,elem);
elem->key=7;
InsertBSTree(&tree,elem);
elem->key=5;
InsertBSTree(&tree,elem);
elem->key=12;
InsertBSTree(&tree,elem);
InOrderTraverseBSTree(tree,Print);
printf("Search a node that key is 2:\n");
node=SearchBSTNode(tree,2);
if(!node)
printf("Not found!\n");
else
Print(&node->e);
printf("Delete a record which key=5:\n");
DeleteBSTree(&tree,5);
InOrderTraverseBSTree(tree,Print);
printf("After Destroyed:\n");
DestroyBSTree(&tree);
InOrderTraverseBSTree(tree,Print);
return 0;
}
参考:
高一凡《数据结构》--算法实现及解析