C++实现二叉树的递归和非递归遍历方法

来源:互联网 发布:windows me 系统安装 编辑:程序博客网 时间:2024/06/07 07:14

     声明:本博客为原创博客,未经允许,不得转载!小伙伴们如果是在别的地方看到的话,建议还是来csdn上看吧(原文链接地址为http://blog.csdn.net/bettarwang/article/details/12867815),毕竟在csdn上看代码和提问、讨论都更方便。

下面是二叉树和各种遍历方法,其中每种遍历方法都给出了递归和非递归的算法。

template<class T>void preOrderTraversal(BTNode<T>*root,bool recursionFlag){if(recursionFlag)//recursionFlag为真时则采用递归方法进行遍历。{if(root!=NULL){cout<<root->data<<' ';//if(root->leftChild!=NULL)//这个虽然可加可不加,但是自己觉得其实加上会更好。   preOrderTraversal(root->leftChild,true);//if(root->rightChild!=NULL)    preOrderTraversal(root->rightChild,true);}}else{BTNode<T>*p,*stack[100];int top=-1;p=root;do {while(p!=NULL){cout<<p->data<<' ';//因为是先序遍历嘛。stack[++top]=p;p=p->leftChild;}p=stack[top--];p=p->rightChild;} while (top>=0||p!=NULL);//之所以是||而不是&&是因为比如p==NULL时可能只是到了叶结点那里,但是此时显然不能结束。又比如根结点出栈之后top=-1,但是此时也应该继续下去,因为还有根结点的右孩子还要遍历嘛。}}//////////////////////////////////下面是中序遍历template<typename T>void inOrderTraversal(BTNode<T>*root,bool recursionFlag){if(recursionFlag){if(root!=NULL){inOrderTraversal(root->leftChild,true);cout<<root->data<<' ';inOrderTraversal(root->rightChild,true);}}else{stack<BTNode<T>*>nodeStack;BTNode<T>*p=root;do {while(p!=NULL){nodeStack.push(p);p=p->leftChild;}p=nodeStack.top();nodeStack.pop();cout<<p->data<<' ';p=p->rightChild;} while (!nodeStack.empty()||p!=NULL);}}///////////////////////////////下面是后序遍历序列。template<class T>void postOrderTraversal(BTNode<T>*root,bool recursionFlag){if(recursionFlag){if(root!=NULL){postOrderTraversal(root->leftChild,true);postOrderTraversal(root->rightChild,true);cout<<root->data<<' ';}}else{stack<BTNode<T>*>nodeStack;BTNode<T>*p=root;stack<int>flagStack;int flag;do {while(p!=NULL){nodeStack.push(p);flagStack.push(1);p=p->leftChild;}p=nodeStack.top();nodeStack.pop();flag=flagStack.top();flagStack.pop();if(flag==1){nodeStack.push(p);flagStack.push(2);p=p->rightChild;}else{cout<<p->data<<' ';p=NULL;//这一句很重要,没有这一句的话就会陷入无穷循环中。}} while (!nodeStack.empty()||p!=NULL);}}////////////////////////////////////////////下面是按层次遍历。也称广度优先遍历。template<class T>void layerOrderTraversal(BTNode<T>*root,bool recursionFlag){if(recursionFlag)//注意:这里即使是递归,也要借助队列。{static deque<BTNode<T>*>nodeQueue;static BTNode<T>*p;if(root==NULL)//注意:这句很重要,它是递归执行的。return;cout<<root->data<<' ';if(root->leftChild!=NULL)nodeQueue.push_back(root->leftChild);if(root->rightChild!=NULL)nodeQueue.push_back(root->rightChild);if(!nodeQueue.empty())//加这个判断条件很重要,没有它的话就会出错。{p=nodeQueue.front();nodeQueue.pop_front();layerOrderTraversal(p,true);}elsereturn;}else{if(root==NULL)return;deque<BTNode<T>*>nodeQueue;    nodeQueue.push_back(root);BTNode<T>*p;while(!nodeQueue.empty()){p=nodeQueue.front();            nodeQueue.pop_front();//注意是pop_front()而不是pop_back(),一定要保证从后面进,从前面出的队列性质。如果从后面进又从后面出的话就变成堆栈了。cout<<p->data<<' ';if(p->leftChild!=NULL)    nodeQueue.push_back(p->leftChild);if(p->rightChild!=NULL)    nodeQueue.push_back(p->rightChild);}}}///////////////////////////////////////template<class T>void depthFirstTraversal(BTNode<T>*root,int flag,bool recursionFlag)//flag==1时为前序遍历,flag==2时为中序遍历。但是这里要写非递归算法比上面的更简洁。{if(recursionFlag){if(flag==1){if(root!=NULL){cout<<root->data<<' ';depthFirstTraversal(root->leftChild,1,true);depthFirstTraversal(root->rightChild,1,true);}}else if(flag==2){if(root!=NULL){depthFirstTraversal(root->leftChild,2,true);cout<<root->data<<' ';depthFirstTraversal(root->rightChild,2,true);}}else{cout<<"flag error!"<<endl;return;}}else{if(flag==1){if(root==NULL)return;stack<BTNode<T>*>nodeStack;BTNode<T>*p;nodeStack.push(root);while(!nodeStack.empty()){p=nodeStack.top();nodeStack.pop();cout<<p->data<<' ';if(p->rightChild!=NULL)//堆栈是先进后出,所以如果要先遍历左子树的话,就要让右子树先进堆栈。nodeStack.push(p->rightChild);if(p->leftChild!=NULL)nodeStack.push(p->leftChild);}}else if(flag==2){if(root==NULL)return;stack<BTNode<T>*>nodeStack;stack<int>flagStack;BTNode<T>*p;nodeStack.push(root);flagStack.push(1);while(!nodeStack.empty()){p=nodeStack.top();if(p->leftChild!=NULL&&flagStack.top()==1){flagStack.pop();flagStack.push(2);flagStack.push(1);nodeStack.push(p->leftChild);//continue; //这个continue是多余的。}else{cout<<p->data<<' ';nodeStack.pop();flagStack.pop();if(p->rightChild!=NULL){nodeStack.push(p->rightChild);flagStack.push(1);}}}}else{cout<<"flag error"<<endl;return;}}}