树的非递归遍历
2016-03-01 23:28
211 查看
树是递归定义的,利用递归算法遍历树实现起来比较简单,然而难的是非递归遍历。非递归遍历需要借助栈这一数据结构来完成。
首先定义树的结点和构建链表栈:
1.非递归前序遍历:
思想:(1)访问结点p,并将节点p进栈。如p的左孩子不为空,这将p的左孩子置为结点p,重复(1);若p的左孩子为空,这获取栈顶值并出栈,栈顶结点的右孩子赋给p,重复(1),如栈为空且p==NULL,则遍历结束。
思想:
对于任意结点p
(1)若左孩子不为空,则将p进栈并将p的左孩子置为当前的p,然后对当前结点p进行同样处理。
(2)若左孩子为空,这访问该结点,并将栈顶元素出栈且将p置为栈顶元素的右孩子,进行(1)操作。
(3)知道p为空且栈顶元素为空时遍历结束。
首先定义树的结点和构建链表栈:
//定义树的节点 typedef struct Node { int data; struct Node* lchild; struct Node* rchild; }Node; //定义栈节点 typedef struct Stacknode { Node* tnode; struct Stacknode* next; }Stacknode; //构建栈 typedef struct Stacktree { struct Stacknode* top; }Stacktree; //初始化栈 void init_stack(Stacktree* T) { T->top=NULL; } //判断栈是否为空 int is_stack_empty(Stacktree* T) { if(T->top==NULL) return 1; return 0; } //获取栈顶值 Node* get_stack_topvalue(Stacktree* T) { if(is_stack_empty(T)) { return (Node*)-1; } return T->top->tnode; } //进栈 void Push(Stacktree* T,Node* value) { if(T==NULL) { return ; } Stacknode* newnode=(Stacknode*)malloc(1*sizeof(Stacknode)); newnode->tnode=value; newnode->next=T->top; T->top=newnode; } //出栈 void Pop(Stacktree* T) { if(is_stack_empty(T)) { return ; } Stacknode* tmp=T->top; T->top=T->top->next; free(tmp); tmp=NULL; }创建树:
Node* create_tree() { int _data; scanf("%d",&_data); if(_data==-1) { return NULL; } Node* root=(Node*)malloc(1*sizeof(Node)); root->data=_data; root->lchild=create_tree(); root->rchild=create_tree(); return root; }遍历:
1.非递归前序遍历:
思想:(1)访问结点p,并将节点p进栈。如p的左孩子不为空,这将p的左孩子置为结点p,重复(1);若p的左孩子为空,这获取栈顶值并出栈,栈顶结点的右孩子赋给p,重复(1),如栈为空且p==NULL,则遍历结束。
void pre_print(Node* root) { if(root) { Stacktree st; init_stack(&st); while(root!=NULL || !is_stack_empty(&st)) { while(root!=NULL) { printf("%d\t",root->data); Push(&st,root); root=root->lchild; } if(!is_stack_empty(&st)) { root=get_stack_topvalue(&st); Pop(&st); root=root->rchild; } } printf("\n"); } }2.非递归中序遍历:
思想:
对于任意结点p
(1)若左孩子不为空,则将p进栈并将p的左孩子置为当前的p,然后对当前结点p进行同样处理。
(2)若左孩子为空,这访问该结点,并将栈顶元素出栈且将p置为栈顶元素的右孩子,进行(1)操作。
(3)知道p为空且栈顶元素为空时遍历结束。
void mid_print(Node* root) { if(root) { Stacktree st; init_stack(&st); while(root!=NULL || !is_stack_empty(&st)) { while(root!=NULL) { Push(&st,root); root=root->lchild; } if(!is_stack_empty(&st)) { root=get_stack_topvalue(&st); Pop(&st); printf("%d\t",root->data); root=root->rchild; } } } }
相关文章推荐
- AVL树-自平衡二叉查找树(Java实现)
- 文件遍历排序函数
- Lua 学习笔记之C API 遍历 Table实现代码
- C#遍历文件夹后上传文件夹中所有文件错误案例分析
- C#中遍历Hashtable的4种方法
- Erlang中遍历取出某个位置的最大值代码
- C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析
- C++实现图的邻接表存储和广度优先遍历实例分析
- C语言二叉树的非递归遍历实例分析
- 使用C语言构建基本的二叉树数据结构
- 一波二叉树遍历问题的C++解答实例分享
- C++非递归队列实现二叉树的广度优先遍历
- php遍历目录方法小结
- 一个目录遍历函数
- php遍历删除整个目录及文件的方法
- PHP遍历文件夹与文件类及处理类用法实例
- PHP遍历XML文档所有节点的方法
- php中使用key,value,current,next和prev函数遍历数组的方法
- C#使用前序遍历、中序遍历和后序遍历打印二叉树的方法
- 平衡二叉树