非递归前序遍历

问题:对一个二叉搜索树进行前序遍历,打印出每个结点的值,但是不能使用递归。

解题:

(1)递归可以用迭代来替代

(2)了解递归的前序遍历中发生了什么:①打印出根节点(或子树根节点)的值;②对左子树进行前序遍历;③对右子树进行前序遍历。

          递归隐式地使用了一个数据结构来存放调用栈上的数据。实际上,递归调用用于隐式地在栈上存储右子树的地址,因此左子树遍历完后,可以继续遍历右子树。每次打印             一个结点,并移动到它的左子树上,它的右子树会首先存放在一个栈上,当没有任何子树时,从一个递归调用中返回,也就是从栈上弹出一个右子树结点。这个过程一直持

         续到栈空为止。

(3)代码实现(核心代码)

         结点的存储结构:

struct Node
{
	int data;//数据域
	Node* left;//指向左孩子的指针
	Node* right;//指向右孩子的指针
};

         思路一:

         与其分别实现左子树和右子树结点的情况,不如将两个结点全部压入栈。这里就要考虑入栈的顺序:将右结点先压入栈,然后是左结点。

void preorderTraversal1(){
		stack<Node*> s;
		s.push(root);
		while (s.size() > 0){
			Node* cur = s.top();
			s.pop();
			cout << cur->data << " ";
			Node* n = cur->right;
			if (n != NULL){
				s.push(n);
			}
			n = cur->left;
			if (n != NULL){
				s.push(n);
			}
		}
		cout << endl;
	}

         思路二:

         程序开始时先将根结点入栈,再弹出结点A栈打印。并将弹出栈的结点A的右结点入栈,并将A移动指向它的左节点。重复以上过程直到栈空。

void preorderTraversal2(){
		stack<Node*> s;
		Node* tmp = root;
		s.push(tmp);
		while (s.size() > 0){
			tmp = s.top();
			s.pop();
			while (tmp != NULL){
				cout << tmp->data << " ";
				if (tmp->right != NULL){
					s.push(tmp->right);
				}
				tmp = tmp->left;
			}
		}
	}


ps:并非全部原创,是阅读《程序员面试攻略》第三版的读书笔记。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.先序遍历非递归算法#define maxsize 100typedef struct{ Bitree Elem[maxsize]; int top;}SqStack;void PreOrderUnrec(Bitree t){ SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子树 { visite(p->data); push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) //通过下一次循环中的内嵌while实现右子树遍历 { p=pop(s); p=p->rchild; }//endif }//endwhile }//PreOrderUnrec2.中序遍历非递归算法#define maxsize 100typedef struct{ Bitree Elem[maxsize]; int top;}SqStack;void InOrderUnrec(Bitree t){ SqStack s; StackInit(s); p=t; while (p!=null || !StackEmpty(s)) { while (p!=null) //遍历左子树 { push(s,p); p=p->lchild; }//endwhile if (!StackEmpty(s)) { p=pop(s); visite(p->data); //访问根结点 p=p->rchild; //通过下一次循环实现右子树遍历 }//endif }//endwhile}//InOrderUnrec3.后序遍历非递归算法#define maxsize 100typedef enum{L,R} tagtype;typedef struct { Bitree ptr; tagtype tag;}stacknode;typedef struct{ stacknode Elem[maxsize]; int top;}SqStack;void PostOrderUnrec(Bitree t){ SqStack s; stacknode x; StackInit(s); p=t; do { while (p!=null) //遍历左子树 { x.ptr = p; x.tag = L; //标记为左子树 push(s,x); p=p->lchild; } while (!StackEmpty(s) && s.Elem[s.top].tag==R) { x = pop(s); p = x.ptr; visite(p->data); //tag为R,表示右子树访问完毕,故访问根结点 } if (!StackEmpty(s)) { s.Elem[s.top].tag =R; //遍历右子树 p=s.Elem[s.top].ptr->rchild; } }while (!StackEmpty(s));}//PostOrderUnrec

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值