参考:Mark Allen Weiss 著《数据结构与算法分析——C语言描述》(第二版)
主要内容:二叉树及二叉查找树
一、二叉树
1 二叉树定义
二叉树是一棵每个节点都不能有多于两个儿子的树
2 实现
2.1 实现思路
因为一个二叉树最多有两个儿子,所以我们可以用指针直接指向它们。
2.2 实现代码
typedef struct TreeNode *PtrToNode; typedef struct PtrToNode Tree; struct TreeNode { int Element; Tree Left; Tree Right; };
二、二叉查找树
1 二叉查找树的定义
二叉查找树是一棵特殊的二叉树。对于数中的每个节点X,它的左子树中所有关键字值小于X的关键字;
而它的右子树中所有关键字值大于X的关键字。图1中,只有左边的二叉树是二叉查找树。因为右边的树在关键字为6的节点的左子树中有个节点的关键字为7,大于6。
图1 两棵二叉树
2 基本操作
函数声明代码
1 1 #ifndef BINARY_SEARCH_TREE_H_INCLUDED 2 2 #define BINARY_SEARCH_TREE_H_INCLUDED 3 3 #include <stdio.h> 4 4 #include <stdlib.h> 5 5 6 6 struct TreeNode; 7 7 typedef struct TreeNode *Position; 8 8 typedef struct TreeNode *SearchTree; 9 9 10 10 SearchTree MakeEmpty(SearchTree T); 11 11 Position Find(int X,SearchTree T); 12 12 Position FindMin(SearchTree T); 13 13 Position FindMax01(SearchTree T); 14 14 Position FindMax02(SearchTree T); 15 15 SearchTree Insert(int X,SearchTree T); 16 16 SearchTree Delete(int X,SearchTree T); 17 17 void Retrieve01(Position P); 18 18 int Retrieve(Position P); 19 19 #endif // BINARY_SEARCH_TREE_H_INCLUDED
2.1 初始化操作(MakeEmpty)
2.1.1 实现思路
创建一个空树。
2.1.2 伪代码
1 /*建立一棵空树的例程*/ 2 SearchTree MakeEmpty(SearchTree T) 3 { 4 if(NULL != T) 5 { 6 MakeEmpty(T->Left); 7 MakeEmpty(T->Right); 8 free(T); 9 } 10 return NULL; 11 }
2.2 查找操作(Find)
2.2.1 实现思路见图1。
图2 Find实现思路
注意:一般返回指向树T中具有关键字X的节点的指针,如果这样的节点不存在则返回NULL
2.2.2 伪代码
1 /*二叉查找树得到Find操作*/ 2 Position Find(int X,SearchTree T) 3 { 4 if(NULL == T) 5 { 6 return NULL; 7 } 8 if(X < T->Element) 9 { 10 Find( X,T->Left); 11 }else if(X > T->Element) 12 { 13 Find( X,T->Right); 14 }else{ 15 return T; 16 } 17 }
2.2.3 补充
由Find操作延伸出查找最小值操作(FindMin)和查找最大值操作(FindMax)。
(1)查找最小值操作(FindMin)
基本思路为:从根开始并且只要有左儿子就对左子树进行Find操作,返回值为指向最小值节点的指针。实现代码如下,
1 /*对二叉查找树的FindMin的递归实现*/ 2 Position FindMin(SearchTree T) 3 { 4 if(NULL == T){ 5 return NULL;} 6 if(NULL == T->Left) 7 { 8 return T; 9 }else{ 10 return FindMin(T->Left); 11 } 12 }
(2)查找最小值操作(FindMax)
基本思路为:从根开始并且只要有右儿子就对右子树进行Find操作,返回值为指向最大值节点的指针。实现代码如下,
/*对二叉查找树的FindMax的递归实现*/ Position FindMax01(SearchTree T) { if(NULL == T){ return NULL;} if(NULL == T->Right) { return T; }else{ return FindMin(T->Right); } } /*对二叉查找树的FindMax的非递归实现*/ Position FindMax02(SearchTree T) { if(NULL != T){ while(T->Right != NULL) { T=T->Right; } } return T; }
2.3 插入操作(Insert)
2.3.1 实现思路如图3
图3 插入操作实现思路
2.3.2 实现代码如下,
1 /*插入元素到二叉查找树的例程*/ 2 SearchTree Insert(int X,SearchTree T) 3 { 4 if(NULL == T) 5 { 6 T = (struct TreeNode *)malloc(sizeof(struct TreeNode)); 7 if( T == NULL ) 8 { 9 perror("Out Of Space!!!"); 10 }else{ 11 T->Element = X; 12 T->Left = NULL; 13 T->Right = NULL; 14 } 15 }else if( X > T->Element) 16 { 17 T->Right = Insert( X,T->Right); 18 }else if( X < T->Element) 19 { 20 T->Left = Insert( X,T->Right); 21 } 22 return T; 23 }
2.4 删除操作(Delete)
2.4.1 实现思路如图4
图4 删除操作实现思路
2.4.2 实现代码如下,
/*二叉查找树的删除例程*/ SearchTree Delete(int X,SearchTree T) { Position TmpCell; if(NULL == T) { perror("Element is not found"); }else if(X < T->Element) { T->Left = Delete(X,T->Left); }else if(X > T->Element) { T->Right = Delete(X,T->Right); }else{ if(T->Left && T->Right ) { TmpCell = FindMin(T->Right); T->Element = TmpCell->Element; T->Right =Delete(T->Element,T->Right); }else{ TmpCell = T; if(T->Left == NULL) { T =T->Right; }else if(T->Right == NULL) { T = T->Left; } } free(TmpCell); } return T; }