一颗树是一些节点的集合,这些集合可以是 空集;若非空,则一颗树由称作根(root)的节点r以及0个或多个非空的字数T1, T2, T3, …, Tk组成,这些子树中的每一颗的根都有来自根r的一条有向边(edge)所连接。每一颗子树的根叫做跟r的儿子(child),而r是每一颗子树的根的父亲(parent)。
一颗具体的树:
1.树的相关术语
节点的度:一个节点含有的子树的个数称为该节点的度;
树的度:一棵树中,最大的节点的度称为树的度;
叶节点或终端节点:度为零的节点;即不存在儿子节点的节点。
非终端节点或分支节点:度不为零的节点;
父亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;
兄弟节点:具有相同父节点的节点互称为兄弟节点;
节点的层次:从根开始定义起,根为第1层,根的子节点为第1层,以此类推;
树的高度或深度:树中节点的最大层次;
堂兄弟节点:父节点在同一层的节点互为堂兄弟;
节点的祖先:从根到该节点所经分支上的所有节点;
子孙:以某节点为根的子树中任一节点都称为该节点的子孙。
森林:由m(m>=0)棵互不相交的树的集合称为森林;
2.树的分类
无序树:树中任意节点的子节点之间没有顺序关系,这种树称为无序树,也称为自由树;
有序树:树中任意节点的子节点之间有顺序关系,这种树称为有序树;主要包括二叉树、霍夫曼树、B树。
3.树的基本操作
树的主要操作包括:求树的深度、求给定节点的子节点、兄弟节点、遍历树、插入子树、删除子树等等。
3.1树的递归实现
/*树的递归实现*/
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
//树节点的声明
typedef struct TNode
{
ElemType element;
TNode *fistChild, *nextSibling;
}TNode, *Tree;
//初始化一个节点
Tree initTree(ElemType e)
{
Tree pT;
pT = (TNode*) malloc(sizeof(TNode)); //新建一个树节点
pT->fistChild = NULL;
pT->nextSibling = NULL;
pT->element = e;
return pT;
}
//删除树
void deleteTree(Tree *T)
{
if(*T == NULL)
return ;
deleteTree( &(*T)->nextSibling);
deleteTree(&(*T)->fistChild);
free(*T);
*T = NULL;
}
//遍历树并打印
void printTree(Tree T)
{
if(NULL == T)
return;
else
{
printf("%d\t", T->element);
printTree(T->fistChild);
printTree(T->nextSibling);
}
}
//求树的深度
int treeDepth(Tree tree)
{
int height = 0;
int subTreeDepth = 0;
if(tree == NULL)
return 0;
Tree p = tree->fistChild;
while (p != NULL)
{
subTreeDepth = treeDepth(p);
p = p->nextSibling;
if(subTreeDepth > height)
height = subTreeDepth;
}
return (height + 1);
}
//在树中寻找指定元素的地址
Tree locateElem(Tree tree, ElemType e)
{
Tree result;
if(tree == NULL)
return NULL;
if(tree ->element == e)
{
result = tree;
return result;
}
Tree p = tree->fistChild;
while (p!=NULL)
{
locateElem(p, e);
p = p->nextSibling;
}
}
//返回子节点的指针
Tree findChild(Tree tree, ElemType element)
{
Tree result = locateElem(tree, element);
if( result == NULL && NULL == result->fistChild )
return NULL; //如果没有找到或者该节点是叶子节点,返回空
else
return result->fistChild;
}
//返回兄弟节点的指针
Tree findSiblong(Tree tree, ElemType element)
{
Tree result = locateElem(tree, element);
if(NULL == result && NULL == result->nextSibling)
return NULL; //如果没有找到或者该节点没有右兄弟,返回空
else
return result->nextSibling;
}
bool insertTree(Tree &tree, Tree treeadd, ElemType element)
{
Tree tptree = locateElem(tree, element);
if (tptree != NULL)
{
treeadd->nextSibling = tptree->fistChild;
tptree->fistChild = treeadd;
return true;
}
else
return false;
}
//删除子树
bool deleteSubtree(Tree &tree, ElemType element)
{
Tree tptree = locateElem(tree, element);
if(tptree->fistChild != NULL)
{
deleteTree(&(tptree->fistChild));
return true;
}
else
return false;
}
int main()
{
Tree tree = (TNode *) malloc(sizeof(TNode));
Tree pt = (TNode *) malloc(sizeof(TNode));
tree = initTree(6);
pt = initTree(5);
tree->fistChild = pt;
Tree pt1 = initTree(8);
tree->nextSibling = pt1;
Tree pt2 = initTree(3);
pt->fistChild = pt2;
Tree pt3 = initTree(7);
printf("the original tree is: \n");
printTree(tree);
int depth = treeDepth(tree);
printf("\ndepth of tree is: %d\n",depth);
Tree node = locateElem(tree,8);
int del = deleteSubtree(tree,5);
if(del)
printf("delete subtree sucessfully! Now the tree is: \n");
printTree(tree);
printf("\nNow insert an element 7 in right subtree, before 8: \n");
insertTree(tree,pt3, 8);
printTree(tree);
system("pause");
return 0;
}
参考:http://blog.csdn.net/thefutureisour/article/details/7876328
3.2 树的队列实现
/* 树节点的定义 */
#define MAX_TREE_SIZE 100
typedef struct
{
TElemType data;
int parent; /* 父节点位置域 */
} PTNode;
typedef struct
{
PTNode nodes[MAX_TREE_SIZE];
int n; /* 节点数 */
} PTree
具体的操作有涉及队列,详见维基百科:树–数据结构