树是树型结构的简称。若树中各节点的子树是按照一定的次序从左到右安排的,则称之为有序树,否则称为无序树。
森林是m(m>=0)棵互不相交的树的集合。
树的性质:
1,树中的结点数等于所有结点的度数加1.
2,度为k的树中第i层上至多有k^(i-1)个结点(i>=1).
3,深度为h的k叉树至多有(k^h-1)/(k-1)个结点。
4,具有n个结点的k叉树的最小深度为logk(n(k-1)+1的上取整数。
二叉树是指树的度为2的有序树。
二叉树的存储结构:
strcut BTreeNode{
ElemType data;
struct BTreeNode* left;
struct BTreeNode* right;
}
初始化二叉树
void InitBTree(struct BTreeNode** BT)
{
*BT=NULL;
}
建立二叉树:
我们的算法是由广义表字符串建立一个二叉树,广义表的样式为(A(B(C),D(E(F,G),H(,I)))
void CreateBTree(struct BTreeNode** BT, char* a)
{
struct BTreeNode* p;
struct BTreeNode* s[StackMaxSize];
int top=-1;
int k;
int i=0;
*BT=NULL;
while(a[i])
{
switch(a[i]){
case ' ':
break;
case '(':
if(top==StackMaxSize-1){
printf("stack is too small ,please increase!\n");
exit(1);
}
top++;s[top]=p;k=1;
break;
case ')':
if(top==-1){
printf("a is not valid!\");
exit(1);
}
top--;break;
case ',':
k=2;break;
default:
p=malloc(sizeof(struct BTreeNode));
p->data=a[i];p->left=p->right=NULL;
if(*BT=NULL) *BT=p;
else{
if(k==1) s[top]->left=p;
else s[top]->right=p;
}
}
i++;
}
检查二叉树是否为空
int BTreeEmpty(struct BTreeNode* BT)
{
if(BT==NULL)return 1;else return0;
}
求二叉树深度
int BTreeDepth(struct BTreeNode* BT)
{
if(BT==NULL)
return 0;
else{
int dep1=BTreeDepth(BT->left);
int dep2=BTreeDepth(BT->right);
if(dep1>dep2)
return dep1+1;
else
return dep2+1;
}
}
从二叉树中查找值为x的节点,若存在则返回元素存储位置,否则返回空值。
ElemType* FindBTree(struct BTreeNode* BT,ElemType x)
{
if(BT==NULL) return NULL;
if(BT->data==x)return &(BT->data);
if(p=FindBTree(BT->left,x))return p;
if(p=FindBTree(BT->right,x)) return p;
return NULL;
}
输出二叉树
void PrintBTree(struct BTreeNode* BT)
{
if(BT!=NULL){
printf("%c",BT->data);
if(BT->left!=NULL||BT->right!=NULL){
printf("(");
PrintBTree(BT->left);
if(BT->right!=NULL)printf(",");
PrintBTree(BT->right);
printf(")");
}
}
}
清除二叉树,使之变为一棵空树
void ClearBTree(struct BTreeNode** BT)
{
if(*BT!=NULL){
ClearBTree(&((*BT)->left));
ClearBTree(&((*BT)->right));
free(*BT);
*BT=NULL;
}
}
四种遍历方法:
1,前序:
void Preorder(struct BTreeNode* BT)
{
if(BT!=NULL)
{
printf("%c",BT->data);
Preorder(BT->left);
Preorder(BT->right);
}
}
2,中序
void Inorder(struct BTreeNode* BT)
{
if(BT!=NULL)
{
Inorder(BT->left);
printf("%c",BT->data);
Inorder(BT->right);
}
}
3,后序
void Postorder(struct BTreeNode* BT)
{
if(BT!=NULL){
Postorder(BT->left);
Postorder(BT->right);
printf("%c ",BT->data);
}
}
4,按层遍历
void Levelorder(struct BTreeNode* BT)
{
struct BTreeNode* p;
struct BTreeNode* q[QueueMaxSize];
int front=0,rear=0;
if(BT!=NULL){
rear=(rear+1)%QueueMaxSize;
q[rear]=BT;
}
while(front!=rear){
front=(front+1)%QueueMaxSize;
p=q[front];
printf("%c ",p->data);
if(p->left!=NULL){
rear=(rear+1)%QueueMaxSize;
q[rear]=p->left;
}
if(p->right!=NULL){
rear=(rear+1)%QueueMaxSize;
q[rear]=p->right;
}
}
}
二叉搜索树,又称二叉排序树,它或者是一棵空树,或者是一棵具有如下特性的非空二叉树。
(1)若它的左子树非空,则左子树上所有的结点的关键字均小于根节点的关键字。
(2)若它的右子树非空,则右子树上所有结点的关键字均大于根结点的关键字。
(3)左、右子树本身又各是一棵二叉搜索树。
查找
ElemType* Find(struct BTreeNode* BST,ElemType x)
{
if(BST==NULL)return NULL;
if(x==BST->data)return &(BST->data);
else if(x<BST->data)
return Find(BST->left,x);
else
return Find(BST->right,x);
}
插入
void Insert(struct BTreeNode** BST,ElemType x)
{
if(*BST==NULL){
struct BTreeNode* p=malloc(sizeof(struct BTreeNode));
p->data=x;
p->left=p->right=NULL;
*BST=p;
}
else if(x<(*BST)->data) Insert(&(*BST)->left),x);
else Insert(&((*BST)->right),x);
}
非递归的方法
void Insert(struct BTreeNode** BST,ElemType x)
{
struct BTreeNode* p;
struct BTreeNode* t=*BST,*parent=NULL;
while(t!=NULL){
parent=t;
if(x<t->data)t=t->left;
else t=t->right;
}
p=malloc(sizeof(struct BTreeNode));
p->data=x;
p->left=p->right=NULL;
if(parent==NULL) *BST=p;
else if(x<parent->data)
parent->left=p;
else parent->right=p;
}
删除
int Delete(struct BTreeNode** BST,ElemType x)
{
struct BTreeNode* temp;
temp=*BST;
if(*BST==NULL) return 0;
if(x<(*BST)->data)return Delete(&((*BST->left),x);
if(x>(*BST)->data)return Delete(&((*BST->right),x);
if((*BST)->left==NUL){
*BST=(*BST)->right;free(temp);return 1;
}
else if((*BST)->right==NULL){
*BST=(*BST)->left;free(temp);return 1;
}
else{
if((*BST)->left->right=NULL){
(*BST)->data=(*BST)->left->data;
return Delete(&((*BST)->left),(*BST)->data);
}
else{
struct BTreeNode *p1=*BST,*p2=p1->left;
while(p2->right!=NULL){p1=p2;p2=p2->right;}
(*BST)->data=p2->data;
return Delete(&(p1->right),p2->data);
}
}
}