树的学习(一)
1.在一棵树种,对于任意节点n,n的深度为从根到n的唯一路径长,因为根的深度为0。
2.在一棵树种,对于任意节点n,n的高为从n到一片树叶的最长路径的长,因为树叶的高度都是0。
3.树的三种常见的遍历方式,先序遍历、中序遍历和后序遍历。在先序遍历中对节点的处理工作是在诸儿子节点被处理之前,后序遍历中节点的处理工作是在它的诸儿子节点处理之后进行,中序遍历中节点的处理是在中间(左儿子、节点、右儿子)。
4、二叉树的性质是平均二叉树的深度要比N(节点数)小很多,平均深度为O(N^1/2),对于特殊类型的二叉查找树,其深度的平均值是O(logN)。二叉树深度最大可以到N-1。
struct TreeNode
{
ElementType Element;
SearchTree Left;
SearchTree Right;
};//树节点声明
5、二叉查找树中的每个节点被指定一个关键字值,树的性质是,对于树中的每个节点X,它的左树中所有关键字值小于X的关键字值,而它的右子树中所有关键字值大于X。平均查找深度O(logN)。
6、建立空树
typedef struct TreeNode *SearchTree;
SearchTree
MakeEmpty( SearchTree T )
{
if( T != NULL )
{
MakeEmpty( T->Left );
MakeEmpty( T->Right );
free( T );
}
return NULL;
}
7、Find操作,该操作一般需要返回指向树T中具有关键字X的节点的指针,不存在则返回NULL。
typedef struct TreeNode *Position;
递归查找
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;
}
循环查找
Position
Find(ElementType X, SearchTree T)
{
while (T != NULL && X != T->Element)
{
if (X < T->Element)
T = T->Left;
else T = T->Right;
}
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 )
while( T->Right != NULL )
T = T->Right;
return T;
}
8、二叉查找树的删除操作,如果删除的节点是一片叶子,那么它可以被立即删除,如果节点只有一个儿子,则该节点可以在其父节点调整指针绕过该节点后被删除。如果有两个节点,一般的删除策略是用其右子树的最小的数据代替该节点的数据并递归的删除那个节点
SearchTree
Delete( ElementType X, SearchTree T )
{
Position TmpCell;
if( T == NULL )
printf( "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->Right );
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;
}
9、插入Insert操作,为了将X插入到树T(二叉查找树),可以像Find那样沿着树查找,若找到X,则什么也不做。否则,则将X插入到遍历的路径上的最后一点上。
SearchTree
Insert( ElementType X, SearchTree T )
{
/* 1*/ if( T == NULL )
{
/* Create and return a one-node tree */
/* 2*/ T = malloc( sizeof( struct TreeNode ) );
/* 3*/ if( T == NULL )
/* 4*/ printf( "Out of space!!!" );
else
{
/* 5*/ T->Element = X;
/* 6*/ T->Left = T->Right = NULL;
}
}
else
/* 7*/ if( X < T->Element )
/* 8*/ T->Left = Insert( X, T->Left );
else
/* 9*/ if( X > T->Element )
/*10*/ T->Right = Insert( X, T->Right );
/* Else X is in the tree already; we'll do nothing */
/*11*/ return T; /* Do not forget this line!! */