二叉树的全部遍历实现与应用

论坛 期权论坛 脚本     
匿名技术用户   2021-1-14 14:39   415   0

二叉树的遍历与应用

一、 实验目的

1. 熟练掌握二叉树的根前序、根中序、根后序遍历的递归和非递归的算法实现,并且能够从时间和空间复杂度的角度综合考虑递归和非递归算法的不同特点。

2. 二叉树是计算机科学中应用非常广泛的数据结构之一,通过对二叉树遍历算法的递归与非递归实现加深对二叉树的理解,并且学会用二叉树来解决实际中的简单问题。

3. 训练逻辑性的思维,通过对二叉树遍历算法问题的深入思考,加深对数据结构的认识。

4. 培养程序设计,算法分析以及调试程序的能力,为日后工作中参与项目打下基础。

二、 实验要求及实验环境

1. 实验要求

(1) 实现对二叉树的根前序、根中序、根后序遍历的递归和非递归以及层序遍历的不同算法;

(2) 给出二叉树的根前序和根中序,用递归算法和非递归算法分别建立二叉树。

(3) 对于二叉树的任意两个结点,给出这两个结点的最近公共祖先。

2.实验环境

(1)操作系统:MicrosoftWindows 10 Technical Preview x64.

(2)编译环境:Microsoft Visual Studio 2013 Ultimate.


三、 具体实现

1.数据结构实现

//二叉树的数据结构
struct BinaryTree
{
 char Data; //结点数据
 BinaryTree *LeftChild;//左子树
 BinaryTree *RightChild;//右子树
};
typedef BinaryTree *ROOT;


//实现非递归算法的工作栈
struct Stack
{
 BinaryTree *Data;
 Stack *Next;
 Stack() :Next(NULL){}
};
typedef Stack *STACK;


//实现非递归算法的辅助栈
struct AssistStack
{
 BinaryTree *NodePointer[NODENUMBERS];
 int Top;
};
typedef AssistStack *ATSTACK;


//实现层次遍历的队列
struct Queue
{
 int Front;
 int Rear;
 BinaryTree *Elements[NODENUMBERS];
};
typedef Queue *QUEUE;<strong>
</strong>


2. 功能函数

(1)前序递归遍历

/*递归前序遍历二叉树*/
void RecursionPreviousSortErgodic(ROOT &Root)
{
 if (!BinaryTreeIsEmpty(Root))
 {
  VisitData(Root);
  RecursionPreviousSortErgodic(Root->LeftChild);
  RecursionPreviousSortErgodic(Root->RightChild);
 }
}

(2)前序非递归遍历

/*非递归前序遍历二叉树*/
void NonRecursionPreviousSortErgodic(ROOT &Root)
{
 STACK BinaryTreeStack;
 BinaryTreeStack = new Stack;

 StackMakeNull(BinaryTreeStack);

 struct BinaryTree *Node;
 Node = Root;
 while (Node != NULL)
 {
  VisitData(Node);
  if (Node->RightChild != NULL)
  {
   StackPush(Node->RightChild, BinaryTreeStack);
  }
  if (Node->LeftChild != NULL)
  {
   Node = Node->LeftChild; //进左子树
  }
  else
  {
   Node = StackTop(BinaryTreeStack);
   StackPop(BinaryTreeStack); //做子树空,访问又子树
  }
 }
}

(3)中序递归遍历

/*递归中序遍历二叉树*/
void RecursionMiddleSortErgodic(ROOT &Root)
{
 if (!BinaryTreeIsEmpty(Root))
 {
  RecursionMiddleSortErgodic(Root->LeftChild);
  VisitData(Root);
  RecursionMiddleSortErgodic(Root->RightChild);
 }
}

(4)中序非递归遍历

