二叉树算法(数据结构)

来源:互联网 发布:余文乐有淘宝店吗 编辑:程序博客网 时间:2024/04/28 19:47

本文中给出了二叉树相关的算法及操作,主要包括以下内容:

1,创建二叉树

2,先序遍历(递归) 

3,中序遍历(递归) 

4,后序遍历(递归)

5,先序遍历(非递归)

6,中序遍历(非递归)  

7,后序遍历(非递归) 

 8,层序遍历

9,叶子个数

10,二叉树深度 

11,二叉树宽度

12,结点交换


下面的代码经过了实例测试,是可以运行的代码,供大家参考:

#include <stdio.h>#include <malloc.h>#include <stdlib.h>#include <iostream>#include <queue>#include <stack>using namespace std;typedef struct TNode{      char data;      struct TNode*lchild,*rchild;}TNode,*Tree;Tree Creat( )//按先序序列建立二叉树{//example:124##5##36##7##         Tree T; char ch; printf("input the node:");         scanf("%c",&ch); fflush(stdin);         if(ch=='#')                  T=NULL;         else        {                 T=(TNode*)malloc(sizeof(TNode));                 T->data=ch;                 T->lchild=Creat();                 T->rchild=Creat();        }        return T; }void PreOrder(Tree T)//先序遍历————递归{             TNode *p=T;         if (p != NULL)         {                printf("   %c",p->data);               PreOrder(p->lchild ) ;                 PreOrder(p->rchild ) ;          }}void InOrder(Tree T)//中序遍历——递归{           TNode *p=T;        if (p != NULL)        {                   InOrder( p-> lchild ) ;                   printf("   %c", p ->data);                   InOrder(p-> rchild ) ;         }}void PostOrder(Tree T)//后序遍历——递归{            TNode *p=T;        if (p != NULL){                   PostOrder( p-> lchild ) ;                   PostOrder( p-> rchild ) ;                   printf("   %c", p ->data);         }}void LayerOrder(Tree T)//层序遍历{         TNode *p=T; if(T==NULL)return; queue<Tree>Q; Q.push(T); int Qsize=Q.size(); while(!Q.empty()) { p=Q.front(); Qsize=Q.size(); Q.pop(); Qsize=Q.size(); cout<<p->data; if(p->lchild!=NULL)Q.push(p->lchild); if(p->rchild!=NULL)Q.push(p->rchild); Qsize=Q.size(); }}Tree findNode(Tree t,char x)//查找数据{           Tree p;           if(!t) return(NULL);           else if(t->data==x)return t;           else           {                    p=findNode(t->lchild,x);                    if(!p)p=findNode(t->rchild,x);                    return(p);           }}int Leaf(Tree T)//叶子结点个数{         TNode *p=T;         if(p != NULL)         {                 if((p->lchild==NULL)&&(p->rchild==NULL))                        return 1;                 else                         return(Leaf(p->lchild)+Leaf(p->rchild));         }         else                return 0;}int Depth(Tree T)//树的深度{          TNode *p=T;          int l,r;          if(!p)                   return 0;          else           {                  l=Depth(p->lchild);                   r=Depth(p->rchild);                  if(l>r)                           return l+1;                   else                            return r+1;          }    }//求二叉树的宽度   int Width(Tree pRoot)  {      if (pRoot == NULL)      {          return 0;      }      int nLastLevelWidth = 0;//记录上一层的宽度       int nTempLastLevelWidth = 0;      int nCurLevelWidth = 0;//记录当前层的宽度       int nWidth = 1;//二叉树的宽度   queue<Tree> myQueue;      myQueue.push(pRoot);//将根节点入队列       nLastLevelWidth = 1;          Tree pCur = NULL;      while (!myQueue.empty())//队列不空       {          nTempLastLevelWidth = nLastLevelWidth;          while (nTempLastLevelWidth != 0)          {              pCur = myQueue.front();//取出队列头元素               myQueue.pop();//将队列头元素出对               if (pCur->lchild != NULL)              {                  myQueue.push(pCur->lchild);              }              if (pCur->rchild != NULL)              {                  myQueue.push(pCur->rchild);              }              nTempLastLevelWidth--;          }          nCurLevelWidth = myQueue.size();          nWidth = nCurLevelWidth > nWidth ? nCurLevelWidth : nWidth;          nLastLevelWidth = nCurLevelWidth;      }      return nWidth;  }  void Change(Tree T)//结点交换{          TNode *p=T;           if(p!=NULL)           {                    p=T->lchild;                    T->lchild=T->rchild;                    T->rchild=p;                    Change(T->lchild);                    Change(T->rchild);          }}void InOrderTraverse(Tree T)//非递归中序遍历{stack<Tree> Stack;if(!T){printf("空树!\n");return;}while(T || !Stack.empty()){while(T){Stack.push(T);T=T->lchild;}T=Stack.top();Stack.pop();printf("%c",T->data);T=T->rchild;}                                                                                                                                   }void PreOrderTraverse(Tree T)//非递归先序遍历{stack<Tree> Stack;if(!T){printf("空树!\n");return;}while(T || !Stack.empty()){while(T){Stack.push(T);printf("%c",T->data);T=T->lchild;}T=Stack.top();Stack.pop();    T=T->rchild;}                                                                                                                                   }void PostOrderTraverse(Tree T)//非递归后续遍历{stack<Tree> s;    Tree cur;                      //当前结点     Tree pre=NULL;                 //前一次访问的结点     s.push(T);    while(!s.empty())    {        cur=s.top();        if((cur->lchild==NULL&&cur->rchild==NULL)||(pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))        {            cout<<cur->data<<" ";  //如果当前结点没有孩子结点或者孩子节点都已被访问过 s.pop();//访问完结点后才出栈            pre=cur;         }        else        {            if(cur->rchild!=NULL)//先将右孩子入栈,先进后出                s.push(cur->rchild);            if(cur->lchild!=NULL)//后进先出                    s.push(cur->lchild);        }    }                                                                                                               }void ShowMenu(){           printf("\t\t\t****二叉树算法**** \n");                                          printf("\t\t\t~~~~~~~~~~~~~~~~ \n");                             printf("\t\t\t#1.  先序遍历(递归)   #\n");           printf("\t\t\t#2.  中序遍历(递归)   #\n");            printf("\t\t\t#3.  后序遍历(递归)   #\n");    printf("\t\t\t#4.  先序遍历(非递归)   #\n");           printf("\t\t\t#5.  中序遍历(非递归)   #\n");            printf("\t\t\t#6.  后序遍历(非递归)   #\n");            printf("\t\t\t#7.  层序遍历   #\n");            printf("\t\t\t#8.  叶子个数   #\n");           printf("\t\t\t#9. 二叉树深度 #\n");   printf("\t\t\t#10. 二叉树宽度\n");           printf("\t\t\t#11.  结点交换   #\n");           printf("\t\t\t#0.  退出程序   #\n");           printf("\t\t\t~~~~~~~~~~~~~~~~\n");}int main(){    Tree T;int  t,  l,  d , w;printf("\t\t\t****创建二叉树****\n");printf("◤请先序输入树的各元素,用#表示空结点:\n");T=Creat();while(1){    ShowMenu();printf("◤请您选择(0-11):");scanf("%d",&t);switch(t){   case 1: printf("  ◎先序遍历(递归):");PreOrder(T);printf("\n"); break;     case 2: printf("  ◎中序遍历(递归):");InOrder(T);printf("\n"); break;     case 3: printf("  ◎后序遍历(递归):");PostOrder(T);  printf("\n"); break;case 4: printf("  ◎先序遍历(非递归):");PreOrderTraverse(T);printf("\n"); break;     case 5: printf("  ◎中序遍历(非递归):");InOrderTraverse(T);printf("\n"); break;     case 6: printf("  ◎后序遍历(非递归):");PostOrderTraverse(T);  printf("\n"); break;case 7:printf("   ◎层序遍历:");LayerOrder(T);  printf("\n"); break;                       case 8: printf("  ◎叶子结点个数:");l=Leaf(T);printf(" %d 个\n",l); break;case 9: printf("  ◎二叉树深度:");d=Depth(T);printf(" %d\n",d); break;case 10: printf("  ◎二叉树宽度:");w=Width(T);printf("%d\n",w);break;case 11: printf("  █各结点已交换█");Change(T);printf("\n",d); break;                                         case 0: printf("\t\t******谢谢使用,再见!******\n");return 0;break;default: printf("※输入出错!!!请重输:\n");}}}



原创粉丝点击