二叉樹是一種樹形結構,它的特點是每個每個結點至多有兩棵子樹,二叉樹有左、右子樹之分,且左、右子樹不能顛倒。二叉樹及其變體樹形結構在實際編程中使用的非常多,如:哈弗曼樹,線索二叉樹,紅黑樹等。
1.基本概念
樹是n(n>=0)個結點的有限集合。在任意一個非空樹中:
(1)有且僅有一個結點爲根結點。
(2)當n>1時,其餘結點可分爲m(m>0)個互不相交的有限集T1,T2......Tm,其中每一個集合本身又是一棵樹,並且成爲根的子樹。
結點擁有的子樹數稱爲結點的度。
度爲0的結點稱爲葉子或終端結點。
度不爲0的結點稱爲非終端結點或分支結點。
樹的度是樹內結點度的最大值。
結點的子樹稱爲結點的孩子。
該結點稱爲孩子的雙親。
同一個雙親之間的孩子稱爲兄弟。
根結點稱爲祖先。
除祖先外所有結點稱爲子孫。
樹的層,結點的屢次從根開始定義起,根爲第一層,根的孩子爲第二層,以此類推。
樹中的最大層數稱爲樹的深度。
如果將樹中結點的各子樹看成從左到右是有次序的(不能互換),則稱該樹爲有序樹,否則稱爲無序樹。
二叉樹是另一種樹形結構,它的特點是每個每個結點至多有兩棵子樹,二叉樹有左、右子樹之分,且左、右子樹不能顛倒。
森林是m(m>=0)棵的互不相交的樹的集合。對樹中每個結點而言,其子樹的集合爲森林。
2.二叉樹的性質
性質1:在二叉樹的第i層至多有2的(i-1)次方個結點(i>=1)。
性質2:深度爲i的二叉樹至多有2的k次方減1個結點(k>=1)。
性質3:對任何一個二叉樹T,其終端結點樹爲n0,度爲2的結點樹爲n2,則n0 = n2 + 1。。
性質4:具有n個結點的完全二叉樹的深度爲[log2n]+1。
性質5:如果對一棵有n個結點的完全二叉樹的結點按層序編號,則對任一結點i(1=< i <=n),有:
如果i=1,則結點i是二叉樹的根,無雙親;如果i>1,則其雙親是結點[i/2]
如果2i>n,則結點i無左孩子;否則其左孩子是2i
如果2i+1>n,則結點i無右孩子;否則其右孩子是2i+1
頭文件:
/*****************************************************************************************************
*Copyright: Yue Workstation
*
*FileName: BinTree.h
*
*Function: 二叉樹數據結構定義
*
*Author: Abel Lee
*
*CreateOn: 2012-2-19
*
*Log: 2012-2-19 由Abel Lee創建
*****************************************************************************************************/
#ifndef BIN_TREE_H
#define BIN_TREE_H
#include "global.h"
#define STACK_INCREMENT 2 //棧存儲空間分配增量
typedef struct Node
{
int data;
struct Node *left_child;
struct Node *right_child;
int flag;//專門用於二叉樹後序遍歷
}BiTNode,*BiTree;
typedef struct Stack
{
BiTNode *base;
BiTNode *top;
int stack_size;
}Stack;
int InitBinaryTree(BiTree *T);
int PreviousCreateTree(BiTree *T);
int MiddleCreateTree(BiTree *T);
int RearCreateTree(BiTree *T);
void PreviousPrintTree(BiTree T);
void MiddlePrintTree(BiTree T);
void RearPrintTree(BiTree T);
int BinInitStack(Stack *s);
int BinPush(Stack *s,BiTNode e);
int BinPop(Stack *s,BiTNode **e);
int IsNotEmptyStack(Stack *s);
int BinGetTop(Stack *s,BiTNode **e);
int NotRecursionPreviousPrintTree(BiTree T);
int NotRecursionMiddlePrintTree(BiTree T);
int NotRecursionRearPrintTree(BiTree T);
int LevelPrintTree(BiTree T);
int BinaryTreeIsEmpty(BiTree T);
int BinaryTreeDepth(BiTree T);
int GetRoot(BiTree T);
int Value(BiTree p);
void Assign(BiTree p,int value);
int GetParentNode(BiTree T, int e);
int ChangeNode(BiTree T,int e,int v);
int GetNoteLeftChild(BiTree T, int e);
int GetNoteRightChild(BiTree T, int e);
int GetLeftBrother(BiTree T, int e);
int GetRightBrother(BiTree T, int e);
int InsertChild(BiTree *T, int e, int v,int LR);
int DestroyBinaryTree(BiTree *T);
int DeleteChildTree(BiTree *T, int e);
#endif
源文件:
/*****************************************************************************************************
*Copyright:Yue Workstation
*
*FileName: BinTree.c
*
*Function: 二叉樹操作
*
*Author:Abel Lee
*
*CreateOn:2012-2-19
*
*Log:2011-5-3 由Abel Lee創建
*****************************************************************************************************/
#include "../inc/BinTree.h"
/****************************************************************************************************
*Function Name: InitBinaryTree
*
*Function: 初始化二叉樹
*
*Parameter: T:二叉樹頭指針
*
*Return Value:成功返回0,失敗返回-1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int InitBinaryTree(BiTree *T)
{
*T = (BiTree)malloc(sizeof(BiTNode));
if(*T)
{
return 0;
}
else
{
return -1;
}
}
/****************************************************************************************************
*Function Name: PreviousCreateTree
*
*Function: 先序創建一個二叉樹
*
*Parameter: T:二叉樹頭指針
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int PreviousCreateTree(BiTree *T)
{
int ch;
scanf("%d",&ch);
if(ch == 0)
{
(*T) = NULL;
}
else
{
(*T) = (BiTree)malloc(sizeof(BiTNode));
(*T)->data = ch;
PreviousCreateTree(&((*T)->left_child));
PreviousCreateTree(&((*T)->right_child));
}
return 0;
}
/****************************************************************************************************
*Function Name: MiddleCreateTree
*
*Function: 中序建立一個二叉樹
*
*Parameter: T:二叉樹頭指針
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int MiddleCreateTree(BiTree *T)
{
int ch;
scanf("%d",&ch);
if(ch == 0)
{
(*T) = NULL;
}
else
{
(*T) = (BiTree)malloc(sizeof(BiTNode));
MiddleCreateTree(&((*T)->left_child));
(*T)->data = ch;
MiddleCreateTree(&((*T)->right_child));
}
return 0;
}
/****************************************************************************************************
*Function Name: RearCreateTree
*
*Function: 後序建立一個二叉樹
*
*Parameter: T:二叉樹頭指針
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int RearCreateTree(BiTree *T)
{
int ch;
scanf("%d",&ch);
if(ch == 0)
{
(*T) = NULL;
}
else
{
(*T) = (BiTree)malloc(sizeof(BiTNode));
RearCreateTree(&((*T)->left_child));
RearCreateTree(&((*T)->right_child));
(*T)->data = ch;
}
return 0;
}
/****************************************************************************************************
*Function Name: PreviousPrintTree
*
*Function: 先序遍歷二叉樹
*
*Parameter: T:二叉樹頭
*
*Return Value: 無
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
void PreviousPrintTree(BiTree T)
{
if(T)
{
printf("%d",T->data);
PreviousPrintTree(T->left_child);
PreviousPrintTree(T->right_child);
}
}
/****************************************************************************************************
*Function Name: MiddlePrintTree
*
*Function: 中序遍歷二叉樹
*
*Parameter: T:二叉樹頭
*
*Return Value: 無
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
void MiddlePrintTree(BiTree T)
{
if(T)
{
MiddlePrintTree(T->left_child);
printf("%d",T->data);
MiddlePrintTree(T->right_child);
}
}
/****************************************************************************************************
*Function Name: RearPrintTree
*
*Function: 後序遍歷二叉樹
*
*Parameter: T:二叉樹頭
*
*Return Value: 無
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
void RearPrintTree(BiTree T)
{
if(T)
{
RearPrintTree(T->left_child);
RearPrintTree(T->right_child);
printf("%d",T->data);
}
}
/****************************************************************************************************
*Function Name: BinInitStack
*
*Function: 初始化一個棧
*
*Parameter: s:棧指針
*
*Return Value: 成功返回0,失敗返回-1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int BinInitStack(Stack *s)
{
s->base = (BiTree)malloc(STACK_INIT_SIZE * sizeof(BiTNode));
if(!s->base)
{
perror("Init stack error,malloc have a error message.");
return -1;
}
s->top = s->base;
s->stack_size = STACK_INIT_SIZE;
return 0;
}
/****************************************************************************************************
*Function Name: BinPush
*
*Function: 入棧
*
*Parameter: s:棧指針
* e:入棧元素
*
*Return Value: 成功返回0,失敗返回-1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int BinPush(Stack *s,BiTNode e)
{
if(s->top >= s->base + s->stack_size)
{
s->base = (BiTree)realloc(s->base,(STACK_INIT_SIZE + STACK_INCREMENT) * sizeof(BiTNode));
if(!s->base)
{
perror("Init stack error,realloc have a error message.");
return -1;
}
s->stack_size += STACK_INCREMENT;
}
*(s->top) = e;
s->top++;
return 0;
}
/****************************************************************************************************
*Function Name: BinPop
*
*Function: 出棧
*
*Parameter: s:棧指針
* e:保存出棧元素
*
*Return Value: 成功返回0,失敗返回-1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int BinPop(Stack *s,BiTNode **e)
{
if(s->top != s->base)
{
s->top--;
*e = s->top;
return 0;
}
else
{
return -1;
}
}
/****************************************************************************************************
*Function Name: IsNotEmptyStack
*
*Function: 棧是否爲空
*
*Parameter: s:棧指針
*
*Return Value: 爲空返回0,不空返回1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int IsNotEmptyStack(Stack *s)
{
if(s->top == s->base)
{
return 0;
}
else
{
return 1;
}
}
/****************************************************************************************************
*Function Name: BinGetTop
*
*Function: 獲取棧頂元素
*
*Parameter: s:棧指針
* e:保存出棧元素
*
*Return Value:成功返回0,失敗返回-1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int BinGetTop(Stack *s,BiTNode **e)
{
Stack *temp = s;
if(!IsNotEmptyStack(s))
{
perror("That is a empty stack!");
return -1;
}
temp->top--;
*e = temp->top;
return 0;
}
/****************************************************************************************************
*Function Name: NotRecursionPreviousPrintTree
*
*Function: 棧的非遞歸先序遍歷二叉樹
*
*Parameter: T:二叉樹頭
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int NotRecursionPreviousPrintTree(BiTree T)
{
Stack new_stack;
BiTree p = T;
BinInitStack(&new_stack);
while(p || IsNotEmptyStack(&new_stack))
{
while(p)
{
printf("%d",p->data);
BinPush(&new_stack,*p);
p = p->left_child;
}
if(IsNotEmptyStack(&new_stack))
{
BinPop(&new_stack,&p);
p = p->right_child;
}
}
return 0;
}
/****************************************************************************************************
*Function Name: NotRecursionMiddlePrintTree
*
*Function: 棧的非遞歸中序遍歷二叉樹
*
*Parameter: T:二叉樹頭
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int NotRecursionMiddlePrintTree(BiTree T)
{
Stack new_stack;
BiTree p = T;
BinInitStack(&new_stack);
while(p || IsNotEmptyStack(&new_stack))
{
while(p)
{
BinPush(&new_stack,*p);
p = p->left_child;
}
if(IsNotEmptyStack(&new_stack))
{
BinPop(&new_stack,&p);
printf("%d",p->data);
p = p->right_child;
}
}
return 0;
}
/****************************************************************************************************
*Function Name: NotRecursionRearPrintTree
*
*Function: 棧的非遞歸後序遍歷二叉樹
*
*Parameter: T:二叉樹頭
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int NotRecursionRearPrintTree(BiTree T)
{/*
Stack new_stack;
BiTree p = T;
BiTree q;
InitStack(&new_stack);
do
{
while(p)
{
if(p->flag != 2)
{
if(p->flag !=1 )
{
p->flag = 1;
Push(&new_stack, *p);
}
if(p->left_child && p->left_child->flag != 2)
{
q = p;
p = p->left_child;
}
else if(p->right_child && p->right_child->flag != 2)
{
q = p;
p = p->right_child;
}
else
{
break;
}
}
else
{
break;
}
}
if (IsNotEmptyStack(&new_stack))
{
Pop(&new_stack,&q);
if(p->flag == 1)
{
p->flag = 2;
printf("%d",p->data);
p = q;
}
}
else
{
break;
}
}while(p || IsNotEmptyStack(&new_stack));
*/
return 0;
}
/****************************************************************************************************
*Function Name: LevelPrintTree
*
*Function: 層次遍歷二叉樹
*
*Parameter: T:二叉樹頭
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int LevelPrintTree(BiTree T)
{
BiTree Q[MAX_LENGTH];
int front = 0,rear = 0;
BiTree p;
if(T)
{
Q[rear] = T;
rear = (rear + 1)%MAX_LENGTH;
}
while(front != rear)
{
p = Q[front];//隊頭元素出隊
front = (front + 1)%MAX_LENGTH;
printf("%d",p->data);
if(p->left_child)
{
Q[rear] = p->left_child;
rear = (rear + 1)%MAX_LENGTH;
}
if(p->right_child)
{
Q[rear] = p->right_child;
rear = (rear + 1)%MAX_LENGTH;
}
}
return 0;
}
/****************************************************************************************************
*Function Name: BinaryTreeIsEmpty
*
*Function: 判斷二叉樹是否爲空
*
*Parameter: 二叉樹頭
*
*Return Value: 爲空返回0,不空返回1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int BinaryTreeIsEmpty(BiTree T)
{
if(T)
{
return 1;
}
else
{
return 0;
}
}
/****************************************************************************************************
*Function Name: BinaryTreeDepth
*
*Function: 求二叉樹的深度
*
*Parameter: T:二叉樹頭
*
*Return Value:返回二叉樹深度值
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int BinaryTreeDepth(BiTree T)
{
int left = 0;
int right = 0;
if(!T)
{
return 0;
}
if(T->left_child)
{
left = BinaryTreeDepth(T->left_child);
}
else
{
left = 0;
}
if(T->right_child)
{
right = BinaryTreeDepth(T->right_child);
}
else
{
right = 0;
}
return left > right ? (left+1):(right+1);
}
/****************************************************************************************************
*Function Name: GetRoot
*
*Function: 返回二叉樹根結點
*
*Parameter: T:二叉樹頭
*
*Return Value:成功返回頭數據,失敗返回-1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int GetRoot(BiTree T)
{
if(T)
{
return T->data;
}
else
{
return -1;
}
}
/****************************************************************************************************
*Function Name: Value
*
*Function: 返回二叉樹某節點的值
*
*Parameter: T:二叉樹頭
*
*Return Value: 返回二叉樹結點保存的值
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int Value(BiTree p)
{
return p->data;
}
/****************************************************************************************************
*Function Name: Assign
*
*Function: 爲某個節點分配值
*
*Parameter: p:二叉樹頭
* value:要分配的值
*
*Return Value: 無
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
void Assign(BiTree p,int value)
{
p->data = value;
}
/****************************************************************************************************
*Function Name: GetParentNode
*
*Function: 若e是非根結點,返回他的雙親
*
*Parameter: T:二叉樹頭
* e:結點值
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int GetParentNode(BiTree T, int e)
{
if((T->left_child && T->left_child->data == e) || (T->right_child && T->right_child->data == e))
{
return T->data;
}
else
{
if(T->left_child)
{
return GetParentNode(T->left_child, e);
}
if(T->right_child)
{
return GetParentNode(T->right_child, e);
}
}
return 0;
}
/****************************************************************************************************
*Function Name: ChangeNode
*
*Function: 如果T中存在e,則將e改爲v
*
*Parameter: T:二叉樹頭
* e:被該數據
* v:修改後的數據
*
*Return Value:成功返回0,失敗返回-1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int ChangeNode(BiTree T,int e,int v)
{
if(T->data == e)
{
T->data = v;
}
else
{
if(T->left_child)
{
ChangeNode(T->left_child,e,v);
return 0;
}
if(T->right_child)
{
ChangeNode(T->right_child,e,v);
return 0;
}
}
return -1;
}
/****************************************************************************************************
*Function Name: GetNoteLeftChild
*
*Function: 如果二叉樹中存在e則返回其左孩子
*
*Parameter: T:二叉樹頭
* e:結點值
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int GetNoteLeftChild(BiTree T, int e)
{
if(T->data == e)
{
if(T->left_child)
{
return T->left_child->data;
}
else
{
return 0;
}
}
else
{
if(T->left_child)
{
return GetNoteLeftChild(T->left_child,e);
}
else
{
return 0;
}
if(T->right_child)
{
return GetNoteLeftChild(T->right_child,e);
}
{
return 0;
}
}
}
/****************************************************************************************************
*Function Name: GetNoteRightChild
*
*Function: 如果二叉樹中存在e則返回其右孩子
*
*Parameter: T:二叉樹頭
* e:結點值
*
*Return Value:成功返回0
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int GetNoteRightChild(BiTree T, int e)
{
if(T->data == e)
{
if(T->right_child)
{
return T->right_child->data;
}
else
{
return 0;
}
}
else
{
if(T->left_child)
{
return GetNoteRightChild(T->left_child,e);
}
else
{
return 0;
}
if(T->right_child)
{
return GetNoteRightChild(T->right_child,e);
}
{
return 0;
}
}
}
/****************************************************************************************************
*Function Name: GetLeftBrother
*
*Function: 如果T中存在e,則返回其左兄弟
*
*Parameter: T:二叉樹頭
* e:結點值
*
*Return Value:成功返回左兄弟值
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int GetLeftBrother(BiTree T, int e)
{
if(T->right_child && T->right_child->data == e)
{
if(T->left_child)
{
return T->left_child->data;
}
}
else
{
if(T->left_child)
{
return GetLeftBrother(T->left_child, e);
}
if(T->right_child)
{
return GetLeftBrother(T->right_child, e);
}
}
return 0;
}
/****************************************************************************************************
*Function Name: GetRightBrother
*
*Function: 如果T中存在e,則返回其右兄弟
*
*Parameter: T:二叉樹頭
* e:結點值
*
*Return Value:成功返回左兄弟值
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int GetRightBrother(BiTree T, int e)
{
if(T->left_child && T->left_child->data == e)
{
if(T->right_child)
{
return T->right_child->data;
}
}
else
{
if(T->left_child)
{
return GetRightBrother(T->left_child, e);
}
if(T->right_child)
{
return GetRightBrother(T->right_child, e);
}
}
return 0;
}
/****************************************************************************************************
*Function Name: InsertChild
*
*Function: 如果T中存在e,則LR爲1時,插入v爲e的左孩子,LR爲2時插入v爲e的右孩子,如果不存在返回0
*
*Parameter: T:二叉樹頭指針
* e:結點
* v:結點
* LR:標識
*
*Return Value:成功返回0,失敗返回1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int InsertChild(BiTree *T, int e, int v,int LR)
{
BiTree p = NULL;
if((*T)->data == e)
{
if(LR == 1)
{
InitBinaryTree(&p);
p->data = v;
p->right_child = (*T)->left_child;
p->left_child = NULL;
(*T)->left_child = p;
}
if(LR == 2)
{
InitBinaryTree(&p);
p->data = v;
p->right_child = (*T)->right_child;
p->left_child = NULL;
(*T)->right_child = p;
}
}
else
{
if((*T)->left_child)
{
if(InsertChild(&((*T)->left_child),e,v,LR))
{
return 1;
}
}
if((*T)->right_child)
{
if(InsertChild(&((*T)->right_child),e,v,LR))
{
return 1;
}
}
}
return 0;
}
/****************************************************************************************************
*Function Name: DestroyBinaryTree
*
*Function: 銷燬二叉樹
*
*Parameter: 二叉樹頭指針
*
*Return Value:成功返回1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int DestroyBinaryTree(BiTree *T)
{
if(*T)
{
DestroyBinaryTree(&((*T)->left_child));
DestroyBinaryTree(&((*T)->right_child));
free(*T);
*T = NULL;
}
return 1;
}
/****************************************************************************************************
*Function Name: DeleteChildTree
*
*Function: 如果T中存在e,刪除e結點子樹並返回1,否則返回0
*
*Parameter: T:二叉樹頭指針
* e:結點值
*
*Return Value:成功返回0,失敗返回1
*
*Author:Abel Lee
*
*Log:2012-2-19
***************************************************************************************************/
int DeleteChildTree(BiTree *T, int e)
{
if((*T)->data == e)
{
free(*T);
*T = NULL;
return 1;
}
else
{
if((*T)->left_child)
{
if(DeleteChildTree(&((*T)->left_child),e))
{
return 1;
}
}
{
if(DeleteChildTree((&(*T)->left_child),e))
{
return 1;
}
}
}
return 0;
}