回 帖 发 新 帖 刷新版面

主题:重发二叉树的各种算法(顶的加分)

包括了各种遍历,搜索路径,交换子树,求树的深度,叶子树
还有线索二叉树的生成。用相对符合课本的形式写的。
#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAX 100
#define MAXSIZE 100
typedef int Status;
typedef char ElemType;
typedef struct BitNode/* 定义二叉树机构 */
{
  ElemType data;
  struct BitNode *lchild,*rchild;
}BitNode,*BiTree;
typedef struct Queue/* 定义队列 */
{
   BiTree *base;
   int front,rear;
}Queue;
Status InitQueue(Queue *Q)/* 初始化队列 */
{
  Q->base=(BiTree *)malloc(MAXSIZE*sizeof(BiTree));
  if(!Q->base) return ERROR;
  Q->front=Q->rear=0;
  return OK;
}
Status QueueEmpty(Queue *Q)/* 队列判空 */
{
  if(Q->front==Q->rear) return 1;
  return 0;
}
Status EnQueue(Queue *Q,BiTree e)/* 入队 */
{
   if((Q->rear+1)%MAXSIZE==Q->front) return ERROR;
   Q->base[Q->rear]=e;
   Q->rear=(Q->rear+1)%MAXSIZE;
   return OK;
}
Status DeQueue(Queue *Q,BiTree *e)/* 出队 */
{
  if(Q->rear==Q->front) return ERROR;
  (*e)=Q->base[Q->front];
  Q->front=(Q->front+1)%MAXSIZE;
  return OK;
}

Status PrintElement(ElemType e)/* 最简单的Visit函数 */
{
  printf("%c",e);
  return OK;
}
Status CreateBiTree(BiTree *T)/* 创建二叉树 */
{
  ElemType ch;
  scanf("%c",&ch);
  if(ch==' ') (*T)=NULL;
  else
  {
    if(!((*T)=(BitNode *)malloc(sizeof(BitNode)))) exit (OVERFLOW);
    (*T)->data=ch;
    (*T)->lchild=(*T)->rchild=NULL;
    CreateBiTree(&((*T)->lchild));
    CreateBiTree(&((*T)->rchild));
  }
return OK;
}
Status PreOrderTraverse(BiTree T,Status(*Visit)(ElemType e))/* 先序遍历 */
{
    if(T)
    {
        if(!Visit(T->data)) exit(ERROR);
        PreOrderTraverse(T->lchild,Visit);
        PreOrderTraverse(T->rchild,Visit);
    }
    return OK;
}
Status InOrderTraverse(BiTree T,Status(*Visit)(ElemType e))/* 中序遍历 */
{
if(T)
{
   InOrderTraverse(T->lchild,Visit);
   if(!Visit(T->data)) exit(ERROR);
   InOrderTraverse(T->rchild,Visit);
}
return OK;
}
Status PostOrderTraverse(BiTree T,Status(*Visit)(ElemType e))/* 后序遍历 */
{
  if(T)
  {
    PostOrderTraverse(T->lchild,Visit);
    PostOrderTraverse(T->rchild,Visit);
    if(!Visit(T->data)) exit(ERROR);
  }
  return OK;
}
Status PreOrderTraverse_None_Recursion(BiTree T,Status(*Visit)(ElemType e))/* 先序非递归 */
{   
    BiTree p=T,Stack[MAX];
    int top=0;
    while (p|| top>0)
    {
        while (p)           
        {
            if(!Visit(p->data)) exit(ERROR);
            Stack[top++]=p;
            p=p->lchild;       
        }     
        if (top>0)        
        {
            p=Stack[--top];
            p=p->rchild;        
       }               
    }
    return OK;
}

回复列表 (共18个回复)

沙发