/*非递归中序遍历二叉树*/
void NonRecursionMiddleSortErgodic(ROOT &Root)
{
 STACK BinaryTreeStack;
 BinaryTreeStack = new Stack;
 StackMakeNull(BinaryTreeStack);

 struct BinaryTree *Node;
 Node = Root;

 while ((Node != NULL) || (!StackIsEmpty(BinaryTreeStack)))
 {
  while (Node != NULL)
  {
   StackPush(Node, BinaryTreeStack);
   Node = Node->LeftChild;
  }
  if (!StackIsEmpty(BinaryTreeStack))
  {
   Node = StackTop(BinaryTreeStack);
   StackPop(BinaryTreeStack);

   VisitData(Node);
   Node = Node->RightChild;
  }
 }
}

(5)后序递归遍历

/*递归后序遍历二叉树*/
void RecursionRearSortErgodic(ROOT &Root)
{
 if (!BinaryTreeIsEmpty(Root))
 {
  RecursionRearSortErgodic(Root->LeftChild);
  RecursionRearSortErgodic(Root->RightChild);
  VisitData(Root);
 }
}

(6)后序非递归遍历

/*非递归后序遍历二叉树*/
void NonRecursionRearSortErgodic(ROOT &Root)
{
 ROOT Node;
 int Target[30];

 ATSTACK BinaryTreeStack;
 BinaryTreeStack = new AssistStack;
 AssistStackMakeNull(BinaryTreeStack);

 Node = Root;
 while (Node != NULL || !AssistStackIsEmpty(BinaryTreeStack))
 {
  while (Node != NULL)
  {
   AssistStackPush(Node, BinaryTreeStack);
   Target[BinaryTreeStack->Top] = -1;
   Node = Node->LeftChild;
  }
  while (!AssistStackIsEmpty(BinaryTreeStack) && Target[BinaryTreeStack->Top] == 1)
  {
   Node = AssistStackTop(BinaryTreeStack);
   AssistStackPop(BinaryTreeStack);
   VisitData(Node);
  }
  if (!AssistStackIsEmpty(BinaryTreeStack))
  {
   Target[BinaryTreeStack->Top] = 1;
   Node = AssistStackTop(BinaryTreeStack);
   Node = Node->RightChild;
  }
  else
  {
   break;
  }
 }
}

(7)层序遍历

//层次遍历二叉树
void LevelSortErgodic(ROOT &Root)
{
 ROOT Node;
 Node = Root;

 QUEUE Q;
 Q = new Queue;
 Q->Front = 0;
 Q->Rear = 0;

 if (Root == NULL)
 {
  return;
 }
 Q->Elements[++Q->Rear] = Root;
 while (Q->Front != Q->Rear)
 {
  Node = Q->Elements[++Q->Front];
  VisitData(Node);
  if (Node->LeftChild != NULL)
  {
   Q->Elements[++Q->Rear] = Node->LeftChild;
  }
  if (Node->RightChild != NULL)
  {
   Q->Elements[++Q->Rear] = Node->RightChild;
  }
 }
}



源代码

/**
*Copyright(C) 2014 HIT CS
*All rights reserved.

*Data and Struct Experiment 2 
*Create by Windows 8.1 Enterprise X64
*Edit and Compiled Visual Studio 2013 Ultimate
Version 1.2
Date 10/28/2014
*/

#define _CRT_SECURE_NO_WARNINGS

#define  NODENUMBERS  50

#include <iostream>
#include <string.h>

using namespace std;


//二叉树的数据结构
struct BinaryTree
{
 char Data; //结点数据
 BinaryTree *LeftChild;//左子树
 BinaryTree *RightChild;//右子树
};
typedef BinaryTree *ROOT;


//实现非递归算法的工作栈
struct Stack
{
 BinaryTree *Data;
 Stack *Next;
 Stack() :Next(NULL){}
};
typedef Stack *STACK;


//实现非递归算法的辅助栈
struct AssistStack
{
 BinaryTree *NodePointer[NODENUMBERS];
 int Top;
};
typedef AssistStack *ATSTACK;


//实现层次遍历的队列
struct Queue
{
 int Front;
 int Rear;
 BinaryTree *Elements[NODENUMBERS];
};
typedef Queue *QUEUE;


//对二叉树的操作函数
bool BinaryTreeIsEmpty(ROOT &Root);
char VisitData(ROOT &Root);


//对栈操作的函数
void StackMakeNull(STACK BinaryTreeStack);
void StackPush(BinaryTree *element, STACK BinaryTreeStack);
void StackPop(STACK BinaryTreeStack);
BinaryTree *StackTop(STACK BinaryTreeStack);
bool StackIsEmpty(STACK BinaryTreeStack);


//对辅助栈的操作函数
void AssistStackMakeNull(ATSTACK AssistStack);
void AssistStackPush(BinaryTree *Element, ATSTACK AssistStack);
BinaryTree *AssistStackTop(ATSTACK AssistStack);
void AssistStackPop(ATSTACK AssistStack);
bool AssistStackIsEmpty(ATSTACK AssistStack);


//由中序和前序序列生成测试二叉树的函数
void CreatTestBinaryTree(ROOT &Root);
int SearchPosition(char *MiddleSort, char element);
void PreMidCreatBinaryTree(ROOT &Root, char *Previous, int i, char *Middle, int j, int length); 


//功能函数
void MainChoiceMenu(ROOT &Root);
void GeneralListOut(ROOT &Root);
void RecursionPreviousSortErgodic(ROOT &Root); //递归前序遍历二叉树
void NonRecursionPreviousSortErgodic(ROOT &Root); //非递归前序遍历二叉树
void RecursionMiddleSortErgodic(ROOT &Root); //递归中序遍历二叉树
void NonRecursionMiddleSortErgodic(ROOT &Root); //非递归中序遍历二叉树
void RecursionRearSortErgodic(ROOT &Root); //递归后序遍历二叉树
void NonRecursionRearSortErgodic(ROOT &Root); //非递归后序遍历二叉树
void LevelSortErgodic(ROOT &Root); //层序遍历二叉树
BinaryTree* findLowestCommonAncestor(ROOT &Root, BinaryTree *a, BinaryTree *b); //寻找任意两个节点的公共祖先
BinaryTree *Search(ROOT &Root, char search);

int main()
{
 ROOT Root;
 MainChoiceMenu(Root);
 getchar();
 return 0;
}

//遍历操作选择菜单
void MainChoiceMenu(ROOT &Root)
{
 int choice;
 char a, b;
 BinaryTree *Node1, *Node2, *result;
 CreatTestBinaryTree(Root);

 do
 {
  cout << "\n\n\t二叉树遍历操作选择系统\n------------------------------------" << endl;
  cout << "  1.前序递归遍历二叉树" << endl;
  cout << "  2.前序非递归遍历二叉树" << endl;
  cout << "  3.中序递归遍历二叉树" << endl;
  cout << "  4.中序非递归遍历二叉树" << endl;
  cout << "  5.后序递归遍历二叉树" << endl;
  cout << "  6.后序非递归遍历二叉树" << endl;
  cout << "  7.层序遍历二叉树" << endl;
  cout << "  8.递归前序和后序建立二叉树结果广义表输出" << endl;
  cout << "  9.任意两个根的最近公共祖先" << endl;
  cout << "  0.退出系统" << endl;
  cout << " \n请选择:";
  cin >> choice;

  switch (choice)
  {
   case 0:
   {
    cout << "\n已退出系统\n" << "键入任意内容关闭" << endl;
    getchar();
    break;
   }
   case 1:
   {
    cout << "\n递归前序遍历二叉树结果:";
    RecursionPreviousSortErgodic(Root);
    break;
   }
   case 2:
   {
    cout << "\n非递归前序遍历二叉树结果:";
    NonRecursionPreviousSortErgodic(Root);
    break;
   }
   case 3:
   {
    cout << "\n递归中序遍历二叉树结果:";
    RecursionMiddleSortErgodic(Root);
    break;
   }
   case 4:
   {
    cout << "\n非递归中序遍历二叉树结果:";
    NonRecursionMiddleSortErgodic(Root);
    break;
   }
   case 5:
   {
    cout << "\n递归后序遍历二叉树结果:";
    RecursionRearSortErgodic(Root);
    break;
   }
   case 6:
   {
    cout << "\n非递归后序遍历二叉树结果:";
    NonRecursionRearSortErgodic(Root);
    break;
   } 
   case 7:
   {
    cout << "\n层序遍历二叉树结果:";
       LevelSortErgodic(Root);
       break;
   }
   case 8:
   {
    cout << "\n递归前序和后序建立二叉树结果广义表输出结果:";
    GeneralListOut(Root);
    break;
   }
   case 9:
   {
    cout << "\n寻找任意两个根的最近公共祖先\n-------------------------------" << endl;;
    cout << "输入两个节点(如A B):";
    cin >> a >> b;
    Node1 = Search(Root, a);
    Node2 = Search(Root, b);
    result = findLowestCommonAncestor(Root, Node1, Node2);
    cout << "\n节点 " << a << " 和 " << b << " 的公共祖先节点为: " << result->Data << endl;
    break;
   }
   default:
   {
    cout << "\n输入有误!" << endl;
   }
  }
 } 
 while (choice != 0);
}

//将建立的二叉树用广义表输出
void GeneralListOut(ROOT &Root)
{
 cout << Root->Data;
 if (Root->LeftChild != NULL || Root->RightChild != NULL)
 {
  cout << '(';
  if (Root->LeftChild != NULL)
  {
   GeneralListOut(Root->LeftChild); 
  }
  cout << ',';

  if (Root->RightChild)
  {
   GeneralListOut(Root->RightChild); 
  }
  cout << ')';
 }
}


/*递归前序遍历二叉树*/
void RecursionPreviousSortErgodic(ROOT &Root)
{
 if (!BinaryTreeIsEmpty(Root))
 {
  VisitData(Root);
  RecursionPreviousSortErgodic(Root->LeftChild);
  RecursionPreviousSortErgodic(Root->RightChild);
 }
}

/*非递归前序遍历二叉树*/
void NonRecursionPreviousSortErgodic(ROOT &Root)
{
 STACK BinaryTreeStack;
 BinaryTreeStack = new Stack;

 StackMakeNull(BinaryTreeStack);

 struct BinaryTree *Node;
 Node = Root;
 while (Node != NULL)
 {
  VisitData(Node);
  if (Node->RightChild != NULL)
  {
   StackPush(Node->RightChild, BinaryTreeStack);
  }
  if (Node->LeftChild != NULL)
  {
   Node = Node->LeftChild; //进左子树
  }
  else
  {
   Node = StackTop(BinaryTreeStack);
   StackPop(BinaryTreeStack); //做子树空,访问又子树
  }
 }
}

/*递归中序遍历二叉树*/
void RecursionMiddleSortErgodic(ROOT &Root)
{
 if (!BinaryTreeIsEmpty(Root))
 {
  RecursionMiddleSortErgodic(Root->LeftChild);
  VisitData(Root);
  RecursionMiddleSortErgodic(Root->RightChild);
 }
}

/*非递归中序遍历二叉树*/
void NonRecursionMiddleSortErgodic(ROOT &Root)
{
 STACK BinaryTreeStack;
 BinaryTreeStack = new Stack;
 StackMakeNull(BinaryTreeStack);

 struct BinaryTree *Node;
 Node = Root;

 while ((Node != NULL) || (!StackIsEmpty(BinaryTreeStack)))
 {
  while (Node != NULL)
  {
   StackPush(Node, BinaryTreeStack);
   Node = Node->LeftChild;
  }
  if (!StackIsEmpty(BinaryTreeStack))
  {
   Node = StackTop(BinaryTreeStack);
   StackPop(BinaryTreeStack);

   VisitData(Node);
   Node = Node->RightChild;
  }
 }
}

