二叉树的基本操作

来源:互联网 发布:淘宝男生服装店推荐 编辑:程序博客网 时间:2024/05/17 19:22


// 二叉树.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "malloc.h"
#include<stdlib.h>
#include<stdio.h>
typedef struct BiTNode//二叉树结点
{
 int data;
 struct BiTNode *lchild,*rchild,*next;//next指针用于栈结构
}BiTNode,*BiTree;
/////////////链式栈////////////////
typedef struct  //链式栈
{
 struct BiTNode * top;
}LiStack;
void InitStack(LiStack &S)
{//
 S.top=NULL;
}
bool StackEmpty(LiStack S)
{
 if (S.top==NULL)
  return true;   //空
 else
  return false;
}

void Push(LiStack &S,BiTNode* &p)

 if (!p)
  return ;
 p->next=S.top;
 S.top=p; 
}
bool Pop(LiStack &S,BiTNode* &p)
{
 if (StackEmpty(S))
  return false;
 p=S.top;
 S.top=p->next;
 return true;
};
bool GetTop(LiStack S,BiTNode* &p)
{
 if (StackEmpty(S))
  return false;
 p=(BiTNode*)malloc(sizeof(BiTNode));
 memcpy(p,S.top,sizeof(BiTNode));
 return true;
}
///////////链式队列///////////////
typedef struct// 链式队列
{
 BiTNode *front,*rear;
}LiQueue;
void InitQueue(LiQueue &Q)
{
 Q.front=Q.rear=(BiTNode*)malloc(sizeof(BiTNode));//建立头结点
 Q.front->next=NULL; 
}
bool QueueEmpty(LiQueue Q)
{
 if (Q.rear==Q.front)
  return true;
 else
  return false;
}
void EnQueue(LiQueue &Q,BiTNode* &p)
{
 Q.rear->next=p;//插入到链尾
 Q.rear=p;
}
bool DeQueue(LiQueue &Q,BiTNode* &p)
{//Q.front一直指向头结点
 if (QueueEmpty(Q))//空队
  return false;

 p=Q.front->next;
 Q.front->next=p->next;
   
 if (Q.rear==p)//若队列中只有一个结点,删除后变空
  Q.rear=Q.front;
 return true;
}
////////////////////////////////
void InitBiT(BiTree &T)
{//链式二叉树
 T=NULL;
}
void CreateBiT(BiTree &T,int key[],int &i,int n)//先序建立二叉树
{//int key[]={1,2,3,0,0,4,0,0,5,6,0,0,7,0,0}
 //i表示当前被添加的结点序号 0~n-1;
 if(i<n)
 {
  if(key[i]==0)
  {
   T=NULL;i++;
  }
  else
  {
   T=(BiTree)malloc(sizeof(BiTNode));
   if (!T)
    printf("%s\n","overflow");
   T->data=key[i++];
   CreateBiT(T->lchild,key,i,n);
   CreateBiT(T->rchild,key,i,n);
  }
 }
}
void visit(BiTNode *p)
{
 printf("%d ",p->data);
}
void PreOrder(BiTree T)
{//
 if(T!=NULL)
 {
  visit(T);
  PreOrder(T->lchild);
  PreOrder(T->rchild);
 }
}
void InOrder(BiTree T)
{//
 if(T!=NULL)
 {
  
  InOrder(T->lchild);
  visit(T);
  InOrder(T->rchild);
 }
}
void PostOrder(BiTree T)
{
 if(T!=NULL)
 {
  PostOrder(T->lchild);
  PostOrder(T->rchild);
  visit(T);
 }
}
void PreOrder2(BiTree T)//先序非递归算法
{
 LiStack S;
 InitStack(S);
   
 BiTNode* p=T;
 while(p || !StackEmpty(S))
 {
  if (p)//访问根节点,右孩子入栈
  {
   visit(p);
   Push(S,p->rchild);
   p=p->lchild;
  }
  else
  {
   Pop(S,p);
  }
 }
}
void InOrder2(BiTree T)//中序非递归算法
{
 LiStack S;//需要借助一个栈
 InitStack(S);
 BiTNode *p=T;
 while (p || !StackEmpty(S))
 {
  if (p)//根指针进栈,遍历左子树
  {   
   Push(S,p);
   p=p->lchild;//每遇非空二叉树先向左走
  }
  else
  {
   Pop(S,p); visit(p);//退栈,访问根节点
   p=p->rchild;//此处p必须非空。
  }
 }
}
void PostOrder2(BiTree T)//后序遍历非递归
{
 LiStack S;//需要借助一个栈
 InitStack(S);

 BiTNode *p=T,*r=NULL;
 while(p || !StackEmpty(S))
 {
  if (p) //走到最左边
  {
   Push(S,p);
   p=p->lchild;
  }
  else
  {
   GetTop(S,p);
   if (p->rchild && p->rchild!=r)//还有右子树,并且右子树已经被访问过
   {
    p=p->rchild;//转向右
    Push(S,p);//压入栈
    p=p->lchild; //再走到最左
   }
   else
   {
    Pop(S,p);visit(p);//访问该结点
                r=p;//记录最近访问过的结点;
    p=NULL;//
   }//else
  }//else
 }
}
void LevelOrder(BiTree T)
{//层次遍历  //需要一个队列
 if(!T)
  return;
 LiQueue Q;
 InitQueue(Q);
 BiTNode* p=T;
 EnQueue(Q,p);//根节点归队
 while(!QueueEmpty(Q))
 {
  DeQueue(Q,p);
  visit(p);
  if (p->lchild)
   EnQueue(Q,p->lchild);
  if (p->rchild)
   EnQueue(Q,p->rchild);
 }
}
int SumBiTDegree2(BiTree T,int &Sum)
{//统计二叉树中度为2的结点个数
 if(T!=NULL)
 {
  if (T->lchild && T->rchild)
   Sum++;
  SumBiTDegree2(T->lchild,Sum);//统计左子树度为2的结点个数
  SumBiTDegree2(T->rchild,Sum);//统计右子树度为2的结点个数
 }
 return Sum;
}
int SumLeaf(BiTree T,int &Sum)//叶子结点个数
{
 if(T!=NULL)
 {
  if (T->lchild==NULL && T->rchild==NULL)
   Sum++;
  SumLeaf(T->lchild,Sum);//统计左子树度为2的结点个数
  SumLeaf(T->rchild,Sum);//统计右子树度为2的结点个数
 }
 return Sum;
}
int BiTHeight(BiTree T,int &height)
{//统计二叉树高度
 height=0;
 if(T)
 {
  int height1,height2;
  BiTHeight(T->lchild,height1);
  BiTHeight(T->rchild,height2);
  height= 1+(height1>height2 ?height1:height2);
 }
 return height;
}
int NodeLevel(BiTree T,int key,int &level,bool &flag)
{//计算结点所在层次
    if (flag)
  return level;
 if(T)
 {
  level++;
  if (T->data==key)
  {
   flag=true;//找到了 
   return level;
  }
  else
  {
   NodeLevel(T->lchild,key,level,flag);
   NodeLevel(T->rchild,key,level,flag);
   if (!flag)//如果左右子树都没有该结点
    level--;
  }
 }
 return level;
}
int _tmain(int argc, _TCHAR* argv[])
{
    BiTree T;
 InitBiT(T);
 
 int key[]={1,2,3,0,0,4,0,0,5,6,0,0,7,8,0,0,0,0};
 int i=0;
 CreateBiT(T,key,i,18);

 PreOrder(T);
 printf("\n");

    InOrder(T);
 printf("\n");
//////////////////////////////////////////////////////////////////////////
 int Sum=0;
 SumBiTDegree2(T,Sum);
 printf("度为2的结点个数:%d\n",Sum);
/////////////////////////////////////////////////////////////////////////////
 Sum=0;
 SumLeaf(T,Sum);
 printf("叶子结点个数:%d\n",Sum);
/////////////////////////////////////////////////////////////////////////
 int height=0;
 BiTHeight(T,height);
 printf("二叉树的高度%d\n",height);
//////////////////////////////////////////////////////////////////////////
 int level=0;bool flag=false;
 int node=8;
    NodeLevel(T,node,level,flag);
 printf("结点%d所在层次为%d\n",node,level);
 return 0;
}


0 0
原创粉丝点击