看了书上的递归算法,想转成非递归算法。
模仿前序遍历二叉树的非递归实现。
element结构体的定义见下边的完整代码。
非递归算法:
void ReBuild1(char* pPreOrder, char* pInOrder, int nTreeLen, Node** pRoot) //模仿前序遍历二叉树的非递归算法
{
element s[TREELEN];
int top = -1;
int leftLen;
if(nTreeLen<=0 || !pPreOrder || !pInOrder)
return;
while(top != -1 || nTreeLen>0)
{
while(nTreeLen>0)
{
Node* pTemp = new Node;
pTemp->chValue = *pPreOrder;
pTemp->pLeft = NULL;
pTemp->pRight = NULL;
*pRoot = pTemp;
char* pLeftEnd = pInOrder;
leftLen = 0;
while(*pPreOrder != *pLeftEnd)
{
leftLen++;
if(leftLen>nTreeLen)
return;
pLeftEnd++;
}
top++;
s[top].pPreOrder = pPreOrder;
s[top].pInOrder = pInOrder;
s[top].leftLen = leftLen;
s[top].len = nTreeLen;
s[top].pRoot = pRoot;
pPreOrder++; //对应ReBuild(pPreOrder+1,pInOrder,leftLen,pRoot->pLeft);
pRoot = &((*pRoot)->pLeft);
nTreeLen = leftLen;
}
if(top != -1)
{
pPreOrder = s[top].pPreOrder;
pInOrder = s[top].pInOrder;
leftLen = s[top].leftLen;
nTreeLen = s[top].len;
pRoot = s[top].pRoot;
top--;
pPreOrder = pPreOrder+leftLen+1; //对应ReBuild(pPreOrder+leftLen+1,pInOrder+leftLen+1,nRightLen,pRoot->pRight);
pInOrder = pInOrder+leftLen+1;
nTreeLen = nTreeLen-leftLen-1;
pRoot = &((*pRoot)->pRight);
}
}
}
把书上递归算法的边界条件稍微改了下。
递归算法:
void ReBuild(char* pPreOrder, char* pInOrder, int nTreeLen, Node* &pRoot) //递归 不带返回值
{
if(nTreeLen <= 0 || !pPreOrder || !pInOrder)
return;
Node* pTemp = new Node;
pTemp->chValue = *pPreOrder;
pTemp->pLeft = NULL;
pTemp->pRight = NULL;
pRoot = pTemp;
char* pLeftEnd = pInOrder;
int leftLen = 0;
while(*pPreOrder != *pLeftEnd)
{
leftLen++;
if(leftLen>nTreeLen)
return;
pLeftEnd++;
}
int nRightLen = nTreeLen-leftLen-1;
ReBuild(pPreOrder+1,pInOrder,leftLen,pRoot->pLeft);
ReBuild(pPreOrder+leftLen+1,pInOrder+leftLen+1,nRightLen,pRoot->pRight);
}
#include<iostream>
using namespace std;
#define TREELEN 6
struct Node
{
Node* pLeft;
Node* pRight;
char chValue;
};
struct element
{
char* pPreOrder;
char* pInOrder;
int leftLen;
int len;
Node** pRoot;
};
void ReBuild(char* pPreOrder, char* pInOrder, int nTreeLen, Node* &pRoot) //递归 不带返回值
{
if(nTreeLen <= 0 || !pPreOrder || !pInOrder)
return;
Node* pTemp = new Node;
pTemp->chValue = *pPreOrder;
pTemp->pLeft = NULL;
pTemp->pRight = NULL;
pRoot = pTemp;
char* pLeftEnd = pInOrder;
int leftLen = 0;
while(*pPreOrder != *pLeftEnd)
{
leftLen++;
if(leftLen>nTreeLen)
return;
pLeftEnd++;
}
int nRightLen = nTreeLen-leftLen-1;
ReBuild(pPreOrder+1,pInOrder,leftLen,pRoot->pLeft);
ReBuild(pPreOrder+leftLen+1,pInOrder+leftLen+1,nRightLen,pRoot->pRight);
}
void ReBuild1(char* pPreOrder, char* pInOrder, int nTreeLen, Node** pRoot) //模仿前序遍历二叉树的非递归算法
{
element s[TREELEN];
int top = -1;
int leftLen;
if(nTreeLen<=0 || !pPreOrder || !pInOrder)
return;
while(top != -1 || nTreeLen>0)
{
while(nTreeLen>0)
{
Node* pTemp = new Node;
pTemp->chValue = *pPreOrder;
pTemp->pLeft = NULL;
pTemp->pRight = NULL;
*pRoot = pTemp;
char* pLeftEnd = pInOrder;
leftLen = 0;
while(*pPreOrder != *pLeftEnd)
{
leftLen++;
if(leftLen>nTreeLen)
return;
pLeftEnd++;
}
top++;
s[top].pPreOrder = pPreOrder;
s[top].pInOrder = pInOrder;
s[top].leftLen = leftLen;
s[top].len = nTreeLen;
s[top].pRoot = pRoot;
pPreOrder++; //对应ReBuild(pPreOrder+1,pInOrder,leftLen,pRoot->pLeft);
pRoot = &((*pRoot)->pLeft);
nTreeLen = leftLen;
}
if(top != -1)
{
pPreOrder = s[top].pPreOrder;
pInOrder = s[top].pInOrder;
leftLen = s[top].leftLen;
nTreeLen = s[top].len;
pRoot = s[top].pRoot;
top--;
pPreOrder = pPreOrder+leftLen+1; //对应ReBuild(pPreOrder+leftLen+1,pInOrder+leftLen+1,nRightLen,pRoot->pRight);
pInOrder = pInOrder+leftLen+1;
nTreeLen = nTreeLen-leftLen-1;
pRoot = &((*pRoot)->pRight);
}
}
}
Node* ReBuild2(char* pPreOrder, char* pInOrder, int nTreeLen) //递归 带返回值
{
if(nTreeLen<=0 || !pPreOrder || !pInOrder)
return NULL;
Node* pTemp = new Node;
pTemp->chValue = *pPreOrder;
int leftLen = 0;
char* pEnd = pInOrder;
while(*pPreOrder != *pEnd)
{
leftLen++;
pEnd++;
if(leftLen > nTreeLen)
return NULL;
}
int rightLen = nTreeLen - leftLen - 1;
pTemp->pLeft = ReBuild2(pPreOrder+1,pInOrder,leftLen);
pTemp->pRight = ReBuild2(pPreOrder+leftLen+1,pEnd+1,rightLen);
return pTemp;
}
void PreOrder(Node* root)
{
if(root == NULL) return;
cout<<root->chValue<<endl;
PreOrder(root->pLeft);
PreOrder(root->pRight);
delete root; //释放内存
}
int main()
{
char preOrder[TREELEN]={'a','b','d','c','e','f'};
char inOrder[TREELEN]={'d','b','a','e','c','f'};
Node* pRoot = NULL;
ReBuild(preOrder,inOrder,TREELEN,pRoot);
PreOrder(pRoot); //释放内存
cout<<"************************"<<endl;
ReBuild1(preOrder,inOrder,TREELEN,&pRoot);
PreOrder(pRoot); //释放内存
cout<<"************************"<<endl;
pRoot = ReBuild2(preOrder,inOrder,TREELEN);
PreOrder(pRoot); //释放内存
system("pause");
return 0;
}