/*递归后序遍历二叉树*/
void RecursionRearSortErgodic(ROOT &Root)
{
 if (!BinaryTreeIsEmpty(Root))
 {
  RecursionRearSortErgodic(Root->LeftChild);
  RecursionRearSortErgodic(Root->RightChild);
  VisitData(Root);
 }
}

/*非递归后序遍历二叉树*/
void NonRecursionRearSortErgodic(ROOT &Root)
{
 ROOT Node;
 int Target[30];

 ATSTACK BinaryTreeStack;
 BinaryTreeStack = new AssistStack;
 AssistStackMakeNull(BinaryTreeStack);

 Node = Root;
 while (Node != NULL || !AssistStackIsEmpty(BinaryTreeStack))
 {
  while (Node != NULL)
  {
   AssistStackPush(Node, BinaryTreeStack);
   Target[BinaryTreeStack->Top] = -1;
   Node = Node->LeftChild;
  }
  while (!AssistStackIsEmpty(BinaryTreeStack) && Target[BinaryTreeStack->Top] == 1)
  {
   Node = AssistStackTop(BinaryTreeStack);
   AssistStackPop(BinaryTreeStack);
   VisitData(Node);
  }
  if (!AssistStackIsEmpty(BinaryTreeStack))
  {
   Target[BinaryTreeStack->Top] = 1;
   Node = AssistStackTop(BinaryTreeStack);
   Node = Node->RightChild;
  }
  else
  {
   break;
  }
 }
}

//层次遍历二叉树
void LevelSortErgodic(ROOT &Root)
{
 ROOT Node;
 Node = Root;

 QUEUE Q;
 Q = new Queue;
 Q->Front = 0;
 Q->Rear = 0;

 if (Root == NULL)
 {
  return;
 }
 Q->Elements[++Q->Rear] = Root;
 while (Q->Front != Q->Rear)
 {
  Node = Q->Elements[++Q->Front];
  VisitData(Node);
  if (Node->LeftChild != NULL)
  {
   Q->Elements[++Q->Rear] = Node->LeftChild;
  }
  if (Node->RightChild != NULL)
  {
   Q->Elements[++Q->Rear] = Node->RightChild;
  }
 }
}


BinaryTree *Search(ROOT &Root, char search)
{
 STACK BinaryTreeStack;
 BinaryTreeStack = new Stack;

 StackMakeNull(BinaryTreeStack);

 struct BinaryTree *Node;
 Node = Root;
 while (Node->Data != search)
 {
  if (Node->RightChild != NULL)
  {
   StackPush(Node->RightChild, BinaryTreeStack);
  }
  if (Node->LeftChild != NULL)
  {
   Node = Node->LeftChild; //进左子树
  }
  else
  {
   Node = StackTop(BinaryTreeStack);
   StackPop(BinaryTreeStack); //做子树空,访问又子树
  }
 }
 return Node;
}


BinaryTree* findLowestCommonAncestor(ROOT &Root, BinaryTree *a, BinaryTree *b)
{
 if (Root == NULL)
 {
  return NULL;
 }
 if (Root == a || Root == b)
 {
  return Root;
 }

 BinaryTree *left = findLowestCommonAncestor(Root->LeftChild, a, b);
 BinaryTree *right = findLowestCommonAncestor(Root->RightChild, a, b);

 if (left && right)
 {
  return Root;
 }

 return left ? left : right;
}

/*二叉树的操作函数*/
/*--------------------------------------------*/
bool BinaryTreeIsEmpty(ROOT &Root)
{
 if (Root != NULL)
 {
  return false;
 }
 return true;
}

