题目来自剑指offer
题目:
举例:
思路:类似数据结构中的中序加线索。
具体来说,使用中序遍历的思路,并使用一个变量pLast保存在中序遍历中当前元素pCur的前一个元素。
之后,每处理一个结点,都设置本结点的前驱和上一个结点后继。处理完后,中序遍历的最后一个元素的后继没有被赋值,需要单独赋值为空,其他元素的前驱和后继都已正确赋值完毕。
核心代码
void Convert(BTNode* pRoot,BTNode*& pLast,BTNode*& pHead)
{
if (pRoot == NULL)
{
return;
}
Convert(pRoot->m_pLeft,pLast,pHead);
//处理当前元素
if (pLast == NULL)
{
pHead = pRoot;
}
else
{
pRoot->m_pLeft = pLast;//设置本元素的前驱
pLast->m_pRight = pRoot;//设置上一个元素的后继
}
pLast = pRoot;//记录中序遍历的上一个元素
Convert(pRoot->m_pRight,pLast,pHead);
}
BTNode* Convert(BTNode* pRoot)
{
assert(pRoot);
BTNode* pLast = NULL;
BTNode* pHead = NULL;
Convert(pRoot,pLast,pHead);
//设置最后一个元素的后继
pLast ->m_pRight = NULL;
return pHead;
}
测试代码
#include <iostream>
#include <assert.h>
using namespace std;
struct BTNode
{
int m_nValue;
BTNode* m_pLeft;
BTNode* m_pRight;
};
void Convert(BTNode* pRoot,BTNode*& pLast,BTNode*& pHead)
{
if (pRoot == NULL)
{
return;
}
Convert(pRoot->m_pLeft,pLast,pHead);
//递归当前元素
if (pLast == NULL)
{
pHead = pRoot;
}
else
{
pRoot->m_pLeft = pLast;//设置本元素的前驱
pLast->m_pRight = pRoot;//设置本元素的后继
}
pLast = pRoot;//记录中序遍历的上一个元素
Convert(pRoot->m_pRight,pLast,pHead);
}
BTNode* Convert(BTNode* pRoot)
{
assert(pRoot);
BTNode* pLast = NULL;
BTNode* pHead = NULL;
Convert(pRoot,pLast,pHead);
//设置最后一个元素的后继
pLast ->m_pRight = NULL;
return pHead;
}
void PrintList(BTNode* pHead)
{
assert(pHead);
BTNode* pCur = pHead;
cout<<"从前往后输出链表:"<<endl;
while(pCur->m_pRight)
{
cout<<pCur->m_nValue<<" ";
pCur = pCur->m_pRight;
}
cout<<pCur->m_nValue<<endl;
cout<<"从后往前输出链表:"<<endl;
while(pCur)
{
cout<<pCur->m_nValue<<" ";
pCur = pCur->m_pLeft;
}
cout<<endl;
}
void PrintTree(BTNode* pRoot)
{
if (pRoot == NULL)
{
return;
}
PrintTree(pRoot->m_pLeft);
cout<<pRoot->m_nValue<<" ";
PrintTree(pRoot->m_pRight);
}
void CreatTree(BTNode*& pRoot)
{
int newData;
cin >> newData;
if (-1 == newData)
{
pRoot = NULL;
}
else
{
pRoot = new BTNode;
pRoot->m_nValue = newData;
CreatTree(pRoot->m_pLeft);
CreatTree(pRoot->m_pRight);
}
}
int main()
{
BTNode* pRoot = NULL;
BTNode* pHead = NULL;
CreatTree(pRoot);
cout<<"树的中序遍历:"<<endl;
PrintTree(pRoot);
cout<<endl;
pHead = Convert(pRoot);
PrintList(pHead);
system("pause");
return 1;
}
代码测试:
这里并没有真正简历一个二叉搜索树,而是简单的建立一个普通的二叉树,且数组元素满足二叉搜索树树的性质。
举例:建树算法如树的子结构
输入:10 6 4 -1 -1 8 -1 -1 14 12 -1 -1 16 -1 -1,其中-1表示NULL。
建立的树为: