题目来自剑指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。
建立的树为: