當(dāng)前位置:
首頁 >
二叉树构建及双向链表
發(fā)布時(shí)間:2024/4/11
23
豆豆
生活随笔
收集整理的這篇文章主要介紹了
二叉树构建及双向链表
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
二叉樹構(gòu)建及雙向鏈表
文章目錄
- 二叉樹構(gòu)建及雙向鏈表
- 一、從前序與中序遍歷序列構(gòu)造二叉樹
- 代碼
- 二、從中序與后序遍歷序列構(gòu)造二叉樹
- 代碼
- 三、二叉搜索樹轉(zhuǎn)雙向鏈表
- 代碼
一、從前序與中序遍歷序列構(gòu)造二叉樹
根據(jù)一棵樹的前序遍歷與中序遍歷構(gòu)造二叉樹。
注意: 你可以假設(shè)樹中沒有重復(fù)的元素。例如,給出前序遍歷 preorder = [3,9,20,15,7] 中序遍歷 inorder = [9,3,15,20,7] 返回如下的二叉樹:3/ \9 20/ \15 7代碼
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { private:unordered_map<int, int> index;public:TreeNode* myBuildTree(const vector<int>& preorder, const vector<int>& inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {if (preorder_left > preorder_right) {return nullptr;}// 前序遍歷中的第一個(gè)節(jié)點(diǎn)就是根節(jié)點(diǎn)int preorder_root = preorder_left;// 在中序遍歷中定位根節(jié)點(diǎn)int inorder_root = index[preorder[preorder_root]];// 先把根節(jié)點(diǎn)建立出來TreeNode* root = new TreeNode(preorder[preorder_root]);// 得到左子樹中的節(jié)點(diǎn)數(shù)目int size_left_subtree = inorder_root - inorder_left;// 遞歸地構(gòu)造左子樹,并連接到根節(jié)點(diǎn)// 先序遍歷中「從 左邊界+1 開始的 size_left_subtree」個(gè)元素就對(duì)應(yīng)了中序遍歷中「從 左邊界 開始到 根節(jié)點(diǎn)定位-1」的元素root->left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);// 遞歸地構(gòu)造右子樹,并連接到根節(jié)點(diǎn)// 先序遍歷中「從 左邊界+1+左子樹節(jié)點(diǎn)數(shù)目 開始到 右邊界」的元素就對(duì)應(yīng)了中序遍歷中「從 根節(jié)點(diǎn)定位+1 到 右邊界」的元素root->right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);return root;}TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int n = preorder.size();// 構(gòu)造哈希映射,幫助我們快速定位根節(jié)點(diǎn)for (int i = 0; i < n; ++i) {index[inorder[i]] = i;}return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);} };二、從中序與后序遍歷序列構(gòu)造二叉樹
根據(jù)一棵樹的中序遍歷與后序遍歷構(gòu)造二叉樹。
注意: 你可以假設(shè)樹中沒有重復(fù)的元素。例如,給出中序遍歷 inorder = [9,3,15,20,7] 后序遍歷 postorder = [9,15,7,20,3] 返回如下的二叉樹:3/ \9 20/ \15 7代碼
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:unordered_map<int, int> mp;TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {if (inorder.empty()) return NULL;for (int i = 0; i < inorder.size(); i++) mp[inorder[i]] = i; //記住每個(gè)數(shù)的位置return build(inorder, postorder, 0, inorder.size() - 1, 0, postorder.size() - 1);}TreeNode * build(vector<int>& inorder, vector<int>& postorder, int inL, int inR, int pL, int pR){if (pL > pR) return NULL;TreeNode * root = new TreeNode(postorder[pR]);int k = mp[postorder[pR]];root->left = build(inorder, postorder, inL, k - 1, pL, pL + k - inL - 1);root->right = build(inorder, postorder, k + 1, inR, pL + k - inL, pR - 1);return root;} };三、二叉搜索樹轉(zhuǎn)雙向鏈表
輸入一棵二叉搜索樹,將該二叉搜索樹轉(zhuǎn)換成一個(gè)排序的雙向鏈表。要求不能創(chuàng)建任何新的結(jié)點(diǎn),只能調(diào)整樹中結(jié)點(diǎn)指針的指向。
代碼
/* struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {} };*/ class Solution { public:void BToL(TreeNode* pRootOfTree,TreeNode** Head){if(pRootOfTree == nullptr){return ;}//找到最左側(cè)節(jié)點(diǎn)TreeNode* cur = pRootOfTree; if(cur->left){BToL(cur->left,Head);}//cur:當(dāng)前判斷節(jié)點(diǎn),也是雙向鏈表當(dāng)中的后一個(gè)節(jié)點(diǎn)//head:當(dāng)前節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn),即cur的上一個(gè)節(jié)點(diǎn),即雙向鏈表的前一個(gè)節(jié)點(diǎn) //這一步相當(dāng)于雙向鏈表當(dāng)中的鏈接prev指針,即后一個(gè)節(jié)點(diǎn)鏈接前一個(gè)節(jié)點(diǎn)cur->left = *Head;//當(dāng)?shù)谝淮巫叩竭@里時(shí)cur->left肯定是空,需要判斷if(*Head){//這一步相當(dāng)于雙向鏈表的next指針,即前一個(gè)節(jié)點(diǎn)鏈接后一個(gè)節(jié)點(diǎn)(*Head)->right = cur;}//head也同步往后*Head = cur;//判斷右子樹,遞歸進(jìn)行if(cur->right){BToL(cur->right,Head);}//注意隨著head不斷往后,得到的雙向鏈表剛好是反的,head指針指向的位置是二叉樹的最由節(jié)點(diǎn)}TreeNode* Convert(TreeNode* pRootOfTree){TreeNode* Head = nullptr;BToL(pRootOfTree,&Head);//翻轉(zhuǎn)while(Head && Head->left){Head = Head->left;}return Head;} };總結(jié)
以上是生活随笔為你收集整理的二叉树构建及双向链表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。