实验五:二叉树的基本操作

#include<stdio.h>
#include<stdlib.h>


typedef struct tree{
 char data1;
 struct tree *lchild,*rchild;
}tree,*rtree;

typedef struct stacklist{
 rtree data;
 struct stacklist *next;
}stacklist,*linkstack;

linkstack top;
rtree ch1;

linkstack create()
{
 linkstack p;
 p=(linkstack)malloc(sizeof(stacklist));
 p->next=NULL;
 return p;
} 

void bulidstack(rtree ch1)//进栈
{ 
 linkstack p,q;
 //int data;
 p=top;
// printf("请输入进栈的元素:");
 //scanf("%d",&data);
 q=create();
 q->data=ch1;
 q->next=p->next;
 top->next=q;
}

linkstack outstack()//出栈
{  
 linkstack p,q=NULL;
    p=top->next;
 if(p!=NULL)
 {
  //printf("%d 出栈\n",p->data);
  top->next=p->next;
  q=p;
  //free(p);
  return q;
 }
// else
 // printf("栈为空\n"); 
  return q;
}

int StackEmpty()
{  
 linkstack p;
    p=top->next;
 if(p!=NULL)
  return 0;
 return 1;
}

/*void tip()
{
 printf("**********\n");
 printf("*1 进栈  *\n");
 printf("*2 出栈  *\n");
 printf("*请选择:*\n");
 printf("**********\n");
}*/
/*int main()
{ 
top=create();
int k;
tip();
while(scanf("%d",&k),k)
{
switch(k)
{
case 1:
bulidstack();
printf("操作完成\n");
tip();
break;
case 2:
outstack();
printf("操作完成\n");
tip();
break;
}
}
return 0;
}*/


 

// 按扩展的先序序列(即包括空结点,#表示空结点)输入二叉树的各结点,建立二叉树

#include"stack.h"

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#define OVERFLOW -2
using namespace std;

/*typedef struct tree{
char data1;
struct tree *lchild,*rchild;
}tree,*rtree;*/

int highmax,leaf;
char ch;

void CreateBiTree(rtree &root)//1
{ 
 //二叉树中的节点值(一个字符),#字符表示空树;
 //构造二叉链表的二叉树root
 
 //printf("请按照先序次序输入二叉链表的二叉树root:");
 cin>>ch;
 if(ch=='#') root=NULL;
 else
 { 
  if(!(root=(rtree)malloc(sizeof(tree))))//分配失败
   exit(OVERFLOW);
  root->data1=ch;//生成根节点
  CreateBiTree(root->lchild);
  CreateBiTree(root->rchild);
 }
 return ; 
}

void PreOrderTraverse(rtree &root)//递归先序遍历
{ 
 if(root)
 { 
  cout<<root->data1<<"  ";
  PreOrderTraverse(root->lchild);
  PreOrderTraverse(root->rchild);
 }
 return ;  
}

void InOrderTraverse(rtree &root)//递归中序遍历
{ 
 if(root)
 {
  InOrderTraverse(root->lchild);
  cout<<root->data1<<"  ";
  InOrderTraverse(root->rchild);
 }
 return ;  
}

void InOrderTraverse1(rtree &root)//非递归中序遍历
{  
 top=create();
 linkstack s;
 rtree p;
 p=root;
 
 
 
 while(p||!StackEmpty())
 {  
  
  if(p)
  { 
   bulidstack(p);
   p=p->lchild;
  }
  else
  { 
   s=outstack();
   p=s->data;
   if(p)
    cout<<p->data1<<"  ";
   p=p->rchild;
   
  }
 }
 return ;
}

 

 

void EndOrderTraverse(rtree &root)//递归后序遍历
{   
 if(root)
 {
  EndOrderTraverse(root->lchild);
  EndOrderTraverse(root->rchild);
  cout<<root->data1<<"  ";
 }
 
 return ;  
}

void TreeHigh(rtree &root,int high)//二叉树的高度
{ 
 if(root)
 { 
  high++;
  if(high>highmax)
   highmax=high;
  TreeHigh(root->lchild,high);
  TreeHigh(root->rchild,high);
 }
 return;
 
}

void TreeLeaf(rtree &root,int l)//求二叉树的叶子个数。
{  
 if(root)
 { 
  if(root->lchild==NULL&&root->rchild==NULL)
   leaf++;
  TreeLeaf(root->lchild,l);
        TreeLeaf(root->rchild,l);
 }
 return ;
}