Status InOrderTraverse_None_Recursion(BiTree T,Status(*Visit)(ElemType e))/* 中序非递归 */
{
    BiTree p=T,Stack[MAX];
    int top=0;
    while (p!=NULL || top>0)
    {
        while (p!=NULL)            
        {
            Stack[top++]=p;
            p=p->lchild;
        }    
        
        if (top>0)
        {
            p=Stack[--top];
            if(!Visit(p->data)) exit(ERROR);      
            p=p->rchild;          
        }    
    }
  return OK;
}
Status PostOrderTraverse_None_Recursion(BiTree T,Status(*Visit)(ElemType e))/* 后序非递归 */
{
    BiTree p=T, Stack[MAX];
    int tag[MAX];
    int top=0;
    do
    {
        while(p != NULL)
        {
            Stack[top++] = p;
            tag[top] = 0;
            p = p->lchild;
        }             
        if(top > 0)
        {
            if(!tag[top])
            {
                p = Stack[top-1];
                p = p->rchild;
                tag[top] = 1;
            }
            else if (!Visit(Stack[--top]->data)) exit (ERROR);
        }
    } while((p != NULL)||(top >0));
    return OK;
}     
Status LevelOrderTraverse(BiTree T,Status(*Visit)(ElemType e))/* 层次遍历 */
{
  BiTree p;
  Queue *Q=(Queue *)malloc(sizeof(Queue));
  if(!T) return ERROR;
  if(!InitQueue(Q)) exit(OVERFLOW) ;
  EnQueue(Q,T);
  while(!QueueEmpty(Q))
  {
    DeQueue(Q,&p);
    if(!Visit(p->data)) exit(ERROR);
    if(p->lchild) EnQueue(Q,p->lchild);
    if(p->rchild) EnQueue(Q,p->rchild);
  }
  return OK;
}
Status DestroyBiTree(BiTree *T)/*销毁二叉树*/
{
  if(*T)
  {
     DestroyBiTree(&(*T)->lchild);
     DestroyBiTree(&(*T)->rchild);
     free(*T);
     (*T)=NULL;
  }
  return OK;
}
int BiTreeDepth(BiTree T)/* 求树的深度 */
{
  int dep1,dep2;
  if(T==NULL) return 0;
  else
  {
    dep1=BiTreeDepth(T->lchild);
    dep2=BiTreeDepth(T->rchild);
     if(dep1>dep2) return dep1+1;
     else return dep2+1;
  }
}
int Leaf_Count(BiTree T)/* 求叶子数 */

{
  if(!T) return 0;
  else if(!T->lchild&&!T->rchild) return 1;
  else return Leaf_Count(T->lchild)+Leaf_Count(T->rchild);
}
void Bitree_Revolute(BiTree T)/* 交换所有左右子树 */
{
  BiTree temp;
  temp=T->lchild;/*swap(T->lchild,T->rchild)*/
  T->lchild=T->rchild;
  T->rchild=temp;/*end swap*/
  if(T->lchild) Bitree_Revolute(T->lchild);
  if(T->rchild) Bitree_Revolute(T->rchild);
}

板凳

