非递归方式建树并按任一种非递归遍历次序输出二叉树中

合集下载

二叉树递归先序,非递归中序,递归后序,非递归层次遍历(输入以#结束)

二叉树递归先序,非递归中序,递归后序,非递归层次遍历(输入以#结束)
stack<BiTree> s;
BiTree curr = T->lchild; // 指向当前要检查的节点
s.push(T);
while(curr != NULL || !s.empty())
{
while(curr != NULL) // 一直向左走
if(queue[front]->rchild!=NULL)
{
queue[rear]=queue[front]->rchild; //将队首结点的右孩子指针入队列
rear++; //队尾指针后移一位
}
printf("| 5.退出程序 |\n");
printf("|--------------------------------------------------------------|\n");
printf("| 1.递归先序遍历 |\n");
printf("| 2.非递归中序遍历 |\n");
printf("| 二叉树的基本操作如下: |\n");
printf("| 0.创建二叉树 |\n");
PostOrder(root->rchild); //递归调用,前序遍历右子树
printf("%c ", root->data); //输出数据
}
int visit(BiTree T)
{
if(T)
{
printf("%c ",T->data);
{
printf("非递归中序遍历二叉树:");

递归非递归两种算法遍历二叉树讲解

递归非递归两种算法遍历二叉树讲解

一、设计思想1. 用递归算法遍历设计思想:主要是通过不同程序顺序,从而实现递归的顺序遍历前序遍历:先判断节点是否为空,如果不为空,则输出。

再判断左节点是否为空,如果不为空,则递归调用,直到遍历到最左边。

接着再遍历最左边的右子树,如果此时右子树不为空,则递归遍历左子树的操作,直到遍历到叶子节点。

如果右子树为空,则回溯上次的递归调用,重复输出和遍历右子树的操作。

中序遍历:先遍历左节点是否为空,如果不为空,则递归调用,直到遍历到最左边或者叶子节点,然后输出,接着再遍历最左边的右子树,如果此时右子树不为空,则递归重复遍历左子树的操作,直到遍历到叶子节点。

如果右子树为空,则回溯到上次递归调用,重复输出和遍历右子树的操作。

后序遍历:先判断左节点是否为空,如果不为空则一直递归直到遍历到最左边,然后遍历右节点,再接着遍历到左子树的最右边,直到遍历到叶子节点。

此时输出,回溯到上次递归,继续执行后面的操作,重复,直到将整个树遍历完毕。

2. 用非递归算法遍历设计思想:主要是通过栈的存取,判空,从而实现树的遍历前序遍历:通过一个循环实现。

先输出节点的数值,因为栈的特性,则需要先判断右子树是否为空,如果不为空,则将右子树压栈。

然后判断左子树是否为空,如果不为空,则将左子树压栈。

接着再将栈里面的子树弹出赋给给当前节点变量,重复上述操作,直到栈为空后退出循环。

中序遍历:通过循环实现。

将树一直遍历到最左端,并将中间所经过的节点保存在栈中,当遍历到最左边的时候,则弹出栈里面的子树。

输出数值,将当前节点赋值为当前节点的右子树,遍历右子树,即重复上述操作,直到当前节点为空,并且栈内元素为0。

后序遍历:通过循环和标记栈实现。

将数一直遍历到最左端,并将中间的节点保存在树栈中,同时同步的添加一个标记栈。

当遍历到最左边的时候,弹栈并赋值给当前栈,然后判断标记栈的数值,如果数值为0的话则代表当前树没有遍历过,遍历右子树。

然后重复上面的操作,如果数值为1的话则代表此时数已经遍历过了,可以开始输出了,为了避免重复输出,将当前栈赋为空。

递归非递归两种算法遍历二叉树讲解

递归非递归两种算法遍历二叉树讲解

用递归、非递归两种方法遍历二叉树一、设计思想1. 用递归算法遍历设计思想:主要是通过不同程序顺序,从而实现递归的顺序遍历前序遍历:先判断节点是否为空,如果不为空,则输出。

再判断左节点是否为空,如果不为空,则递归调用,直到遍历到最左边。

接着再遍历最左边的右子树,如果此时右子树不为空,则递归遍历左子树的操作,直到遍历到叶子节点。

如果右子树为空,则回溯上次的递归调用,重复输出和遍历右子树的操作。

中序遍历:先遍历左节点是否为空,如果不为空,则递归调用,直到遍历到最左边或者叶子节点,然后输出,接着再遍历最左边的右子树,如果此时右子树不为空,则递归重复遍历左子树的操作,直到遍历到叶子节点。

如果右子树为空,则回溯到上次递归调用,重复输出和遍历右子树的操作。

后序遍历:先判断左节点是否为空,如果不为空则一直递归直到遍历到最左边,然后遍历右节点,再接着遍历到左子树的最右边,直到遍历到叶子节点。

此时输出,回溯到上次递归,继续执行后面的操作,重复,直到将整个树遍历完毕。

2. 用非递归算法遍历设计思想:主要是通过栈的存取,判空,从而实现树的遍历前序遍历:通过一个循环实现。

先输出节点的数值,因为栈的特性,则需要先判断右子树是否为空,如果不为空,则将右子树压栈。

然后判断左子树是否为空,如果不为空,则将左子树压栈。

接着再将栈里面的子树弹出赋给给当前节点变量,重复上述操作,直到栈为空后退出循环。

中序遍历:通过循环实现。

将树一直遍历到最左端,并将中间所经过的节点保存在栈中,当遍历到最左边的时候,则弹出栈里面的子树。

输出数值,将当前节点赋值为当前节点的右子树,遍历右子树,即重复上述操作,直到当前节点为空,并且栈内元素为0。

后序遍历:通过循环和标记栈实现。

将数一直遍历到最左端,并将中间的节点保存在树栈中,同时同步的添加一个标记栈。

当遍历到最左边的时候,弹栈并赋值给当前栈,然后判断标记栈的数值,如果数值为0的话则代表当前树没有遍历过,遍历右子树。

用递归-非递归两种方法遍历二叉树

用递归-非递归两种方法遍历二叉树

一、设计思想递归实现二叉树遍历的思想:1.要遍历二叉树首先的问题是创建二叉树。

二叉树的创建可以采用很多的方法。

例如:先序,中序,后序,还可以采用层次的方法创建二叉树。

本程序采用的是先序递归的方式创建的二叉树。

2.然后是中序,先序,后序递归遍历二叉树。

递归的思想是一直调用方法本身。

3.中序递归遍历二叉树的思想是先访问左子树,然后访问根节点,最后访问右子树。

当访问左子树或是右子树的时候,实际上调用的是函数本身。

在这里就体现了递归的思想,当函数的返回值是0的时候,则返回上一次的程序,继续执行下面的语句。

4.先序递归遍历二叉树的思想是先访问根节点,然后访问左子树,最后访问右子树。

同样如步骤3的方式相同,当访问左子树或者是右子树的收,实际上调用的是函数本身,直到返回值是0的时候,返回上一层的程序继续执行。

5.后序递归遍历二叉树的思想是先访问左子树,然后访问右子树,最后访问根节点。

同样跟步骤3的方式相同,当访问左子树或者右子树的时候实际上是调用的是方法本直到有返回值的时候才返回上一层的程序,继续执行.非递归实现二叉树遍历的思想:1.跟递归遍历二叉树的前提一样,首先应该创建一个二叉树,同样使用先序递归的方式创建二叉树。

2.然后是中序,先序,后序非递归遍历二叉树。

3.中序非递归遍历二叉树的思想是:首先是根节点压栈,当根节点的左子树不是空的时候,左子树压栈。

直到左子树为空的时候,不再压栈。

将栈顶元素出栈,访问栈顶元素,并将栈顶的右子树进栈。

当右子树的左子树不是空的时候,左子树一直进栈,直到左子树为空,则不再进栈。

重复上面的操作,直到栈空的时候。

4.先序非递归遍历二叉树的思想是:首先是根节点进栈,然后当栈不为空的时候,将栈顶元素出栈,然后访问。

同时将出栈元素的右子树进栈,左子树进栈。

重复上面的操作,直到栈为空。

5.后序非递归遍历二叉树的思想:首先是根节点进栈,当根节点的左子树不为空的时候,左子树进栈,直到左为空的时候,左子树不再进栈。

非递归实现二叉树先序、中序和后序遍历

非递归实现二叉树先序、中序和后序遍历

⾮递归实现⼆叉树先序、中序和后序遍历⽤递归⽅式实现⼆叉树先序、中序和后序遍历很简单。

⽤递归⽅法解决的问题都能⽤⾮递归的⽅法实现。

递归就是利⽤函数栈来保存信息,如果⽤⾃⼰申请的数据结构来代替函数栈,也可以实现相同的功能。

⽤⾮递归的⽅式实现⼆叉树的先序遍历(LeetCode144):1、申请⼀个栈stack,然后将头节点压⼊stack中。

2、从stack中弹出栈顶节点,打印,再将其右孩⼦节点(不为空的话)先压⼊stack中,最后将其左孩⼦节点(不为空的话)压⼊stack中。

3、不断重复步骤2,直到stack为空,全部过程结束。

1/**2 * Definition for a binary tree node.3 * public class TreeNode {4 * int val;5 * TreeNode left;6 * TreeNode right;7 * TreeNode(int x) { val = x; }8 * }9*/10import java.util.*;11class Solution {12public List<Integer> preorderTraversal(TreeNode root) {13 List<Integer> list=new ArrayList<Integer>();14 Stack<TreeNode> stack=new Stack<TreeNode>();15if (root!=null) {16 stack.push(root);17while(!stack.empty()) {18 TreeNode tr=stack.pop();19 list.add(tr.val);20if(tr.right!=null) {21 stack.push(tr.right);22 }23if(tr.left!=null) {24 stack.push(tr.left);25 }26 }27 }28return list;29 }30 }⽤⾮递归的⽅式实现⼆叉树的中序遍历(LeetCode94):1、申请⼀个栈stack,初始时令cur=head2、先把cur压⼊栈中,依次把左边界压⼊栈中,即不停的令cur=cur.left,重复步骤23、不断重复2,直到为null,从stack中弹出⼀个节点,记为node,打印node的值,并令cur=node.right,重复步骤24、当stack为空且cur为空时,整个过程停⽌。

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

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

二叉树中序遍历的非递归算法实现二叉树的中序遍历是指先遍历左子树,再遍历根节点,最后遍历右子树的过程。

下面我们将通过非递归算法来实现二叉树的中序遍历。

首先,我们需要定义一个栈来辅助我们进行中序遍历。

接着,我们从根节点开始,将所有左子节点入栈直至没有左子节点为止。

然后弹出栈顶节点并输出,再将其右子节点入栈。

接着继续对右子节点进行相同的操作,直至栈为空为止。

下面我们来详细讲解一下如何使用非递归算法实现二叉树的中序遍历。

首先,我们定义一个栈用于辅助遍历:stack<TreeNode*> s;然后,我们定义一个指针p指向根节点,并进行循环操作直至栈为空:while(p || !s.empty()) {while(p) {s.push(p); //将当前节点入栈p = p->left; //继续遍历左子树}p = s.top(); //弹出栈顶节点并输出s.pop();cout << p->val << " ";p = p->right; //将右子节点入栈}我们先来看一下这个算法的流程。

首先,我们定义一个栈s和一个指针p,指针p初始指向二叉树的根节点。

然后我们进入一个while 循环,条件是指针p不为空或者栈不为空。

在循环内部,我们首先对左子树进行遍历,将遇到的节点依次入栈。

当左子树遍历完毕后,我们弹出栈顶节点并输出,然后将指针p指向当前节点的右子节点,继续遍历右子树。

直至栈为空,说明遍历结束。

这种非递归算法实现二叉树的中序遍历的时间复杂度为O(n),其中n为节点的个数。

空间复杂度为O(n),因为栈中最多同时保存树中所有节点。

算法的实现比较简单,代码也比较清晰易懂,适合在实际应用中使用。

下面我们将通过一个具体的例子来演示这个算法是如何工作的。

假设我们有如下的二叉树:1/ \2 3/ \4 5首先,我们定义一个根节点指针p指向根节点1。

c语言非递归遍历二叉树

c语言非递归遍历二叉树

c语言非递归遍历二叉树C语言非递归遍历二叉树二叉树是一种常见的数据结构,其遍历方式有前序遍历、中序遍历和后序遍历三种。

在C语言中,我们可以使用递归和非递归两种方式来实现二叉树的遍历。

本文将介绍如何使用非递归方式来实现二叉树的遍历。

1. 前序遍历前序遍历的顺序是先访问根节点,然后访问左子树,最后访问右子树。

使用非递归方式实现前序遍历可以使用栈来辅助实现。

具体步骤如下:1. 将根节点入栈。

2. 当栈不为空时,弹出一个节点并访问它。

3. 如果该节点有右子节点,则将右子节点入栈。

4. 如果该节点有左子节点,则将左子节点入栈。

5. 重复步骤2-4直到所有节点都被访问过。

以下是代码示例:```cvoid preOrderTraversal(TreeNode* root) { if (root == NULL) {return;}Stack* stack = createStack();push(stack, root);while (!isEmpty(stack)) {TreeNode* node = pop(stack);printf("%d ", node->val);if (node->right != NULL) {push(stack, node->right);}if (node->left != NULL) {push(stack, node->left);}}destroyStack(stack);}```2. 中序遍历中序遍历的顺序是先访问左子树,然后访问根节点,最后访问右子树。

使用非递归方式实现中序遍历同样可以使用栈来辅助实现。

具体步骤如下:1. 将根节点入栈。

2. 如果该节点有左子节点,则将左子节点入栈。

3. 如果该节点没有左子节点,则弹出一个节点并访问它,如果该节点有右子节点,则将右子节点入栈。

4. 重复步骤2-3直到所有节点都被访问过。

c语言二叉树 非递归创建

c语言二叉树 非递归创建

C语言二叉树的非递归创建介绍二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。

在C 语言中,我们可以使用递归或非递归的方式来创建二叉树。

本文将介绍如何使用非递归的方式创建二叉树,并提供相应的代码示例。

非递归创建二叉树的思路非递归创建二叉树的思路是使用栈来辅助实现。

我们可以按照先序遍历的方式输入节点的值,如果输入的值不为空,则创建一个新节点,并将其压入栈中。

然后从栈中取出一个节点,再次输入左子节点的值,如果不为空则创建新节点,并将其作为当前节点的左子节点,同时将新节点压入栈中。

接着输入右子节点的值,如果不为空则创建新节点,并将其作为当前节点的右子节点,同时将新节点压入栈中。

重复以上步骤,直到栈为空。

代码示例下面是一个用C语言实现的非递归创建二叉树的代码示例:#include <stdio.h>#include <stdlib.h>typedef struct TreeNode {int value;struct TreeNode* left;struct TreeNode* right;} TreeNode;typedef struct StackNode {TreeNode* treeNode;struct StackNode* next;} StackNode;void push(StackNode** top, TreeNode* treeNode) {StackNode* stackNode = (StackNode*)malloc(sizeof(StackNode));stackNode->treeNode = treeNode;stackNode->next = *top;*top = stackNode;}TreeNode* pop(StackNode** top) {if (*top == NULL) {return NULL;}TreeNode* treeNode = (*top)->treeNode;StackNode* temp = *top;*top = (*top)->next;free(temp);return treeNode;}TreeNode* createBinaryTree() {int value;TreeNode* root = NULL;printf("请输入根节点的值(-1表示空节点):");scanf("%d", &value);if (value == -1) {return NULL;}root = (TreeNode*)malloc(sizeof(TreeNode));root->value = value;root->left = root->right = NULL;StackNode* stack = NULL;push(&stack, root);while (stack != NULL) {TreeNode* currentNode = pop(&stack);printf("请输入节点%d的左子节点的值(-1表示空节点):", currentNode->v alue);scanf("%d", &value);if (value != -1) {TreeNode* leftNode = (TreeNode*)malloc(sizeof(TreeNode));leftNode->value = value;leftNode->left = leftNode->right = NULL;currentNode->left = leftNode;push(&stack, leftNode);}printf("请输入节点%d的右子节点的值(-1表示空节点):", currentNode->v alue);scanf("%d", &value);if (value != -1) {TreeNode* rightNode = (TreeNode*)malloc(sizeof(TreeNode));rightNode->value = value;rightNode->left = rightNode->right = NULL;currentNode->right = rightNode;push(&stack, rightNode);}}return root;}void preOrderTraversal(TreeNode* root) {if (root == NULL) {return;}printf("%d ", root->value);preOrderTraversal(root->left);preOrderTraversal(root->right);}int main() {TreeNode* root = createBinaryTree();printf("先序遍历结果:");preOrderTraversal(root);printf("\n");return 0;}使用说明1.运行程序后,按照提示输入根节点的值。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

//非递归方式建树,并按任一种非递归遍历次序输出二叉树中的所有结点;
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MaxSize 50
typedef char ElemType;
typedef struct TNode{
ElemType data;
struct TNode *lchild,*rchild;
}BTree;
//------------------------------------------------------------------------------
ElemType str[]="A(B(C(D,E(F,G(,H))),I(J,K(L))),M)"; //"A(B(D,E(G,H(I))),C(F))";
//------------------------------------------------------------------------------
void CreateBTree(BTree **T,ElemType *Str); //非递归建树;
void TraverseBTree(BTree *T); //选择非递归算法的遍历方式;
void PreOrderUnrec(BTree *T); //先序遍历非递归算法;
void InOrderUnrec(BTree *T); //中序遍历非递归算法;
void PostOrderUnrec(BTree *T); //后序遍历非递归算法;
//------------------------------------------------------------------------------
int main(void)
{
BTree *T = NULL; printf("\n二叉树的广义表格式为:\n\t"); puts(str);
CreateBTree(&T,str);
TraverseBTree(T);
system("pause"); return 0;
}
//------------------------------------------------------------------------------
void CreateBTree(BTree **T,ElemType *Str)
{ //按二叉树广义表建立对应的二叉树存储结构;
BTree *p = NULL,*Stack[MaxSize];//数组为存储树根结点指针的栈,p为指向树结点的指针; int top = -1; //top为Stack栈的栈顶指针;
char flag; //flag为处理结点的左子树(L)和右子树(R)的标记;
*T = NULL;
while(*Str)
{
if (*Str == '(') {Stack[++top] = p;flag = 'L';} //入栈;
else if(*Str == ')') --top; //出栈;
else if(*Str == ',') flag = 'R';
else
{
if(!(p = (BTree *)malloc(sizeof(BTree)))) exit (1);
p->data = *Str;
p->lchild = p->rchild = NULL; //初始化新结点;
if(*T == NULL) *T = p; //根结点;
else
{
if(flag == 'L') Stack[top]->lchild = p;
if(flag == 'R') Stack[top]->rchild = p;
}
}
++Str;
}
}
//------------------------------------------------------------------------------
void TraverseBTree(BTree *T) //选择非递归算法的遍历方式;
{
int mark;
printf("\n非递归算法遍历方式:\n\t1 --- 前序遍历\n\t2 --- 中序遍历"); printf("\n\t3 --- 后序遍历\n\t4 --- 退出\n请选择:\n");
if(T == NULL) printf("该树为空!\n");
while(T != NULL && scanf("%d",&mark)==1)
{
if(mark==1) {printf("先序遍历:\t");PreOrderUnrec(T);}
else if(mark==2) {printf("中序遍历:\t");InOrderUnrec(T);}
else if(mark==3) {printf("后序遍历:\t");PostOrderUnrec(T);}
else
{
system("cls"); printf("\n二叉树的广义表格式为:\n\t"); puts(str);
printf("\n非递归算法遍历方式:\n\t1 --- 前序遍历\n\t2 --- 中序遍历"); printf("\n\t3 --- 后序遍历\n\t4 --- 退出\n请选择:\n");
printf("数据非法,重新输入!\n");
}
printf("\n");
}
printf("\n请多多指教!by Haroldi.");
}
//------------------------------------------------------------------------------
void PreOrderUnrec(BTree *T) //先序遍历非递归算法;
{
BTree *p = T,*Stack[MaxSize];
int top = -1;
while (p != NULL || top != -1)
{
while (p!=NULL) //遍历左子树;
{
printf("%c ",p->data);
Stack[++top] = p;
p=p->lchild;
}
if (top != -1) //下次while内循环中实现右子树遍历;
{
p = Stack[top--];
p=p->rchild;
}
}
}
//------------------------------------------------------------------------------
void InOrderUnrec(BTree *T) //中序遍历非递归算法;
{
BTree *p = T,*Stack[MaxSize];
int top = -1;
while (p != NULL || top != -1)
{
while (p!=NULL)
{
Stack[++top] = p;
p=p->lchild;
}
if (top != -1)
{
p = Stack[top--];
printf("%c ",p->data);
p=p->rchild;
}
}
}
//------------------------------------------------------------------------------
void PostOrderUnrec(BTree *T) //后序遍历非递归算法;
{
BTree *p = T,*Stack[MaxSize];
int top = -1;
char flag[MaxSize];//标识,若为'R'则说明左右孩子均已遍历,防止再次走过,形成死循环;while(p != NULL || top != -1)
{
while(p != NULL)
{
Stack[++top] = p;
flag[top] = 'L';
p = p->lchild;
}
while(top != -1 && flag[top] == 'R')
{
printf("%c ",Stack[top--]->data); //flag='R',在此退栈;
}
if(top != -1) {flag[top] = 'R'; p = Stack[top]->rchild;}
}
}
//------------------------------------------------------------------------------ 输出结果:。

相关文档
最新文档