二叉樹的基本算法
包括二叉樹的遍歷(先、中、后),二叉樹的層次,二叉樹的深度,二叉樹的葉子節點數計算。相關算法思想可以看書,這里只是給出相關算法實現。
代碼實現
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef char ElemType;
typedef struct TNode {
char data;
TNode * lchild;
TNode * rchild;
}TNode, *BiTree;
int IsEmpty_BiTree(BiTree *T) {
if(*T == NULL)
return 1;//如果樹為空一直進入死循環,直到輸入數據為止
else
return 0;
}
void Create_BiTree(BiTree *T){
char ch;
ch = getchar();
//當輸入的是"#"時,認為該子樹為空
if(ch == '#')
*T = NULL;
//創建樹結點
else{
*T = (BiTree)malloc(sizeof(struct TNode));
(*T)->data = ch; //生成樹結點
//生成左子樹
Create_BiTree(&(*T)->lchild);
//生成右子樹
Create_BiTree(&(*T)->rchild);
}
}
void TraverseBiTree(BiTree T) { //先序遍歷
if(T == NULL)//指針為空,說明節點不存在
return;
else {
printf("%c ",T->data);
TraverseBiTree(T->lchild);
TraverseBiTree(T->rchild);
}
}
void InOrderBiTree(BiTree T) { //中序遍歷
if(NULL == T)
return;
else {
InOrderBiTree(T->lchild);
printf("%c ",T->data);
InOrderBiTree(T->rchild);
}
}
void PostOrderBiTree(BiTree T) {
if(NULL == T)
return;
else {
InOrderBiTree(T->lchild);
InOrderBiTree(T->rchild);
printf("%c ",T->data);
}
}
int TreeDeep(BiTree T) {
int deep = 0;
if(T)
{
int leftdeep = TreeDeep(T->lchild);
int rightdeep = TreeDeep(T->rchild);
deep = leftdeep+1 > rightdeep+1 ? leftdeep+1 : rightdeep+1;
}
return deep;
}
//樹的葉子結點為
int Leafcount(BiTree T, int &num) {//一般涉及到變化的都會取地址
if(T)
{
if(T->lchild ==NULL && T->rchild==NULL)
{
num++;
printf("%c ",T->data);
}
Leafcount(T->lchild,num);
Leafcount(T->rchild,num);
}
return num;
}
//樹的層次顯示 (利用隊列,先進先出的原則可以完美實現)
void LevelOrder_BiTree(BiTree T){
//用一個隊列保存結點信息,這里的隊列采用的是順序隊列中的數組實現
int front = 0;
int rear = 0;
BiTree BiQueue[MAXSIZE];
BiTree tempNode;
if(!IsEmpty_BiTree(&T)){
BiQueue[rear++] = T;
while(front != rear){//
//取出隊頭元素,並使隊頭指針向后移動一位
tempNode = BiQueue[front++];
//判斷左右子樹是否為空,若不為空,則加入隊列
if(!IsEmpty_BiTree(&(tempNode->lchild)))
BiQueue[rear++] = tempNode->lchild;
if(!IsEmpty_BiTree(&(tempNode->rchild)))
BiQueue[rear++] = tempNode->rchild;
printf("%c ",tempNode->data);
}
}
}
int main(void)
{
BiTree T;
BiTree *p = (BiTree*)malloc(sizeof(BiTree));
int deepth,num=0 ;
Create_BiTree(&T);//一般涉及到變化的都會取地址
printf("先序遍歷二叉樹:\n");
TraverseBiTree(T);
printf("\n");
printf("中序遍歷二叉樹:\n");
InOrderBiTree(T);
printf("\n");
printf("后序遍歷二叉樹:\n");
PostOrderBiTree(T);
printf("\n層次遍歷結果:");
LevelOrder_BiTree(T);
printf("\n");
deepth=TreeDeep(T);
printf("樹的深度為:%d",deepth);
printf("\n");
printf("樹的葉子結點為:");
Leafcount(T,num);
printf("\n樹的葉子結點個數為:%d",num);
return 0;
}
運行演示

線索二叉樹的中序遍歷
#include<iostream>
#include <stdlib.h>
using namespace std;
typedef struct BiThrNode
{
char data;
struct BiThrNode *lchild,*rchild; /*左右孩子指針*/
int LTag,RTag; /*左右標志*/
}BiThrNode,*BiThrTree;
BiThrTree pre;
void CreateBiTree(BiThrTree *T){
char ch;
ch = getchar();
//當輸入的是"#"時,認為該子樹為空
if(ch == '#')
*T = NULL;
//創建樹結點
else{
*T = (BiThrTree)malloc(sizeof(struct BiThrNode));
(*T)->data = ch; //生成樹結點
//生成左子樹
CreateBiTree(&(*T)->lchild);
//生成右子樹
CreateBiTree(&(*T)->rchild);
}
}
/*以結點p為根的子樹中序線索化*/
void InThreading(BiThrTree p)
{
/*pre是全局變量,初始化時其右孩子指針為空,便於在樹的最左點開始建線索*/
if(p)
{
InThreading(p->lchild); /*左子樹遞歸線索化*/
if(!(p->lchild) ) /*p的左孩子為空*/
{
p->LTag=1; /*給p加上左線索*/
p->lchild=pre; /*p的左孩子指針指向pre(前驅)*/
}
else
{
p->LTag=0;
}
if(!(pre->rchild) ) /*pre的右孩子為空*/
{
pre->RTag=1; /*給pre加上右線索*/
pre->rchild=p; /*pre的右孩子指針指向p(后繼)*/
}
else
{
pre->RTag=0;
}
pre=p; /*保持pre指向p的前驅*/
InThreading(p->rchild); /*右子樹遞歸線索化*/
}
}
/*帶頭結點的中序線索化*/
void InOrderThreading(BiThrTree &Thrt,BiThrTree T)
{
/*中序遍歷二叉樹T,並將其中序線索化,Thrt指向頭結點*/
Thrt=new BiThrNode; /*建頭結頭*/
Thrt->LTag=0; /*頭結點有左孩子,若樹非空,則其左孩子為樹根*/
Thrt->RTag=1; /*頭結點的右孩子指針為右線索*/
Thrt->rchild=Thrt; /*初始化時右指針指向自己*/
if(!T) Thrt->lchild=Thrt; /*若樹為空,則左指針也指向自己*/
else
{
Thrt->lchild=T; pre=Thrt; /*頭結點的左孩子指向根,pre初值指向頭結點*/
InThreading(T); /*調用上述算法,對以T為根的二叉樹進行中序線索化*/
pre->rchild=Thrt; /*算法結束后,pre為最右結點,pre的右線索指向頭結點*/
pre->RTag=1;
Thrt->rchild=pre; /*頭結點的右線索指向pre*/
}
}
/*遍歷中序線索二叉樹*/
void InOrderTraverse_Thr(BiThrTree T)
{
/*T指向頭結點,頭結點的左鏈lchild指向根結點*/
/*中序遍歷二叉線索樹T的非遞歸算法,對每個數據元素直接輸出*/
BiThrTree p=T->lchild; /*p指向根結點*/
while(p!=T)
{
while(p->LTag == 0) /*沿左孩子向下*/
{
p=p->lchild;
}
cout<<p->data<<" "; /*訪問其左子樹為空的結點*/
while(p->RTag == 1 && p->rchild!=T) /*沿右線索訪問后繼結點*/
{
p=p->rchild;
cout<<p->data<<" ";
}
p=p->rchild;
}
cout<<p->data;
}
int main()
{
BiThrTree T;
BiThrTree Thrt;
cout<<"Input the Threaded BinaryTree 's node:"<<endl;
CreateBiTree(&T);
InOrderThreading(Thrt,T); /*帶頭結點的中序線索化*/
cout<<"InOrderTraverse_Thr:"<<endl;
InOrderTraverse_Thr(T); /*遍歷中序線索二叉樹*/
return 0;
}
運行演示

二叉樹結構圖

參考文獻
- 數據結構-用C語言描述(第二版)[耿國華]