Status FindNode(BitNode *T, char e)/* 搜索结点并返回路径 */
{
    BitNode *p=T, *Stack[MAX];/* p表示当前结点,栈Stack[]用来存储结点  */
    int tag[MAX];
    int top=0, i;
    do
    {
        while(p != NULL)/* 先处理结点的左孩子结点,把所有左孩子依次入栈  */
        {
            Stack[top++] = p;
            tag[top] = 0;
            p = p->lchild;
        }             
        if(top > 0) /* 所有左孩子处理完毕后  */
        {
            if(!tag[top]) /* 如果当前结点的右孩子还没被访问  */
            {
                p = Stack[top-1];/* 输出栈顶结点 ,但不退栈 ,因为要先输出其孩子结点  */
                p = p->rchild; /* 处理其右孩子结点  */
                tag[top] = 1; /* 表示栈中top位置存储的结点的右孩子被访问过了,下次轮到它退栈时可直接输出  */
            }
            else /* 如果该结点的左右孩子都被访问过了  */
            {   
                if(Stack[top-1]->data==e)
                {
                    printf("The path: ");
                    for(i=0; i<top; i++) /* 输出从栈底到栈顶的元素构成路径  */
                        printf("%c", Stack[i]->data);
                    return OK;
                }  
                top--;           
            }
        }
    } while((p != NULL)||(top >0));
    return ERROR;
}    
void welcome()
{
   printf("A.CreateBiTree\n");
   printf("B.PreOrderTraverse\n");
   printf("C.InOrderTraverse\n");
   printf("D.PostOrderTraverse\n");
   printf("E.PreOrderTraverse_None_Recursion\n");
   printf("F.InOrderTraverse_None_Recursion\n");
   printf("G.PostOrderTraverse_None_Recursion\n");
   printf("H.LevelOrderTraverse\n");
   printf("I.DestroyBiTree\n");
   printf("J.BiTreeDepth\n");
   printf("K.Leaf_Count\n");
   printf("L.Bitree_Revolute\n");
   printf("M.Find_Node\n");
   printf("Q.Quit the System\n");
}
void Action(BiTree T)
{
  char e;
  fflush(stdin);
  printf("Input a Data to Search:");
  e=getchar();
  if(!FindNode(T,e)) printf("Data Not Find");

}
void main()
{
  BitNode *T=NULL;
  char key;
   system("cls");
   welcome();
   while((key=getch())!='q')
   {
      switch(key)
      {   case 'a' :system("cls");CreateBiTree(&T);fflush(stdin);system("cls");welcome();break;
          case 'b' :system("cls");PreOrderTraverse(T,PrintElement);getch();system("cls");welcome();break;
          case 'c' :system("cls");InOrderTraverse(T,PrintElement);getch();system("cls");welcome();break;
          case 'd' :system("cls");PostOrderTraverse(T,PrintElement);getch();system("cls");welcome();break;
          case 'e' :system("cls");PreOrderTraverse_None_Recursion(T,PrintElement);getch();system("cls");welcome();break;
          case 'f' :system("cls");InOrderTraverse_None_Recursion(T,PrintElement);getch();system("cls");welcome();break;
          case 'g' :system("cls");PostOrderTraverse_None_Recursion(T,PrintElement);getch();system("cls");welcome();break;
          case 'h' :system("cls");LevelOrderTraverse(T,PrintElement);getch();system("cls");welcome();break;
          case 'i' :system("cls");DestroyBiTree(T);getch();system("cls");welcome();break;
          case 'j' :system("cls");printf("Depth=%d",BiTreeDepth(T));getch();system("cls");welcome();break;
          case 'k' :system("cls");printf("Leadf=%d",Leaf_Count(T));getch();system("cls");welcome();break;
          case 'l' :system("cls");Bitree_Revolute(T);printf("Revolute Success");getch();system("cls");welcome();break;
          case 'm' :system("cls");Action(T);getch();system("cls");welcome();break;
          default :;
      }
   }
}

3 楼

再来一个线索二叉树