char VisitData(ROOT &Root)
{
 cout << Root->Data << " ";
 return Root->Data;
}


/*栈的操作函数*/
/*--------------------------------------------*/
//将栈置空
void StackMakeNull(STACK BinaryTreeStack)
{
 BinaryTreeStack = new Stack;
 BinaryTreeStack->Next = NULL;
}

//压栈
void StackPush(BinaryTree *element, STACK BinaryTreeStack)
{
 STACK Node;
 Node = new Stack;
 Node->Data = element;
 Node->Next = BinaryTreeStack->Next;
 BinaryTreeStack->Next = Node;
}

//删除栈顶元素
void StackPop(STACK BinaryTreeStack)
{
 STACK Node;
 if (BinaryTreeStack->Next)
 {
  Node = BinaryTreeStack->Next;
  BinaryTreeStack->Next = Node->Next;
  delete Node;
 }
}

//弹出栈顶元素
BinaryTree *StackTop(STACK BinaryTreeStack)
{
 if (BinaryTreeStack->Next)
 {
  return (BinaryTreeStack->Next->Data);
 }
 else
 {
  return NULL;
 }
}

//判断栈是否为空
bool StackIsEmpty(STACK BinaryTreeStack)
{
 if (BinaryTreeStack->Next)
 {
  return false;
 }
 else
 {
  return true;
 }
}


/*辅助站栈的操作函数*/
/*--------------------------------------------*/
//将辅助栈置空
void AssistStackMakeNull(ATSTACK AssistStack)
{
 AssistStack->Top = -1;
}

//压栈辅助栈
void AssistStackPush(BinaryTree *Element, ATSTACK AssistStack)
{
 AssistStack->NodePointer[++AssistStack->Top] = Element;
}

BinaryTree *AssistStackTop(ATSTACK AssistStack)
{
 return AssistStack->NodePointer[AssistStack->Top];
}

void AssistStackPop(ATSTACK AssistStack)
{
 AssistStack->Top--;
}

bool AssistStackIsEmpty(ATSTACK AssistStack)
{
 if (AssistStack->Top == -1)
 {
  return true;
 }
 return false;
}


/*--用于生成测试二叉树的函数部分*/
/*--------------------------------------------*/
void CreatTestBinaryTree(ROOT &Root)
{
 //char PreviousSort[11] = "ABDHLEKCFG"; //二叉树的前序序列
 //char MiddleSort[11] = "HLDBEKAFCG";   //二叉树的中序序列

 char PreviousSort[16] = "ABDGLEHIMCFJNK"; //二叉树的前序序列
 char MiddleSort[16] = "GLDBAHEMIJNFKC";   //二叉树的中序序列

 int i = 0, j = 0, length;
 length = strlen(PreviousSort);

 PreMidCreatBinaryTree(Root, PreviousSort, i, MiddleSort, j, length);
}

//根据中序和前序表达式利用递归生成二叉树
void PreMidCreatBinaryTree(ROOT &Root, char *Previous, int i, char *Middle, int j, int length)
{
 int k;
 if (length <= 0) //递归终止的条件
 {
  return;
 }
 Root = new BinaryTree;
 Root->LeftChild = NULL;
 Root->RightChild = NULL;

 Root->Data = Previous[i];
 k = SearchPosition(Middle, Previous[i]);
 PreMidCreatBinaryTree(Root->LeftChild, Previous, (i+1), Middle, j, (k-j));
 PreMidCreatBinaryTree(Root->RightChild, Previous, (i +(k-j)+1), Middle, (k+1), (length-1-(k-j)));
}

//查找当前根节点在中序序列中的位置
int SearchPosition(char *MiddleSort, char element)
{
 int i;
 for (i = 0; MiddleSort[i] != '\0'; i++)
 {
  if (element == MiddleSort[i])
  {
   break;
  }
 }
 return i;
}


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP