一、二叉树的创建
typedef struct node
{
int nValue;
struct node *lchild;
struct node *rchild;
}BTNode;
1.递归创建
void RecCreateBiTree(BTNode **pRoot)
{
int nNum;
if(pRoot == NULL)return;
cin>>nNum;
if(nNum == 0)return;
//添加节点
*pRoot = new BTNode;
(*pRoot)->nValue = nNum;
(*pRoot)->lchild = NULL;
(*pRoot)->rchild = NULL;
//处理当前节点的左右
RecCreateBiTree(&((*pRoot)->lchild));
RecCreateBiTree(&((*pRoot)->rchild));
}
2.数组创建
BTNode *ArrToBiTree(int arr[],int nLen)
{
BTNode *pTree = NULL;
int i;
if(arr == NULL || nLen <=0)return NULL;
//根据数组长度创建结构体数组
pTree = new BTNode[nLen];
//数组元素拷贝 结构数组赋初值
for(i = 0;i<nLen;i++)
{
pTree[i].nValue = arr[i];
pTree[i].lchild = NULL;
pTree[i].rchild = NULL;
}
//根据左右关系关联
for(i = 0;i < nLen/2; i++)
{
if(2*i+1 < nLen)
pTree[i].lchild = pTree+2*i+1;
if(2*i +2 < nLen)
pTree[i].rchild = pTree+2*i+2;
}
return pTree;
}
二、二叉树的遍历
(一)递归遍历
1.前序遍历
void PreOrderTraversal(BTNode *pRoot)
{
if(pRoot == NULL)return;
//根
cout<<pRoot->nValue<<" ";
//左
PreOrderTraversal(pRoot->lchild);
//右
PreOrderTraversal(pRoot->rchild);
}
2.中序遍历
void InOrderTraversal(BTNode *pRoot)
{
if(pRoot == NULL)return;
//左
InOrderTraversal(pRoot->lchild);
//根
cout<<pRoot->nValue<<" ";
//右
InOrderTraversal(pRoot->rchild);
}
3.后序遍历
void PostOrderTraversal(BTNode *pRoot)
{
if(pRoot == NULL)return;
//左
PostOrderTraversal(pRoot->lchild);
//右
PostOrderTraversal(pRoot->rchild);
//根
cout<<pRoot->nValue<<" ";
}
(二)非递归遍历
1.前序遍历
void PreOrderWithoutRec(BTNode* pRoot)
{
if (pRoot == NULL)return;
BTNode* p = pRoot;
stack<BTNode*> s;
while (!s.empty() || p)
{
//边遍历边打印,并存入栈中
while (p)
{
cout << p->nValue<< " ";
s.push(p);
p = p->lchild;
}
//当p为空时,说明根和左子树都遍历完了,该进入右子树了
if (!s.empty())
{
p = s.top();
s.pop();
p = p->rchild;
}
}
}
2.中序遍历
void InOrderWithoutRec(BTNode* pRoot)
{
if (pRoot == NULL)return;
BTNode* p = pRoot;
stack<BTNode*> s;
while (!s.empty() || p)
{
//一直遍历到左子树最下边,边遍历边保存根节点到栈中
while (p)
{
s.push(p);
p = p->lchild;
}
//当p为空时,说明已经到达左子树最下边,这时需要出栈了
if (!s.empty())
{
p = s.top();
s.pop();
cout << p->nValue<< " ";
//进入右子树,开始新的一轮左子树遍历
p = p->rchild;
}
}
}
3.后序遍历
void PostOrderWithoutRec(BTNode *pRoot)
{
if (pRoot == NULL)return;
BTNode *p = pRoot;
stack<BTNode*> s;
BTNode *pre = NULL;//pre表示最近一次访问的结点
while(!s.empty() || p)
{
//沿着左孩子方向走到最左下 。
while(p)
{
s.push(p);
p = p->lchild;
}
//get the top element of the stack
p = s.top();
//如果p没有右孩子或者其右孩子刚刚被访问过
if(p->rchild == NULL || p->rchild == pre)
{
//visit this element and then pop it
cout << p->nValue << " ";
s.pop();
pre = p;
p = NULL;
}
else
p = p->rchild;
}
}