树的操作

来源:互联网 发布:行知实践园 编辑:程序博客网 时间:2024/06/05 17:41

#include<stdio.h>
#include<stdlib.h>
#include<iostream.h>
#define MAX 50
typedef char Elemtype ;
typedef int Status;
typedef struct BitNode
{
 Elemtype data;
 BitNode *Lchild,*Rchild;//左,右孩子指针
}BitNode, *BitTree;
typedef struct Lnode{
 char   data;
 struct  Lnode  *next;
}Lnode,*LinkList;//单向链表
void InitTree(BitTree *BT) 
{   //构造一个空二叉树
    BT=NULL;
}
//——————————创建二叉树————————————
int  CreateBitTree(BitTree &BT)
{//构造一个二叉树
 Elemtype ch;
 cin>>ch;
 if(ch=='#') BT=NULL;//建空树
 else
 {
  if(!(BT=(BitNode*)malloc(sizeof(BitNode))))
  {exit(1);}
  BT->data=ch;
  CreateBitTree(BT->Lchild);
  CreateBitTree(BT->Rchild);
 }
 return 1;
}
//——————————先序遍历二叉树————————————
void DLR(BitTree root)
{//递归方法先序遍历二叉树
 if(root!=NULL)
 {
  printf("%c  ",root->data);
  DLR(root->Lchild);
  DLR(root->Rchild);
  
 }
}
//——————————先序遍历二叉树的叶子结点——————————
void Preleaf(BitTree T){//先序遍历叶子结点,树
 if(T!=NULL){
  if(T->Lchild==NULL &&T->Rchild==NULL)
   printf("%c ",T->data);
  Preleaf(T->Lchild);
  Preleaf(T->Rchild);
 }
}
//——————————链表储存二叉树叶子结点——————————
void linkleaf(BitTree T,LinkList &p)
{
 LinkList r;
 if(T!=NULL){
  if(T->Lchild==NULL&&T->Rchild==NULL){
   r=(LinkList)malloc(sizeof(Lnode));
   r->data=T->data;
   r->next=NULL;
   while(p->next!=NULL){
    p=p->next;
   }
   p->next=r;
  }
  linkleaf(T->Lchild,p);
  linkleaf(T->Rchild,p);
 }
 
}

void printlink(LinkList &L)
{//打印叶子结点链表
 LinkList p;
 p=L;
 if(p==NULL) return;
 while(p->next!=NULL){
  p=p->next;
  printf("%c ",p->data);
  
 }
 printf("/n");

}
//——————————判断是否是完全二叉树————————————
Status Fultree(BitTree root) {
 BitTree queue[MAX];
 BitTree p; // 定义队列
 int rear = 0, front = 0;
 if (root != NULL) {
  queue[rear] = root;
  rear = (rear + 1) % MAX;
 }
 
 // 此while的作用是在根节点在队内的初始情况下开始 按层次遍历二叉树
 // 只遍历左右子树都有的节点 while结束时 p指向第一个例外节点
 while (rear != front) {
  p = queue[front];
  front = (front + 1) % MAX;
  
  // 当队不满,
  if ((rear + 1) %MAX != front && p->Lchild != NULL && p->Rchild != NULL)
  {
   
   queue[rear]= p->Lchild;
   rear = (rear + 1) % MAX;
   queue[rear] = p->Rchild;
   rear = (rear + 1) % MAX;
  } else
   break;
 }
 
 // 经前面的while,p肯定指向第一个没有双子的节点
 // 此时又分四种情况
 if (p->Lchild ==NULL && p->Rchild != NULL)
  return 0; // 第一种:有右无左 肯定不是完全二叉树
 
 else if (p->Lchild != NULL && (p->Lchild->Lchild != NULL || p->Lchild->Lchild != NULL))
  return 0; // 第二种:有左无右但左子树还有子树 排除
 
 // 第三种:有左无右 左也无子,
 // 但在继续按层次遍历过程中
 // 发现后来的某个节点有子树,排除
 else {
  while (rear != front) {
   p = queue[front];
   front = (front + 1) % MAX;
   
   if (p->Lchild != NULL|| p->Rchild != NULL)
    return 0;
  }
 }
 // 经过层层筛选,剩下的就是完全二叉树
 return 1;
}
//——————————判断是否是二叉排序树————————————
void SortTree(BitTree &T){  //判断是否是二叉排序树
 BitTree s[100];BitTree t[100];
 int top=0;int k=0;
 while(T!=NULL||top!=0){
  while(T){
   s[++top]=T;T=T->Lchild;
  }
  if(top!=0){
   t[k++]=s[top];
   T=s[top--]->Rchild;
  }
 }
 for(int i=0;i<k-1;i++)
  if(t[i]->data>=t[i+1]->data){printf("不是二叉排序树/n");return;}
 printf("是二叉排序树/n");
}
void mainmenu()//显示出菜单
{
 printf("-------------------请选择----------------------/n");
 printf("1、建立二叉链表。/n");
 printf("2、遍历二叉树输出。/n");
 printf("3、对比两种遍历叶子结点方法的输出结果。/n");
 printf("4、判断二叉树是否是完全二叉树。/n");
 printf("5、判断二叉树是否是二叉排序树。/n");
 printf("0、退出操作/n");
 printf("------------------------------------------------/n");
}
void main()
{
 int flag=0;
 int t,h=0;
 BitTree T;
 while(1)
 {
  
  mainmenu();
  scanf("%d",&t);
  switch(t)
  {
  case 1:
          printf("请输入字符串构造二叉树(#代表空树):/n");
            flag=CreateBitTree(T);
             getchar();
   break;
  case 2:
   if(flag==1)
   {
    if(T!=NULL){
   printf("用递归算法先序遍历二叉树:/n");
   DLR(T);printf("/n");}
    else{printf("二叉树为空!/n");}
   }
   else{printf("请先建立二叉树!/n");}
  
  break;
  case 3:
   if(flag==1)
   {
    if(T!=NULL){
   LinkList head,p;
         head=(LinkList)malloc(sizeof(Lnode));
         head->next=NULL;
         p=head;
   printf("用链表存储叶子结点:/n");
            linkleaf(T,p);
   printlink(head);
   printf("/n");
   printf("先序遍历叶子结点:/n");
   Preleaf(T);
            printf("/n");
    }
    else{printf("二叉树为空!/n");}
   }
   else{printf("请先建立二叉树!/n");}
   break;
  case 4:
   int f;
   f=0;
   f=Fultree(T);
   if(f==1){printf("是完全二叉树。/n");}
   else{printf("不是完全二叉树。/n");}
   break;
  case 5:
   if(flag==1)
   {
    if(T!=NULL){
      SortTree(T);printf("/n");}
    else{printf("二叉树为空!/n");}
   }
   else{printf("请先建立二叉树!/n");}
   break;
  case 0:
   exit(0);
   break;
  default:
   printf("输入错误!/n");

  }
 }

}

原创粉丝点击