#include "stdio.h"
#include "stdlib.h"
#include "malloc.h"
#define OK 1
#define ERROR 0
typedef int Status;
typedef int TElemType;
typedef enum {Link,Thread} PointerTag;/*枚举 Link==0:指针,Thread==1:线索*/
typedef struct BiThrNode/*定义线索二叉树*/
{
   TElemType data;
   struct BiThrNode *lchild,*rchild;
   PointerTag LTag,RTag;
}BiThrNode,*BiThrTree;
BiThrTree pre;
void InThreading(BiThrTree p)/*递归中序线索化二叉树*/
{
  if(p)
  {
   InThreading(p->lchild);/*左子树线索化*/
   if(!p->lchild)
   { p->LTag=Thread;p->lchild=pre; } /*前驱线索*/
   if(!pre->rchild)
   { pre->RTag=Thread;pre->rchild=p;}/*后继线索*/
   pre=p;/*保持pre指向p的前驱*/
   InThreading(p->rchild);/*右子树线索化*/
  }
}
Status PrintElement(TElemType e)/*最简单的Visit函数*/
{
  printf("%d",e);
  return OK;
}
Status CreateBiTree(BiThrTree *T)/*先序遍历建二叉树*/
{
  int dat;
  scanf("%d",&dat);
  if(!dat) (*T)=NULL;
  else
  {
    (*T)=(BiThrNode *)malloc(sizeof(BiThrNode));
    if(!(*T)) return ERROR;
    (*T)->data=dat;(*T)->LTag=(*T)->RTag=Link;
    (*T)->lchild=(*T)->rchild=NULL;
    CreateBiTree(&((*T)->lchild));/*创建左孩子*/
    CreateBiTree(&((*T)->rchild));/*创建右孩子*/
  }
return OK;
}
Status InOrderThreading(BiThrTree *Thrt,BiThrTree T)/*中序遍历二叉树T,并将其中序线索化,Thrt指向头节点*/
{
   (*Thrt)=(BiThrTree)malloc(sizeof(BiThrNode));
   if(!Thrt) return ERROR;
   (*Thrt)->LTag=Link;(*Thrt)->RTag=Thread;/*建头结点*/
   (*Thrt)->rchild=(*Thrt);/*右指针回指*/
   if(!T) (*Thrt)->lchild=(*Thrt);/*若二叉树空,则左指针回指,为了若T为空树是能结束循环*/
   else {
   (*Thrt)->lchild=T;
   pre=(*Thrt);
   InThreading(T);/*中序遍历进行中序线索化*/
   pre->rchild=(*Thrt);/*最后一个结点的右孩子线索化,因为pre=p */
   pre->RTag=Thread;
   (*Thrt)->rchild=pre;
   }
   return OK;
}

Status InOrderTraverse_Thr(BiThrTree T,Status (*Visit)(TElemType e))/*T指向头结点,头结点的左链lchild指向根结点,中序遍厉二叉树*/
/*道理同逆序*/
{
   BiThrTree p;
   p=T->lchild;/*p指向根结点*/
   while(p!=T)/*空树或遍厉结束时,p==T  */
   {
     while(p->LTag==Link) p=p->lchild;
     if(!Visit(p->data)) return ERROR;/*访问其左子树为空的结点*/
     while(p->RTag==Thread&&p->rchild!=T)
     {
       p=p->rchild;
       if(!Visit(p->data)) return ERROR;/*访问后继结点*/
     }
    p=p->rchild;
   }
  return OK;
}
Status InOrderTraverse_Thr_Reverse(BiThrTree T,Status (*Visit)(TElemType e))/*反向遍历*/
{
BiThrTree p;
p=T->rchild;
while(p!=T)
{
   while(p->RTag==Link) p=p->rchild;/*搜索至最右的结点*/
   if(!Visit(p->data)) return ERROR;/*访问其右子树为空的结点*/
   while(p->LTag==Thread&&p->lchild!=T)
   {
      p=p->lchild;
      Visit(p->data);
   }
   p=p->lchild;/*非叶子结点,首先找其左子树*/
}
}

void main()
{
   BiThrTree T,Thrt;
   CreateBiTree(&T);
   InOrderThreading(&Thrt,T);
   InOrderTraverse_Thr(Thrt,PrintElement);
   printf("\n");
   InOrderTraverse_Thr_Reverse(Thrt,PrintElement);
   getch();
}

4 楼

谢谢

5 楼


[size=6][/size][size=6]谢谢你的程序,在运行时怎么输入啊,我不会输入啊,希望你能帮助我一下,好吗[/size]

6 楼


不用线索二叉树那个,只要二叉树的基本操作那个就行,运行通过后我不会输入,帮我一下吧,大侠,我真的急用啊,谢谢了

7 楼


你的程序真的不错,呵呵

8 楼

给我回个内容吧,我急等着用啊,谢谢啊

9 楼

谢谢楼主的归纳啊。很全面,对我们学习是很有帮助的,顶一下

10 楼

支持

我来回复

您尚未登录,请登录后再回复。点此登录或注册