树和二叉树



//BiTree.h

struct BiTNode   //采用二叉链表存储结构
{
 char data;
 struct BiTNode* lchild;
 struct BiTNode* rchild;
}BiTNode;


struct BiTNode* CreateBiTree();  
int DestroyBiTree(struct BiTNode* T);
int visit(char elem);

//递归遍历算法
int PreOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem));
int InOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem));
int PostOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem));

//非递归遍历算法
void PreOrderTraverse(struct BiTNode* T, int (*visit)(char elem));
void InOrderTraverse(struct BiTNode* T, int (*visit)(char elem));
void PostOrderTraverse(struct BiTNode* T, int (*visit)(char elem));


//stack.h 堆栈数据结构,用于非递归算法中的附加空间

#define STACK_SIZE 256

struct stack
{
 struct BiTNode* elem[STACK_SIZE];
 int top;  //top总是指向栈顶元素的上一个元素
 int bottom; //恒0
};
void initStack(struct stack* s);
struct BiTNode* getTop(struct stack* s);
struct BiTNode* pop(struct stack* s);
void push(struct stack* s,struct BiTNode* p);
int isEmpty(struct stack* s);


//stack.c 堆栈的实现

#include<stdio.h>
#include<string.h>
#include "stack.h"

//初始化堆栈为0,栈指针为0
void initStack(struct stack* s)
{
 memset(s->elem,0,STACK_SIZE);
 s->top = s->bottom = 0;
}

//获取栈顶元素,栈顶指针不变
struct BiTNode* getTop(struct stack* s)
{
 return s->elem[s->top-1];
}

//弹出&返回栈顶元素
struct BiTNode* pop(struct stack* s)
{
 if(s->top == s->bottom)  //若栈空
 {
  printf("Stack is empty!
");
  return 0;
 }

 --s->top;
 return s->elem[s->top];
}

//将pB指针压入栈中
void push(struct stack* s,struct BiTNode* pB)
{
 if(s->top<STACK_SIZE)  //栈未满
 {
  s->elem[s->top] = pB;
  ++s->top;
 }
 else  
  printf("Stack is full!
");
}

//判断栈是否为空,空返回非0
int isEmpty(struct stack* s)
{
 return s->top == s->bottom;
}


//BiTree.c 二叉树创建、销毁、递归算法实现

#include<stdio.h>
#include<malloc.h>
#include "BiTree.h"
#include "stack.h"

struct BiTNode* CreateBiTree() //采用先序递归方法创建一棵二叉树
{
 struct BiTNode* T;
 char ch,tmp;
 printf("please input the value of the node:
");
 scanf("%c",&ch);
 tmp = getchar(); //忽略回车符
 if(ch == ''&'')    //输入&符号表示此节点为空
 {
  printf("Null BiTreeNode Created!
");
  T = NULL;
  return NULL;
 }
 
 T = (struct BiTNode *)malloc(sizeof(BiTNode)); //为当前节点分配内存
 if(!T)
 {
  printf("Allocate memory failed!
");
  return NULL;
 }

 T->data = ch;  //为当前节点赋值

 T->lchild = CreateBiTree();  //递归创建左子树
 T->rchild = CreateBiTree(); //递归创建右子树

 return T; 
}

//销毁二叉树,销毁成功返回0,错误返回1
int DestroyBiTree(struct BiTNode* T)
{
 if(T)
 {
  struct BiTNode* lchild = T->lchild;
  struct BiTNode* rchild = T->rchild;
  free(T);
  if(0 == DestroyBiTree(lchild))
  {
   if(0 == DestroyBiTree(rchild))
    return 0;
   else
    return 1;
  }
 } 
 return 0;
}
//访问节点元素
int visit(char elem)
{
 if(elem == ''&'')
  return 1;
 printf("%c ",elem);
 return 0;
}

//先序遍历递归算法,返回值为0表示遍历成功,1为失败
int PreOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem))
{
 if(T)
 {
  if(0 != visit(T->data))  //访问根节点
   return 1;

  if(T->lchild)
  {
   if(0 != InOrderTraverse_R(T->lchild,visit)) //递归遍历左子树
    return 1;
  }
  
  if(T->rchild)
  {
   if(0 != InOrderTraverse_R(T->rchild, visit)) //递归遍历右子树
    return 1;
  }  
 } 
 return 0;   
}

//中序遍历递归算法,返回值为0表示遍历成功,1为失败
int InOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem))
{
 if(T)
 {
  if(T->lchild)
  {
   if(0 != InOrderTraverse_R(T->lchild,visit)) //递归遍历左子树
    return 1;
  }
  
  if(0 != visit(T->data))  //访问根节点
   return 1;
  
  if(T->rchild)
  {
   if(0 != InOrderTraverse_R(T->rchild,visit)) //递归遍历右子树
    return 1;
  }  
 } 
 return 0;  
}

//后序遍历递归算法,返回0表示遍历成功,1为失败
int PostOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem))
{
 if(T)
 {
  if(T->lchild)
  {
   if(0 != PostOrderTraverse_R(T->lchild,visit)) //递归遍历左子树
    return 1;
  }
  
  if(T->rchild)
  {
   if(0 != PostOrderTraverse_R(T->rchild,visit)) //递归遍历右子树
    return 1;
  }
  
  if(0 != visit(T->data))  //访问根节点
   return 1;
 } 
 return 0;     
}

