树遍历和非递归

利用随机函数产生80个(不大于200且各不相同的)随机整数,用这些整数来生成一棵二树,分别对二叉树进行先序遍历,中序遍历和后序列遍历输出树中结点元素序列。注意:先序遍历输出要求采用非递归来实现。

(2)程序实现的基本思想

1.建立合适的二叉树

程序是以

图1.1

的形式建立的。

2.前序遍历是以stack栈和指针左右子女实现的。

3.前序遍历,中序遍历,后序遍历分别用了递归实现。

4.如建立二叉树,其中随机产生的数值是(因为80个数比较多,所以就以#define Max_size 10,若要以80个数,可#define Max_size 10改成#define Max_size 80):

106   199   95   144   102   164   26   96   87   168

由以上数值可以建立出以下的树:

图1.2

由图1.2可得出他们的前序,中序和后序。

前序序列:106   95   26   87   102   96   199   144   164   168

中序序列:26    87   95   96   102   106 144   164   168   199

后序序列:87    26   96   102 95    168 164   144   199   106

(3)系统流程图

程序步骤:

#include "stdio.h"

#include "conio.h"

#define Max_size 10    /*声明要产生的不同的随机数*/

struct tree    /*声明树的结构*/

{

struct tree *left;

int data;

struct tree *right;

};

typedef struct tree treenode;

typedef treenode *b_tree;        /*声明二叉树链表*/

/*插入二叉树的节点*/

b_tree insert_node(b_tree root,int node)

{

b_tree newnode;

b_tree currentnode;

b_tree parentnode;

newnode=(b_tree)malloc(sizeof(treenode));    /*建立新节点的的内存空间*/

newnode->data=node;

newnode->right=NULL;

newnode->left=NULL;

if(root==NULL)

return newnode;

else

{

currentnode=root;

while(currentnode!=NULL)

{    parentnode=currentnode;

if(currentnode->data>node)           /*值小于上一根节点的就插入到左孩子*/

currentnode=currentnode->left;

else    currentnode=currentnode->right;

}

if(parentnode->data>node)                /*值大于上一根节点的就插入到右孩子*/

parentnode->left=newnode;

else    parentnode->right=newnode;

}

return root;

}

/*建立二叉树*/

b_tree create_btree(int *data,int len)

{

b_tree root=NULL;

int i;

for(i=0;i<len;i++)

root=insert_node(root,data[i]);

return root;

}

void preorder_nonrecursive(b_tree root)

{

b_tree stack[Max_size];

b_tree p;

int top=-1;

int i;

if (root != NULL)

{

top++;                        /* 根节点入栈 */

stack[top] = root;

while (top > -1)              /* 栈不空时循环 */

{

p = stack[top];           /* 出栈并访问该节点 */

top--;

printf("%d\t", p->data);

if (p->right != NULL)     /* 右孩子入栈 */

{

top++;

stack[top] = p->right;

}

if (p->left != NULL)     /* 左孩子入栈 */

{

top++;

stack[top] = p->left;

}

}

}

}

/*二叉树前序遍历--递归*/

void preOrder(b_tree point)

{

if(point!=NULL)

{printf("%d\t",point->data);

preOrder(point->left);

preOrder(point->right);

}

}

/*二叉树中序遍历--递归*/

void inOrder(b_tree point)

{    if(point!=NULL)

{

inOrder(point->left);

printf("%d\t",point->data);

inOrder(point->right);

}

}

/*二叉树后序遍历--递归*/

void postOrder(b_tree point)

{

if(point!=NULL)

{

postOrder(point->left);

postOrder(point->right);

printf("%d\t",point->data);

}

return;

}

/*主函数*/

main()

{

b_tree root=NULL;

int i,j;

int value;

int nodelist[Max_size];

printf("\nThe elements of binary tree:\n");

/*读取数值存到数组中*/

srand((unsigned)time( NULL ));

for( i = 0; i <Max_size;i++ )

{

nodelist[i]=rand()%200+1;

for(j=0;j<i;j++)

if(nodelist[i]==nodelist[j])

{

nodelist[i]=rand()%200+1;

j=0;

}

printf( "%d\t", nodelist[i]);

}

/*建立二叉树*/

root=create_btree(nodelist,Max_size);

/*前序遍历二叉树--非递归*/

printf("\n\nThe non-inorder traversal result is :\n");

preorder_nonrecursive(root);

/*前序遍历二叉树--递归*/

printf("\nThe inorder traversal result is :\n");

preOrder(root);

/*中序遍历二叉树--递归*/

printf("\nThe inorder traversal result is :\n");

inOrder(root);

/*后序遍历二叉树--递归*/

printf("\nThe postOrder traversal result is :\n");

postOrder(root);

getch();

}

(4)系统运行效果图

from: http://www.cnblogs.com/yongfeng/archive/2010/02/10/1666927.html

时间: 2024-12-18 10:22:17

树遍历和非递归的相关文章

二叉树高度,以及栈实现二叉树的先序,中序,后序遍历的非递归操作

求解二叉树的高度 树是递归定义的,所以用递归算法去求一棵二叉树的高度很方便. #include <iostream> #include <cstdio> using namespace std; struct Node { char data; Node *lchild; Node *rchild; }; void High(Node *T, int &h) { if (T == NULL) h = 0; else { int left_h; High(T->lchi

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

二叉树前序.后序和后序遍历(非递归实现) (1)前序     我们知道,前序遍历的顺序是根左右,当根节点不为空时,该节点才可以被打印.目前书上常见对树的遍历都是采用递归的方法实现的,我们知道递归必然会产生中断,也就是有现场信息的保存,如果要实现非递归,那么我们必须自己要有一个栈,用来保存现场信息. 我先给出实现的伪代码,稍后我将解释为什么需要这么做,为何要用到这些条件. 伪代码如下: 1 void PreOrderTraverse(BinaryTree root) 2 { 3    Binary

c/c++二叉树的创建与遍历(非递归遍历左右中,破坏树结构)

二叉树的创建与遍历(非递归遍历左右中,破坏树结构) 创建 二叉树的递归3种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 二叉树的非递归4种遍历方式: 1,先中心,再左树,再右树 2,先左树,再中心,再右树 3,先左树,再右树,再中心 4,层级遍历 二叉树的查找,求高度,求个数,求父节点,复制二叉树,释放二叉树 编译方法,用gcc编译不过去,用g++编译,命令如下: g++ -g nodestack.c nodequeue.c bintree.c

二叉树遍历的非递归

前序遍历的非递归:1.在入栈时增加结果集,不停的取左子树入栈.直到为空.2.假设栈非空,pop栈顶结点.取其右子树作为当前结点,继续第一步.直到栈为空 中序遍历的非递归:1.在入栈时,不停的取左子树入栈,直到为空.2.假设栈非空,pop栈顶结点,增加结点集,取其右子树作为当前结点.继续第一步.直到栈为空 后序遍历的非递归:1.在遍历结点时,总是先将右子树结点入栈,再将左子树结点入栈. 2.假设左子树结点和右子树结点为空或者右子树结点已经訪问过,弹出栈顶元素,标记已訪问结点.增加结果集.直到栈为空

二叉树的递归遍历和非递归遍历(附详细例子)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

二叉树基本操作续二:前序、中序、后序遍历(非递归 迭代方式)

这里给出二叉树三种遍历方式的迭代实现代码.二叉树的递归实现使用系统栈入栈出栈,而非递归的迭代实现方法就是手动维护一个栈,来模拟递归的入栈出栈过程. 本文没有给出用户栈的代码,如果需要结合上篇的测试代码一起测试,则需要自己实现自己的栈,以及基本的pop.push等栈操作函数. 前序迭代遍历: 1 void iter_preorder(tree_pointer ptr) 2 { 3 //前序遍历:先遍历根节点,然后再分别遍历左右子树 4 int top = -1; 5 tree_pointer st

先序遍历的非递归遍历算法

先序遍历的非递归遍历算法: 1 void InOrderTraversal(BinTree BT) 2 { 3 BinTree T=BT; 4 stack S=CreatStack(MaxSize)://创建并初始化堆栈S 5 while(T || !IsEmpty(S)){ 6 While(T){//一直向左并将沿途节点压入堆栈 7 printf("%5d",T->Data);//(访问)打印节点 8 Push(S,T); 9 T=T->left; 10 } 11 if(

二叉树非递归先中后序遍历 及 非递归交换二叉树两个孩子的位置

看到一个非递归交换一个二叉树的左右孩子的位置,于是想实现之,才发现非递归的先中后序遍历都忘记了……于是杂七杂八的写了一些,抄抄资料就实现了,然后实现非递归交换两个孩子的位置还是相当容易的.先直接上代码吧,其实这东西还是得自己写写过一遍的,印象才会更加深刻: #include <iostream> #include <fstream> #include <string> #include <stack> using std::cout; using std::

【数据结构与算法】二叉树深度遍历(非递归)

据说这个笔试面试的时候非常easy考到,所以写到这里. 图示 代码实现 /** * 源代码名称:TreeIteratorNoRecursion.java * 日期:2014-08-23 * 程序功能:二叉树深度遍历(非递归) * 版权:[email protected] * 作者:A2BGeek */ import java.util.Stack; public class TreeIteratorNoRecursion { class TreeNode<T> { private T mNod