void tip()
{ 
 cout<<"************计科1001陈东东**************"<<endl;
 cout<<"*1 输入字符序列,建立二叉链表          *"<<endl;
 cout<<"*2 先序、中序、后序遍历二叉树:递归算法 *"<<endl;
 cout<<"*3 中序遍历二叉树:非递归算法           *"<<endl;
 cout<<"*4 求二叉树的高度                      *"<<endl;
 cout<<"*5 求二叉树的叶子个数                  *"<<endl;
 cout<<"*6 借助队列实现二叉树的层次遍历        *"<<endl;
 cout<<"*0 退出                                *"<<endl;
 cout<<"****************************************"<<endl;
 
}


队列

 

#define MAXQSIZE 100  /*队列的最大长度*/


typedef struct queue{
    rtree *base;   // 队列的元素空间头指针指示器
    int  front;                  
    int  rear;   /*尾指针指示器*/
}SqQueue; 

rtree data2;  

int InitQueue(SqQueue &Q) {//初始化操作 
 Q.base = (rtree * )malloc(MAXQSIZE*sizeof(rtree));
 if (!Q. base) exit (OVERFLOW);  
 Q.front=Q.rear =0;
 return 1;
} 

int EnQueue(SqQueue &Q,rtree e) {//入队操作 
 if ((Q. rear+ 1) % MAXQSIZE == Q. front)
 { 
  printf("队列已满,不能进队\n");
  return -1;//满标志 
 } 
 // printf("请输入进队元素:");
 //scanf("%d",&e);
 Q.base[Q.rear] = e;//进队
 Q.rear = (Q. rear + 1) % MAXQSIZE;//队尾指针后移
 return 1;
}

rtree DeQueue (SqQueue &Q) {//出队操作
 rtree e;
 if (Q. front == Q. rear) { 
  printf("队列已经为空\n");
  return 0;
 }
 e = Q. base[Q. front];//队头出队
 // printf("%d  出队\n",e);
 Q.front = (Q.front + 1) % MAXQSIZE;//队头下标后移
 return e;
}
int QueueEmpty(SqQueue &Q)//判断是否为空
{  
 if (Q. front == Q. rear) 
  return 1;
 return 0;
}


void Traverse(rtree &root)
{ 
    SqQueue Q;
    InitQueue(Q);//初始化
 rtree p;
 EnQueue(Q,root);
 while(!QueueEmpty(Q))
 {
  p=DeQueue(Q);
  cout<<p->data1<<"  ";
  if(p->lchild)
  EnQueue(Q,p->lchild);
  if(p->rchild)
  EnQueue(Q,p->rchild);
 }
 cout<<endl;
 return ; 
}

int main()
{ 

 tip();
 int k;
 rtree root;//声明根
    while(scanf("%d",&k),k)
 { 
  switch(k)
  { 
  case 1: 
   cout<<"按扩展的先序序列,#表示空结点,请输入字符:"<<endl;
   CreateBiTree(root);
   cout<<"操作完毕"<<endl;
   tip();
   break;
  case 2:
   cout<<"先序递归遍历:";
   PreOrderTraverse(root);
   cout<<endl;
   cout<<"中序递归遍历:";
   InOrderTraverse(root);
   cout<<endl;
            cout<<"后序递归遍历:";
   EndOrderTraverse(root);
   cout<<endl;
   cout<<"操作完毕"<<endl;
            tip();
   break;
  case 3:
   cout<<"中序非递归遍历:";
   InOrderTraverse1(root);
   cout<<endl;
   cout<<"操作完毕"<<endl;
   tip();
   break;
  case 4:
   highmax=0;
   TreeHigh(root,0);
            cout<<"二叉树的高度为:"<<highmax<<endl;
   cout<<"操作完毕"<<endl;
   tip();
   break;
  case 5:
   leaf=0;
   TreeLeaf(root,0);
   cout<<"二叉树的叶子结点个数为:"<<leaf<<endl;
   cout<<"操作完毕"<<endl;
   tip();
   break;
  case 6:
   Traverse(root);
   cout<<"操作完毕"<<endl;
   tip();
   break;
  }
 }
 //CreateBiTree(root);
 /*PreOrderTraverse(root);
 cout<<endl;
 InOrderTraverse(root);
 cout<<endl;
 
   EndOrderTraverse(root);
   cout<<endl;
   highmax=0;
   TreeHigh(root,0);
   cout<<"二叉树的高度为:"<<highmax<<endl;
   leaf=0;
   TreeLeaf(root,0);
   cout<<"二叉树的叶子结点个数为:"<<leaf<<endl;
   InOrderTraverse1(root);
 cout<<endl;*/
 
 
 
 return 0;
}


//ABD###CE##F##


1)输入字符序列,建立二叉链表。

2)先序、中序、后序遍历二叉树:递归算法。

3)中序遍历二叉树:非递归算法。(最好也能实现先序、后序非递归算法)

4)求二叉树的高度 。

5)求二叉树的叶子个数。

6)借助队列实现二叉树的层次遍历。

7)在主函数中设计一个简单的菜单,分别调试上述算法。

 

 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值