`
sylinx_yqg
  • 浏览: 143439 次
  • 性别: Icon_minigender_1
  • 来自: 福建 漳州
社区版块
存档分类
最新评论

树相关操作的递归算法实现

阅读更多
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
/***************************************************************** * 文件名:Rstree.c * * 文件描述:树相关操作的递归算法实现 * * 创建人:颜清国 2006年4月15日 * * * 修改记录: * **************************************************************/ #include "stdio.h"#include"stdlib.h"#include"conio.h"#define LEFT 1#define RIGHT 2#define MAX 20/************************************** 定义树的结构体***************************************/typedef struct tagtree{ char data;                /*数据域*/ int flag;                 /*非递归操作时用来做标志*/ struct tagtree*lchild;    /*指向左孩子的指针域*/ struct tagtree*rchild;    /*指向右孩子的指针域*/}tree;/****************************************  创建一棵树,要求这棵树用括号表示法输入*****************************************/void CreateTree(tree **root,char *str){ char ch; tree *stack[MAX],*lp=NULL,*temp;      /*定义一个指向树的一个栈,                                    用来创建其结点的父子关系*/ int top=-1,flag;              /*指向树栈的栈顶,flag用来标记左右孩子*/ (*root)=NULL;                 /*特别注意这里一定要先将指向根结点的指针附空,否则                                   在XP系统下就会出大错*/while((*str)!='\0'){ ch=(*str); switch(ch) {  case '(':                 /*下去的DATA值将作为栈顶结点的左右孩子*/           top++;	   stack[top] = lp; /*将双亲结点入栈*/           flag = LEFT;     /*标记其下一个结点将作为此栈顶结点的                               左孩子*/           break;  case ',':           flag = RIGHT;    /*标记为下去结点将作为此栈顶结点的                               右孩子*/           break;  case ')':           top--;           /*将栈顶结点退栈,这样才能保证双亲及                               其对应孩子的正确配对*/           break;  default:                  /*此时CH为DATA域*/           lp = (tree*)malloc(sizeof(tree)); /*创建一个结点*/           lp->data = ch;           lp->lchild = NULL;           lp->rchild = NULL;           if((*root) == NULL)       /*是树的根结点*/             (*root) = lp;           else           {                  /*注意此处不能用这种表达方式*/                 /* temp = (flag == LEFT) ? stack[top]->lchild : stack[top]->rchild;                  temp = lp;  */                 switch(flag)                  {                    case RIGHT:                           /*插到右结点*/                                stack[top]->rchild = lp;                                 break;                    case LEFT:                           /*插到左结点*/                                 stack[top]->lchild = lp;                                  break;                     }               }          break;   }   str++;}}/******************************************** 用括号表示法输出树**********************************************/void OutTree(tree *root){ if(root != NULL) {  printf("%c",root->data);       /*先输出根结点*/  if(root->lchild != NULL || root->rchild != NULL)  {   printf("(");   OutTree(root->lchild);        /*处理左子树*/   if(root->rchild != NULL)   {    printf(",");   }  OutTree(root->rchild);         /*处理右子树*/  printf(")");}}}/************************************************ 递归先序遍历二叉树************************************************/void RsPrePath(tree *root){ if(root!=NULL) {   printf("%c ",root->data);         /*遇到根结点先输出*/   RsPrePath(root->lchild);            /*遇到根结点左子数先输出,                                       直到空,返回是输出左子数                                       根结点右子数*/   RsPrePath(root->rchild);            /*同样处理右子数*/ }}/************************************************ 递归中序遍历二叉树************************************************/void RsMidPath(tree *root){ if(root!=NULL) {   RsMidPath(root->lchild);   printf("%c ",root->data);   RsMidPath(root->rchild); }}/************************************************ 递归后序遍历二叉树************************************************/void RsLastPath(tree *root){ if(root!=NULL) {   RsLastPath(root->lchild);   RsLastPath(root->rchild);   printf("%c ",root->data); }}/*********************************************** 递归遍历二叉树演示************************************************/void RsTreeDemo(tree*root){ printf("\nthe PrePath is:"); RsPrePath(root); printf("\nthe MidPath is:"); RsMidPath(root); printf("\nthe LastPath is:"); RsLastPath(root);}/************************************************ 用树形表示法输出树*************************************************/void DispTree(tree *root,int x,int y,int n)     /*n用来控制第一层树的高度*/{ int i=0; if(root !=NULL)  {    gotoxy(x,y);                               /*到相应结点输出*/    printf("%c",root->data);    if(root->lchild != NULL)                  /*处理左子树,这里只有第一次N为可变的,*/    {       i=1;                                   /*为的是能够输出整棵树,而不会被覆盖,*/       while(ilchild,x-n,y+n,2);       /*递归处理左子树*/     }     if(root->rchild != NULL)    {       i=1;       while(irchild,x+n,y+n,2);       /*递归处理右子树*/     }   }}/***************************************************** 根据DATA域,查找第一个遇到的结点,并返回该结点 *****************************************************/tree* IndexNode(tree *root,char data,int *high,int temp){ if(root == NULL) {    (*high)=0;    return NULL; } else       if(root->data == data)  /*找到所要找的结点*/       {           (*high) = temp;           return root;       }       else       {	   if(IndexNode(root->lchild,data,high,temp+1)==NULL)           {	      IndexNode(root->rchild,data,high,temp+1);/*如果在左子树中没有找到*/           }       }}/**************************************************** 找某一结点的左子树 ****************************************************/tree* FindLchild(tree * node){  if(node !=NULL)  {       return node->lchild;  }  else        return NULL;}/**************************************************** 找某一结点的右子树 ****************************************************/tree* FindRchild(tree * node){if(node !=NULL)  {       return node->rchild;  }  else        return NULL;}/**************************************************** 先序遍历查找所有叶子结点 ****************************************************/void FindLeaft(tree *root){ if(root == NULL)    return; if(root->lchild == NULL && root->rchild == NULL) {    printf("%c ",root->data); } FindLeaft(root->lchild); FindLeaft(root->rchild);}void main(){ tree *root; int high; char str[100]; clrscr(); printf("Please  input the Tree string:"); gets(str); CreateTree(&root,str); printf("\nthe Tree is:"); DispTree(root,10,4,5); gotoxy(2,15); FindLeaft(root); /*printf("\n%c",IndexNode(root,'t',&high,1)->data); printf("\n%d",high);*/ /*RsTreeDemo(root);*/ getch();}


分享到:
评论

相关推荐

    用递归算法实现整数逆序

    ### 用递归算法实现整数逆序 #### 背景与意义 在计算机科学领域,递归算法是一种常用且强大的技术手段。通过将问题分解为更小规模的子问题来解决,递归能够有效地简化复杂度较高的计算任务。本篇文章主要探讨如何...

    VC对磁盘文件遍历搜索的递归算法和非递归算法

    非递归算法在处理大量文件和深目录树时,性能通常优于递归算法,因为它减少了函数调用开销,且内存占用更可控。 **VC++实现细节**: 在提供的`查找指定文件.rar`压缩包中,可能包含了一个VC++工程文件,用于演示非...

    .Net 初学者的树控件和递归算法求阶乘

    在.NET框架中,树控件...总之,.NET初学者在学习过程中应掌握树控件的使用,如创建、操作节点和处理事件,同时理解并能应用递归算法,如求阶乘。通过实践和探索,可以提升编程能力,为后续的.NET开发奠定坚实基础。

    用递归和非递归算法实现二叉树的三种遍历

    之后,你需要分别用递归和非递归算法实现二叉树的三种遍历。递归实现较为直观,而非递归实现需要更深入的理解和技巧,通常涉及栈的使用。 递归算法通常简洁,但对于大型树可能会导致栈溢出。非递归算法虽然代码更...

    程序设计中递归算法

    递归算法的执行过程主要依赖于系统提供的栈结构来实现。在回溯阶段,每次递归调用都会将当前的状态压入栈中;而在递推阶段,则会依次从栈中弹出这些状态,恢复控制流。 #### 六、递归算法的非递归化 尽管递归算法...

    二叉树遍历的非递归算法分析与实现

    ### 二叉树遍历的非递归算法分析与实现 #### 一、引言 在数据结构领域中,二叉树作为一种基本的数据组织形式,其应用极为广泛。对于二叉树的操作,其中最重要的就是遍历操作。遍历是指按照特定顺序访问二叉树的...

    中序遍历二叉树非递归算法

    在实际编程中,中序遍历非递归算法不仅适用于二叉树的遍历,还常用于解决二叉树相关的更复杂问题,如平衡因子的计算、二叉树的镜像翻转等。此外,对于算法的优化,可以考虑动态调整栈的大小,以适应不同规模的二叉树...

    Hanoi塔问题的一种非递归算法

    ### Hanoi塔问题的一种非递归算法:深入解析与实现 #### 一、引言 Hanoi塔问题作为计算机科学领域内经典的递归问题之一,因其简洁性和挑战性而广受关注。通常,Hanoi塔问题的解决方案多采用递归算法,尽管其逻辑...

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

    ### 二叉树先序、中序、后序遍历非递归算法 #### 前言 在计算机科学中,二叉树是一种常见的数据结构,它被广泛应用于各种算法和程序设计中。二叉树的遍历是理解并操作二叉树的基础,通常有三种主要的遍历方式:...

    递归算法应用:删除某一个节点的子树算法

    在数据结构中,递归算法广泛应用于树形结构的操作,例如二叉树的遍历、搜索、插入、删除等操作。今天,我们将讨论递归算法在删除某一个节点的子树算法中的应用。 问题描述:在二叉树中,删除值为 x 的节点,并删除...

    简单的递归算法

    给定的Java代码实现了一个特殊的递归算法来生成斐波那契数列的前n项,但其实现方式并非标准的递归,而是采用了循环结构。下面对代码进行逐行分析: 1. **类定义与主方法**:`Test` 类包含一个 `main` 方法,用于...

    opengl L系统递归算法实现分形树

    在这个"opengl L系统递归算法实现分形树"的例子中,我们将深入探讨如何利用OpenGL和L系统来创建具有自相似性的分形树。 1. **OpenGL基础知识**: - OpenGL是跨语言、跨平台的图形API,用于渲染2D、3D矢量图形。 -...

    先序遍历非递归算法(C语言)

    根据给定的信息,本文将详细解释三种二叉树非递归遍历算法的实现方法:先序遍历、中序遍历以及后序遍历,并重点介绍先序遍历的非递归算法在C语言中的具体实现。 ### 先序遍历非递归算法(C语言) #### 1. 算法概述...

    程序2_delphi_milemut_递归算法_

    在编程领域,递归算法是一种强大的工具,尤其在处理树形结构或遍历目录时显得尤为重要。本项目“程序2_delphi_milemut_递归算法”是使用Delphi编程语言实现的一个应用,旨在通过递归方法列出指定目录“C:\Windows\...

    题目:编写递归算法,将二叉树中所有结点的左右子树相互交换 - READ.doc

    递归交换算法是二叉树中结点左右子树的交换算法的设计和实现,涉及到树形结构、递归函数、指针操作等多个方面。该算法的设计和实现需要考虑到问题的规模、复杂度和时间复杂度等方面。通过测试结果的分析,可以验证...

    树的遍历前序后序递归算法、层序非递归算法

    递归算法实现如下: ```java void preOrder(Node node) { if (node != null) { System.out.print(node.data + " "); preOrder(node.left); preOrder(node.right); } } ``` 2. **后序遍历**:后序遍历的...

    二叉树非递归遍历算法实现

    这段代码展示了二叉树的非递归遍历算法实现,包括前序遍历、中序遍历和后序遍历。在二叉树的遍历中,递归是一种直观且常见的方法,但非递归遍历则可以避免调用栈过深导致的溢出问题,适用于大型数据结构。 首先,...

    27丨递归树:如何借助树来求解递归算法的时间复杂度?1

    递归树是一种用于分析递归算法时间复杂度的可视化工具,尤其在处理复杂递归关系时,能够简化问题的理解和计算。在递归算法中,我们通常将大问题分解为小问题来解决,这个过程可以抽象成一棵树的结构,即递归树。 ...

    非递归实现二叉树的算法

    ### 非递归实现二叉树的遍历算法 #### 概述 在计算机科学中,二叉树是一种常用的数据结构,它在许多实际应用中都有广泛的应用,如文件系统、编译器的设计等。通常,二叉树的遍历(前序、中序、后序)可以采用递归...

    java递归算法

    总的来说,Java递归算法是解决问题的强大工具,尤其适用于数据结构(如树、图的遍历)、搜索算法(如深度优先搜索)以及解决数学和逻辑问题。然而,理解和调试递归算法可能相对困难,因此在使用时需谨慎。

Global site tag (gtag.js) - Google Analytics