//先序遍历非递归算法
void PreOrderTraverse(struct BiTNode* T, int (*visit)(char elem))
{
 struct stack ss;
 struct BiTNode* p = T;
 initStack(&ss); 
 while(p||!isEmpty(&ss))
 {
  if(p)
  {
   visit(p->data);
   push(&ss,p);
   p=p->lchild;
  }
  else
  {
   p = getTop(&ss);
   pop(&ss);
   p = p->rchild;
  }
 }
}

//中序遍历非递归算法
void InOrderTraverse(struct BiTNode* T, int (*visit)(char elem))
{
 struct stack ss;
 struct BiTNode* p;
 initStack(&ss);

 push(&ss,T);
 while(!isEmpty(&ss))
 {
  while(p = getTop(&ss)) 
   push(&ss,p->lchild); //向左走到尽头
  p = pop(&ss);  //空指针退栈

  if(!isEmpty(&ss))
  {
   p = pop(&ss);
   visit(p->data);  //访问节点
   push(&ss,p->rchild); //向右一步
  }
 }
}

//后序遍历非递归算法
void PostOrderTraverse(struct BiTNode* T, int (*visit)(char elem))
{
 struct stack ss;
 struct BiTNode* p = T;
 struct BiTNode* q;
 initStack(&ss); //初始化空栈

 while(p || !isEmpty(&ss))
 {
  if(p)
  {
   push(&ss,p);
   p = p->lchild;
  }
  else
  {
   p =getTop(&ss);
   if(p)
   {
    push(&ss,NULL);
    p = p->rchild;
   }
   else
   {
    pop(&ss);
    q = pop(&ss);
    visit(q->data);
   }
  }
 }
}



//main.c 测试主程序

#include<stdio.h>
#include "BiTree.h"

int main()
{
 struct BiTNode* bt = 0;
 bt = CreateBiTree(bt);
 printf("先序遍历序列:
");
 PreOrderTraverse_R(bt,visit);
 printf("
中序遍历序列:
");
 InOrderTraverse_R(bt,visit);
 printf("
后序遍历序列:
");
 PostOrderTraverse_R(bt,visit);

 printf("
非递归先序遍历序列:
");
 PreOrderTraverse(bt,visit);

 printf("
非递归中序遍历序列:
");
 InOrderTraverse(bt,visit);

 printf("
非递归后序遍历序列:
");
 PostOrderTraverse(bt,visit);
 DestroyBiTree(bt);
 return 0;
}



查找结点



查找结点就是遍历二叉树中的每一个节点,逐个比较数据,当找到目标数据时将返回该数据所在结点的指针。


代码如下:
CBTType *TreeFindNode(CBTType *treeNode,DATA data)
{
 CBTType *ptr;
 if(treeNode==NULL)
 {
  return NULL;
 }else
 {
  if(treeNode->data==data)
  {
   return treeNode;
  }
  else        //分别向左右子树查找   
  {

   if(ptr=TreeFindNode(treeNode->left,data))  //左子树递归查找 
   {

    return ptr;
   }
   else if(ptr=TreeFindNode(treeNode->right,data))         //右子树递归查找 
   {
    return ptr;
   }
   else
   {
    return NULL;
   }
  }
 } 



输入参数treeNode为待查找的二叉树的根结点,输入参数data为待查找的结点数据。程序中首先判断根结点是否为空,然后根据数据判断是否为根结点,然后分别向左右子树进行查找,采用递归的方法进行查找,查找到该结点则返回结点对应的指针;如果全都查找不到,则返回NULL。



计算二叉树的深度

计算二叉树深度就是计算二叉树中结点的最大层数,这里往往需要采用递归算法来实现。



int TreeDepth(CBTType *treeNode)
{
 int depleft,depright;
 if(treeNode==NULL)
 {
  return 0;     //结点为空的时候,深度为0
 }
 else
 {
  depleft=TreeDepth(treeNode->left);  //左子树深度(递归调用)
  depright=TreeDepth(treeNode->right);         //右子树深度(递归调用)
  if(depleft)
  {
   return ++depleft;
  }
  else
  {
   return ++depright;
  }
 }
}

输入参数treeNode为待计算的二叉树的根结点。首先判断根节点是否为空,然后分别按照递归调用来计算左子树深度和右子树深度,从而完成整个二叉树深度的计算。  




版权声明:

原文地址:https://www.cnblogs.com/walccott/p/4957062.html