数据结构二叉树——建立二叉树、中序递归遍历、非递归遍历、层次遍历

数据结构二叉树——

编写函数实现:建立二叉树、中序递归遍历、借助栈实现中序非递归遍历、借助队列实现层次遍历、求高度、结点数、叶子数及交换左右子树。

("."表示空子树)

#include<stdio.h>
#include<stdlib.h>
//***********二叉树链表节点结构
typedef char DataType;

typedef struct Node
{
 DataType data;
 struct Node*LChild;
 struct Node*RChild;
}BiTNode,*BiTree;

void Insert_tree(BiTree *T)
{
 char ch;
 ch = getchar();
 if (ch == ‘.‘)//"."表示空子树
  *T = NULL;
 else 
 {
  *T = (BiTree)malloc(sizeof(BiTNode));
  (*T)->data = ch;
  Insert_tree(&((*T)->LChild));
  Insert_tree(&((*T)->RChild));
 }
}

//*************二叉树的中序递归遍历
void InOrder(BiTree root)
{
 if (root != NULL)
 {
  InOrder(root->LChild);
  printf("%c ",root->data);
  InOrder(root->RChild);
 }
}
//****************二叉树的中序非递归遍历算法(调用栈操作)
#define Stack_Size 50

typedef struct //顺序栈结构
{
 BiTree elem[Stack_Size];
 int top;   //用来存放栈顶元素的下标,top为-1表示空栈
}SeqStack;

void InitStack(SeqStack *S)// 顺序栈初始化
{
 S->top = -1;  //制造一个空栈
}

int Push(SeqStack *S, BiTree x)  //顺序进栈
{
 if (S->top == Stack_Size - 1)
  return 0;  //栈已满
 S->top++;
 S->elem[S->top] = x;
 return 1;
}

int Pop(SeqStack * S, BiTree *x)//顺序出栈
{
 if (S->top == -1)  //栈为空
  return 0;
 else
 {
  *x = S->elem[S->top];
  S->top--;
  return 1;
 }
}

int IsEmpty(SeqStack *s)
{
 return s->top == -1 ? 0 : 1;
}

void InOrder_2(BiTree root)   //二叉树的中序非递归遍历
{
 BiTree p;
 SeqStack S;
 InitStack(&S);
 p = root;
 while (p != NULL|| IsEmpty(&S))
 {
  if (p != NULL)
  {
   Push(&S, p);
   p = p->LChild;
  }
  else
  {
   Pop(&S,&p);
   if(p != NULL)
   printf("%c ", p->data);
   p = p->RChild;
  }
 }
}

//***********************借助队列实现二叉树的层次遍历
#define MAXSIZE 50
typedef struct
{
 BiTree element[MAXSIZE];
 int front;
 int rear;
}SeqQueue;

void InitQueue(SeqQueue *Q)//循环队列初始化
{
 Q->front = 0;
 Q->rear = 0;
}

int EnterQueue(SeqQueue *Q,BiTree x) //循环队列入队
{
 if ((Q->rear + 1) % MAXSIZE == Q->front)
  return 0;
 Q->element[Q->rear] = x;
 Q->rear = (Q->rear + 1) % MAXSIZE;
 return 1;
}

int IsEmpty_Q(SeqQueue *Q)//判断是否为空
{
 return(Q->rear == Q->front) ? 0 : 1;
}

int EeleteQueue(SeqQueue *Q,BiTree *x)  //循环队列出队
{
 if (Q->front == Q->rear)
  return 0;
 *x = Q->element[Q->front];
 Q->front = (Q->front + 1) % MAXSIZE;
 return 1;
}

int Layer_Order(BiTree root)
{
 SeqQueue Q;
 BiTree p;
 InitQueue(&Q);
 if (root == NULL)
  return 0;
 EnterQueue(&Q, root);
 while (IsEmpty_Q(&Q))
 {
  EeleteQueue(&Q,&p);
  printf("%c ", p->data);
  if(p->LChild)
  EnterQueue(&Q,p->LChild);
  if(p->RChild)
  EnterQueue(&Q,p->RChild);
 }
 return 1;
}

//***********************二叉树的高度(后序遍历)
int PostTreeDepth(BiTree bt)
{
 int hl, hr, max;
 if (bt != NULL)
 {
  hl = PostTreeDepth(bt->LChild);
  hr = PostTreeDepth(bt->RChild);
  max = hl > hr ? hl : hr; //使用三目运算符 为书写方便
  return (max + 1);
 }
 else
  return 0;
}
//***********************二叉树的结点个数

int Order(BiTree root)
{
 static int ordercount = 0;//static 定义静态变量,在静态区存储,程序运行结束释放,用于实现在原先基础上加“1”,实现统计数字的效果(与下文运用全局变量目的一致)
 if (root != NULL)
 {
  ordercount++;
  Order(root->LChild);
  Order(root->RChild);
 }
 return ordercount;
}

//***********************二叉树的叶子个数
int LeafCount = 0;//定义全局变量,它的内存在程序执行完之后才释放,用于实现在原先基础上加“1”,实现统计数字的效果
void leaf(BiTree root)  //后序遍历统计叶子结点数目
{
 //int LeafCount = 0;
 if (root != NULL)
 {
  leaf(root->LChild);
  leaf(root->RChild);
  if ((root->LChild == NULL) && (root->RChild == NULL))
   LeafCount++;
 }
 //return LeafCount;
}
//***********************交换二叉树每个结点的左子树和右子树
void Exchange(BiTree root)
{
 BiTree temp = NULL;
 if (root != NULL)
 {
  temp = root->LChild;
  root->LChild = root->RChild;
  root->RChild = temp;
  Exchange(root->LChild);
  Exchange(root->RChild);
 }
}

void menu()
{
 printf("***********************************************\n");
 printf("*                  MENU                       *\n");
 printf("***********************************************\n");
 printf("* 1.输入字符序列,建立二叉树的二叉链表   *\n");
 printf("* 2.二叉树的中序递归遍历                *\n");
 printf("* 3.二叉树的中序非递归遍历              *\n");
 printf("* 4.借助队列实现二叉树的层次遍历        *\n");
 printf("* 5.求二叉树的高度                      *\n");
 printf("* 6.求二叉树的结点个数                  *\n");
 printf("* 7.求二叉树的叶子个数                  *\n");
 printf("* 8.交换二叉树每个结点的左子树和右子树  *\n");
 printf("* 0.退出                                *\n");
 printf("***********************************************\n");
 printf("***********************************************\n");
 printf("请输入选择序号:->");
}

int main()
{
 int choose = 1;
 BiTree TT = NULL;
 while (choose)
 {
  menu();
  scanf_s("%d", &choose);
  getchar();//为不影响二叉树的输入,将输入缓存中的回车(\n)取出
  switch (choose)
  {
  case 1:
   Insert_tree(&TT);
   break;
  case 2:
   InOrder(TT);
   printf("\n");
   break;
  case 3:
   InOrder_2(TT);
   printf("\n");
   break;
  case 4:
   Layer_Order(TT);
   printf("\n");
   break;
  case 5:
   printf("高度 = %d\n",PostTreeDepth(TT));
   break;
  case 6:
   printf("节点个数 = %d \n",Order(TT));
   break;
  case 7:
   leaf(TT);
   printf("叶子个数 = %d\n", LeafCount);
   break;
  case 8:
   Exchange(TT);
   InOrder(TT);
   printf("\n");
   break;
  default:
   break;
  }
 }
 system("pause");
 return 0;
}

时间: 2024-12-20 21:02:41

数据结构二叉树——建立二叉树、中序递归遍历、非递归遍历、层次遍历的相关文章

Java数据结构系列之——树(4):二叉树的中序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树的中序遍历:递归与非递归实现 * * @author wl * */ public class BiTreeInOrder { // 中序遍历的递归实现 public static void biTreeInOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreeInOrderByRecursi

二叉树的前序、中序、后序遍历(递归、非递归)实现

本文部分来源于CSDN兰亭风雨大牛的原创.链接为http://blog.csdn.net/ns_code/article/details/12977901 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的.二叉树有前.中.后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的).下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍

二叉树前序、中序、后序遍历非递归写法的透彻解析

前言 在前两篇文章二叉树和二叉搜索树中已经涉及到了二叉树的三种遍历.递归写法,只要理解思想,几行代码.可是非递归写法却很不容易.这里特地总结下,透彻解析它们的非递归写法.其中,中序遍历的非递归写法最简单,后序遍历最难.我们的讨论基础是这样的: //Binary Tree Node typedef struct node { int data; struct node* lchild; //左孩子 struct node* rchild; //右孩子 }BTNode; 首先,有一点是明确的:非递归

面试之路(11)-java递归和非递归二叉树前序中序后序遍历

二叉树的遍历 对于二叉树来讲最主要.最基本的运算是遍历. 遍历二叉树 是指以一定的次序访问二叉树中的每个结点.所谓 访问结点 是指对结点进行各种操作的简称.例如,查询结点数据域的内容,或输出它的值,或找出结点位置,或是执行对结点的其他操作.遍历二叉树的过程实质是把二叉树的结点进行线性排列的过程.假设遍历二叉树时访问结点的操作就是输出结点数据域的值,那么遍历的结果得到一个线性序列. 从二叉树的递归定义可知,一棵非空的二叉树由根结点及左.右子树这三个基本部分组成.因此,在任一给定结点上,可以按某种次

二叉树前序、中序和后序的遍历方法(递归、用栈和使用线索化)

在2^k*2^k个方格组成的棋盘中,有一个方格被占用,用下图的4种L型骨牌覆盖所有棋盘上的其余所有方格,不能重叠. 代码如下: def chess(tr,tc,pr,pc,size): global mark global table mark+=1 count=mark if size==1: return half=size//2 if pr<tr+half and pc<tc+half: chess(tr,tc,pr,pc,half) else: table[tr+half-1][tc+

二叉树的先序、中序、后序、层次遍历的递归和非递归解法

二叉树的先序.中序.后序.层次遍历的递归和非递归解法 package tree; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; public class TreeTraverse { /** * 先序递归 * @param root */ public static void preOrderTraverse(TreeNode root) { if (root == null) { ret

二叉树先序、中序、后续遍历非递归

1 ** 2 * 二叉树先序遍历非递归 3 * @param root 4 */ 5 public void preOrder_no_recursive(TreeNode root){ 6 if(root == null) return; 7 8 Stack<TreeNode> stack = new Stack<>(); 9 stack.add(root); 10 while(!stack.isEmpty()){ 11 TreeNode tn = stack.pop(); 12

Java数据结构系列之——树(5):二叉树的后序遍历的递归与非递归实现

package tree.binarytree; import java.util.Stack; /** * 二叉树后序遍历的递归与非递归实现 * * @author wl * */ public class BitreePostOrder { // 后序遍历的递归实现 public static void biTreePostOrderByRecursion(BiTreeNode root) { if (root == null) { return; } biTreePostOrderByRe

二叉树的中序、先序、后序遍历非递归遍历算法(使用堆栈,用循环实现)

1 typedef struct TreeNode *BinTree; 2 typedef BinTree Position; 3 struct TreeNode{ 4 ElementType Data; 5 BinTree Left; 6 BinTree Right; 7 }; 8 BinTree BT; 9 void InOrderTraversal(BinTree BT)//中序遍历非递归遍历算法(使用堆栈,用循环实现) 10 { 11 BinTree T=BT; 12 Stack S=C

数据结构二叉树的递归与非递归遍历之 实现可编译(1)java

前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序遍历为例进行说明,中序遍历和后序遍历,以此类推! 二叉树递归与非递归遍历的区别,虽然递归遍历,跟容易读懂,代码量少,运算快,但是却容易出现溢出的问题,所以所以非递归遍历,在处理千万级的运算量时会先的很有用处. 二叉树的先序遍历:先访问根节点,再访问先后访问左右节点.如图: 二叉树的递归遍历之java