二叉树的非递归遍历

来源:互联网 发布:格式化u盘数据恢复 编辑:程序博客网 时间:2024/07/13 11:19

typedef struct NodeType{   int data;   struct NodeType* left;   struct NodeType* right;   NodeType(){left = NULL;right = NULL;};}Node;const int MAX = 100;Node* stack[MAX];int top = -1;int tag[MAX];


1 前序遍历

  从根节点开始的所有的左结点依次入栈,然后从root的左子树的左叶子结点开始回溯,那么此左叶子结点一定没有左子结点,可能会有右子结点。该回溯节点出栈后,将它的右子结点当作根结点,重复上述动作。

void PreOrder(Node* root){while (NULL != root ||top >= 0) {while (NULL != root) {cout << root->data << endl;top++;stack[top] = root;root = root->left;}//从root的左子树的左叶子节点开始回溯if (top >= 0) {Node* cur = stack[top];top--;//回溯完后即出栈root = cur->right;}}}

2 中序遍历
  与前序遍历基本一样,root表示需要入栈的根节点,当root为NULL,并且栈为空时,结束遍历。即所有的树节点都已经入栈过,并且最后都通过回溯的方式出栈了,则表示遍历结束。

void InOrder(Node* root){
//所有的节点都是先将其左子树的根节点入栈,然后从叶子节点开始回溯,回溯完叶子节点后入栈该叶子节点的右子树。如果该叶子节点的右子树为NULL,则继续回溯该叶子节点的父节点。while (NULL != root ||top >= 0) {while (NULL != root) {top++;stack[top] = root;root = root->left;}//从root的左子树的左叶子节点开始回溯if (top >=0) {Node* cur = stack[top];cout << cur->data << endl;top--;//回溯完后即出栈root = cur->right;}}}

3 后序遍历
  从根节点开始的所有的左结点依次入栈,然后将最后一个入栈的左子结点开始回溯。但是入栈的这些左子结点都会被回溯两次。一次是从左子结点返回,一次是从右子结点返回。第一次回溯到该结点不能出栈,必须要先访问其右子结点(可以看作一个根结点,重复上述访问步骤),等到其右子树访问完了后再次回溯到该左子结点时,才能真正出栈。
void PostOrder(Node* root){while (NULL != root ||top >= 0) {while (NULL != root) {top++;stack[top] = root;tag[top] = 0;//默认root的右节点没有访问过(算法保证回溯到root时,则它的左节点一定是访问过的)root = root->left;}//从roo的t左子树的左叶子节点开始回溯if (top >= 0) {Node* cur = stack[top];if (1 == tag[top]) {cout << cur->data << endl;top--;//第二次回溯到该节点后出栈} else {//第一回溯到该节点暂时不出栈root = cur->right;tag[top] = 1;//标识root的右节点已经访问过}}}}


0 0
原创粉丝点击