先序遍历和中序遍历非递归代码:
#include <iostream> #include <vector> using namespace std; typedef struct BinaryTree { int data; struct BinaryTree *rchild, *lchild; }BinaryTree; int createBinaryTree( BinaryTree * &T) //必须用引用 因为内存是在函数里面分配的 { int ch; scanf("%d", &ch); if(ch != 0) { T = (BinaryTree *)malloc(sizeof(BinaryTree)); T->data = ch; createBinaryTree(T->lchild); createBinaryTree(T->rchild); } else { T = NULL; } return 0; } int visit(int data) { printf("%d ", data); return 0; } int PreOrderTraverse(BinaryTree T) //先序遍历 { BinaryTree* p; vector<BinaryTree *> Stack; Stack.push_back(&T); while(!Stack.empty()) { while((p = Stack.back()) != NULL) { visit(p->data); Stack.push_back(p->lchild); } Stack.pop_back(); if(!Stack.empty()) { p = Stack.back(); Stack.pop_back(); Stack.push_back(p->rchild); } } return 0; } int InOrderTraverse(BinaryTree T) //中序遍历 { BinaryTree* p; vector<BinaryTree *> Stack; Stack.push_back(&T); while(!Stack.empty()) { while((p = Stack.back()) != NULL) Stack.push_back(p->lchild); Stack.pop_back(); if(!Stack.empty()) { p = Stack.back(); Stack.pop_back(); visit(p->data); Stack.push_back(p->rchild); } } return 0; } int main() { BinaryTree * T = NULL; createBinaryTree(T); PreOrderTraverse(*T); InOrderTraverse(*T); return 0; }
注意理清楚弹栈的机制。
---------------------------------
今天参考了一下别人的思路 补上后序遍历非递归算法 注意如何设置在右子树弹出时双亲结点的访问和弹出
int AferOrderTraverse(BinaryTree T) //后序遍历 { BinaryTree * p; vector<BinaryTree *> Stack; int tag[30] = {0}; //用tag标签记录存入的是左子树0 还是右子树1 int tagnum = 0; //记录存放的数量 Stack.push_back(&T); tag[0] = 0; tagnum = 1; while(!Stack.empty()) { while((p = Stack.back())!= NULL) { Stack.push_back(p->lchild); tag[tagnum++] = 0; } //只要右子树弹出,其双亲结点就被访问并弹出 while(tag[tagnum - 1] == 1) //若是右子树 先弹出开始的空集 访问其parent结点(一定是其上一个结点) 再循环弹出 { Stack.pop_back(); tagnum--; visit(Stack.back()->data); } Stack.pop_back(); tagnum--; if(!Stack.empty()) { p = Stack.back(); Stack.push_back(p->rchild); tag[tagnum++] = 1; } } return 0; }