树_数据结构
二叉樹基本數(shù)據(jù)結(jié)構(gòu)
目錄
- 相同樹
- 二叉樹的層序遍歷
- 數(shù)組轉(zhuǎn)換為二分樹
- 樹的非遞歸遍歷
- 樹的非遞歸遍歷version2
- 不同的二叉樹
- 實現(xiàn)不同的二叉樹
- 高度平衡二叉樹
- 二叉查找樹中查找
- 根據(jù)前序和中序遍歷生成二叉樹
- 根據(jù)中序個后序遍歷生成二叉樹
- 將二叉樹變成一個鏈表形式二叉樹
- N個孩子結(jié)點用數(shù)組表示的樹的前序非遞歸遍歷
- 872.葉子結(jié)點相同的樹
- 129.所有根結(jié)點的路徑和
226.反轉(zhuǎn)二叉樹
線索二叉樹:
n個結(jié)點的二叉鏈表 每個結(jié)點有左右孩子兩個指針域,有2n個指針域 ;n-1條分支線樹。100.Same Tree
102. Binary Tree Level Order Traversal
// 二叉樹的層序遍歷是用數(shù)據(jù)結(jié)構(gòu) 隊列queue 來實現(xiàn)的 // 滿足基本的先進(jìn)先出的的順序 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ // 利用上述的結(jié)構(gòu)定義 // 將結(jié)點按層序結(jié)構(gòu)依次打印 // 判斷程序結(jié)束的語句還是有一點欠缺 void levelOrderTraverse(TreeNode *root){queue<TreeNode*> q;if(root)q.push(root);while(!q.empty()){TreeNode front=q.front();cout<<front->val<<endl;q.pop();if(front->left)q.push(front->left);if(front->right)q.push(front->right);} } class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> ans;DFS(root,0,ans);return ans;} private:void DFS(TreeNode* root,int depth,vector<vector<int>>& ans){if(!root) return;while (ans.size()<=depth) ans.push_back({});ans[depth].push_back(root->val);DFS(root->left,depth+1,ans);DFS(root->right,depth+1,ans);} };// 這個是由底向上輸出的版本 // 我寫了一個swap函數(shù),利用循環(huán)將最后一元素pop后,插入到最前面的位置 // 顯示的錯誤是void函數(shù)問題 // 這個問題還是模棱兩可的,不是很清晰 class Solution { public:vector<vector<int>> levelOrderBottom(TreeNode* root) {vector<vector<int>> result;DFS(root,0,result);reverse(result.begin(),result.end()); //添加一個reverse的內(nèi)置函數(shù)return result;} private:void DFS(TreeNode *root,int depth,vector<vector<int>>&result){if(!root)return;while(result.size()<=depth){result.push_back({}); }result[depth].push_back(root->val);DFS(root->left,depth+1,result);DFS(root->right,depth+1,result);} }; # 這個是自低向上的輸出 # dfs recursively def levelOrderBottom1(self, root):res = []self.dfs(root, 0, res)return resdef dfs(self, root, level, res):if root:if len(res) < level + 1:res.insert(0, [])# 保證插入的一定位于頭位置res[-(level+1)].append(root.val)self.dfs(root.left, level+1, res)self.dfs(root.right, level+1, res)108. Convert Sorted Array to Binary Search Tree
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/// @param: input a array // @return treenode root// divide and conquer classsic class Solution { public:TreeNode* sortedArrayToBST(vector<int>& nums) {return Divide_Array(0,nums.size()-1,nums);}TreeNode* Divide_Array(int i,int j,vector<int>& nums){if(i<0||j>=nums.size()||i>j||i>=nums.size()||j<0){return NULL;}int mid=i+(j-i)/2;TreeNode* root=new TreeNode(nums[mid]);root->left=Divide_Array(i,mid-1,nums);root->right=Divide_Array(mid+1,j,nums);return root;}};二叉樹前序非遞歸遍歷
94Binary Tree Inorder Traversal
#include<stack> /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ // need stack data-structure class Solution { public:vector<int> inorderTraversal(TreeNode* root) {TreeNode *cur=root;//define a stack ?stack<TreeNode *> s;vector<int> ans;while(cur){if(cur->left){s.push(cur);cur=cur->left;}else{ans.push_back(cur->val);cur=cur->right;}while(!cur && !s.empty()){cur=s.top();ans.push_back(cur->val);s.pop();cur=cur->right;}}return ans;} };中序遍歷先考慮leftnode 左結(jié)點是不是存在,再將結(jié)點進(jìn)行進(jìn)棧。(左根右)
// define the stack data-structure typedef struct Node{BTree data;struct Node *next; }Node,*pNode;typedef struct Stack{pNode pTop;pNode pBottom; }Stack,*PSTACK;// define the tree node data-structure typedef struct BTNode{char data;struct BTNode *pLchild;struct BTNode *pRchild;}BTNode,*BTree;void inorder_traverse(BTree pTree){PSTACK stack=create_stack();BTree node_pop;BTree pcur=pTree;while(pcur || !is_empty(stack)){if(pcur->pLchild){push_stack(stack, pcur);pcur=pcur->pLchild;}else{printf("%c",pcur->data);pcur=pcur->pRchild;}while(!pcur && !is_empty(stack)){pcur=get_top(stack);printf("%c",pcur->data);pop_stack(stack, &node_pop);pcur=pcur->pRchild;}} }
后序遍歷是現(xiàn)將結(jié)點進(jìn)棧,檢查左右結(jié)點都是否存在,再考慮將右結(jié)點,左結(jié)點依次進(jìn)棧。
// 基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)如中序遍歷 void posorder_traverse(BTree pTree){PSTACK stack=create_stack();BTree node_pop;BTree pcur=pTree;BTree pPre=NULL;// first need push the first to the stackpush_stack(stack, pTree);while(!is_empty(stack)){pcur=get_top(stack);// detection the nodeif((pcur->pLchild==NULL && pcur->pRchild)||(pPre!=NULL &&(pcur->pLchild==pPre ||pcur->pRchild==pPre))){printf("%c",pcur->data);pop_stack(stack,&node_pop);pPre=pcur;}else{// other situtation,mean have left and right childif(pcur->pRchild!=NULL)push_stack(stack, pcur->pRchild);if(pcur->pLchild!=NULL)push_stack(stack, pcur->pLchild);}} }Binary Tree with loop-version 2
/** Date:nov.5.2018* @author:Danny * Program function:implement traverse the tree with loop */#include<cstdlib> using namespace std; /** Define the TreeNode data structure*/struct TreeNode {int val;TreeNode *Lchild;TreeNode *Rchlid; };/** 1.PreOrderTraverse*//** 遍歷順序:根-左-右* 現(xiàn)將根結(jié)點進(jìn)行壓棧* 當(dāng)棧不為空的時候,棧頂元素出棧,并輸出棧頂元素的值(根結(jié)點)* 如果右孩子結(jié)點存在,進(jìn)行壓棧* 如果左孩子結(jié)點存在,進(jìn)行壓棧*/ void PreOrderTraverse(TreeNode *root){if(!root){cout<<"empty tree !"<<endl;return ;}stack<TreeNode *> stack_node;stack_node.push(root);while(!stack_node.empty()){TreeNode *temp=stack_node.top();stack_node.pop();cout<<temp->val<<endl; // 現(xiàn)將根結(jié)點進(jìn)行輸出if(temp->Rchlid){stack_node.push(temp->Rchlid);}if(temp->Lchild){stack_node.push(temp->Lchild);}}}/** 2.inOrderTraverse*//** 遍歷順序:左-根-右* 初始結(jié)點為根結(jié)點,如果結(jié)點不為空,將當(dāng)前結(jié)點進(jìn)行壓棧* 將結(jié)點替換為結(jié)點的左孩子* 否則輸出棧頂?shù)脑? 當(dāng)前結(jié)點替換為結(jié)點的右孩子,出棧*/void inOrderTraverse(TreeNode *root){if(!root){cout<<"empty tree!"<<endl;return ;}stack<TreeNode *>stack_node;while(root|| !stack_node.empty()){if(root){stack_node.push(root);root=root->Lchild;}else{TreeNode *cur=stack_node.top();stack_node.pop();cout<<cur->val<<endl;root=cur->Rchlid;}} }/** 3.PostOrderTraverse*//** 遍歷順序:左-右-根* 由兩個棧來實現(xiàn)* 先把根結(jié)點壓入第一個棧*/void PostOrderTraverse(TreeNode *root){if(!root){cout<<"empty tree !"<<endl;return ;}stack<TreeNode *>stack1,stack2;stack1.push(root);while(!stack1.empty()){TreeNode *cur=stack1.top();stack1.pop();stack2.push(cur);if(cur->Lchild)stack1.push(cur-<Lchild);if(cur->Rchlid)stack1.push(cur->Rchlid);}while(!stack2.empty()){TreeNode *top=stack2.top();stack2.pop();cout<<top->val<<endl;}}96 Unique Binary Search Trees
前序遍歷是將根結(jié)點進(jìn)展,在考慮左結(jié)點是否存在。(根左右)
class Solution { public:int numTrees(int n) {vector<int> sub_tree(n+1,0);sub_tree[0]=1;for(int i=1;i<=n;i++){for(int j=0;j<i;j++){sub_tree[i]+=sub_tree[j]*sub_tree[i-j-1];}}return sub_tree[n];// formula derivation error/*if(n==0)return 0;if(n==1)return 1;while(n>=2){return 2*(numTrees(n-1)+numTrees(n-2));}*/} };95Unique Binary Search Trees II
-這個代碼是沒有看懂的,需要后續(xù)繼續(xù)補充學(xué)習(xí)
// create :2018.10.12 // @author:dengshuoclass Solution { private:vector<TreeNode*> helper(int start, int end){vector<TreeNode*> res;if(start > end) {res.push_back(NULL);return res;}// use two pointer for(int i = start; i <= end; i++){vector<TreeNode*> lefts = helper(start, i - 1);vector<TreeNode*> rights = helper(i + 1, end);for(int j = 0; j < (int)lefts.size(); j++){for(int k = 0; k < (int)rights.size(); k++){TreeNode* root = new TreeNode(i);root->left = lefts[j];root->right = rights[k];res.push_back(root);}}}return res;} public:vector<TreeNode*> generateTrees(int n) {if(n == 0) return vector<TreeNode*>(0);return helper(1,n);} };// Author: Huahua // Running time: 16 ms class Solution { public:vector<TreeNode*> generateTrees(int n) {if (n == 0) return {};const auto& ans = generateTrees(1, n);cout << ans.size() << endl; // 計算結(jié)點數(shù)return ans;} private:vector<TreeNode*> generateTrees(int l, int r) {if (l > r) return { nullptr };vector<TreeNode*> ans;for (int i = l; i <= r; ++i)for (TreeNode* left : generateTrees(l, i - 1))for (TreeNode* right : generateTrees(i + 1, r)) {ans.push_back(new TreeNode(i));ans.back()->left = left;ans.back()->right = right;}return ans;} };110Balanced Binary Tree
- 實現(xiàn)高度平衡二叉樹
- 平衡二叉樹:
結(jié)點為空或者左右兩個子樹高度差的絕對值不超過1.
還是使用遞歸來實現(xiàn),要注意這個遞歸實現(xiàn)的順序流程
700.Search in a Binary Search Tree
class Solution { public:TreeNode* searchBST(TreeNode* root, int val) { if(root==NULL || root->val==val)return root; //當(dāng)樹為空的時候,返回 [] 不知道為什么這個還是可以運行。if(val<root->val)return searchBST(root->left,val);else{return searchBST(root->right,val);}} };105.Construct Binary Tree with preorder and inorder traversal
// 這就是我的思路 // 根據(jù)preorder確定當(dāng)前根結(jié)點的位置 // 在根據(jù) 根結(jié)點在inorder的位置,劃分左右子樹 // 遞歸的進(jìn)行,知道左右子樹都為空,或者前序和后序遍歷為空截止遞歸 class Solution { public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {if(perorder.size()==0 || inorder.size()==0)return NULL;int index= //我找不出根結(jié)點在中序遍歷的位置,無法進(jìn)行劃分TreeNode *root=preorder[0];root->left=bulidTree();root->right=bulidTree(); } }; //添加輔助函數(shù) TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {return builTreeHelper(preorder,0,preorder.size(),inorder,0,inorder.size()); }TreeNode* builTreeHelper(vector<int>& preorder, int sp, int ep, vector<int>& inorder, int si, int ei) {if (sp == ep) return nullptr;TreeNode* root = new TreeNode(preorder[sp]);int dis = find(inorder.begin()+si,inorder.begin()+ei,preorder[sp]) - inorder.begin() - si;root->left = builTreeHelper(preorder,sp+1,sp+1+dis,inorder,si,si+dis);root->right = builTreeHelper(preorder,sp+1+dis,ep,inorder,si+dis+1,ei);return root; } // 未通過的代碼 // 同樣也是使用輔助函數(shù)來實現(xiàn) class Solution { public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {if(preorder.size()==0 || inorder.size()==0)return NULL;return recursionBulid(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);} private:TreeNode *recursionBulid(vector<int>& preorder,int startpreorder,int endpreorder,vector<int>& inorder,int startinorder,int endinorder){int rootvalue=preorder[startpreorder];TreeNode *root= new TreeNode(0);root->val=rootvalue;root->left=root->right=NULL;if(startpreorder==endpreorder){if(startinorder==endinorder)return root;}int root_inorder=startpreorder;while(root_inorder<=endinorder && inorder[root_inorder]!=rootvalue){root_inorder++;}int root_left_length=root_inorder-startpreorder;int left_preorder_end=startpreorder+root_left_length;if(root_left_length>0){root->left=recursionBulid(preorder,startpreorder+1,left_preorder_end,inorder,startinorder,root_inorder-1);}if(root_left_length<endpreorder-startpreorder){root->right=recursionBulid(preorder,left_preorder_end+1,endpreorder,inorder,root_inorder+1,endinorder);}return root; } };106.Construct Binary tree with inorder and postorder traversal
// 按照自己的思路來寫的 // Runtime error // 錯可能就錯在遞歸函數(shù)的邊界值。能夠取到,是從什么開始 // 例如 取左值,不取右值。可以對比下面一個代碼的區(qū)間問題 class Solution { public:TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {// can construct a binary treeif(inorder.size()==0 || postorder.size()==0){return nullptr;}if(inorder.size()==1 && postorder.size()==1){TreeNode * root=new TreeNode(postorder[0]);return root;}return recursionBulid(inorder,0,inorder.size()-1,postorder,0,postorder.size()-1); } private:TreeNode *recursionBulid(vector<int>& inorder,int start_in,int end_in,vector<int> &postorder,int start_post,int end_post){TreeNode *root=new TreeNode(postorder[end_post]);int root_inorder=start_in;int root_value=postorder[end_post];while(root_inorder<end_in && inorder[root_inorder]!=root_value){root_inorder++;}int left_length=root_inorder-start_in;root->left=recursionBulid(inorder,start_in,root_inorder-1,postorder,start_post,left_length-start_post);root->right=recursionBulid(inorder,root_inorder+1,end_in,postorder,left_length+1,end_post-1);return root;} }; // 利用vecotr 可以迭代的性質(zhì) // 注意便捷的情況 public:typedef vector<int>::iterator Iter;TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {// write your code hereif (inorder.size() == 0)return NULL;return buildTreeRecur(inorder.begin(), inorder.end(), postorder.begin(), postorder.end());}TreeNode *buildTreeRecur(Iter istart, Iter iend, Iter pstart, Iter pend){if(istart == iend)return NULL;int rootval = *(pend-1);Iter iterroot = find(istart, iend, rootval);TreeNode *res = new TreeNode(rootval);res->left = buildTreeRecur(istart, iterroot, pstart, pstart+(iterroot-istart));res->right = buildTreeRecur(iterroot+1, iend, pstart+(iterroot-istart), pend-1);return res;} };114.Flatten Binary tree To Linked List
// 這是自己寫的 // 思路: // 1.利用前序遍歷preorder,遍歷所有結(jié)點 // 2.構(gòu)造二叉樹,一直添加右子結(jié)點// 這個代碼運行時錯誤的 class Solution { public:void flatten(TreeNode* root) {queue<TreeNode*> q=preOrder(root);q.pop();while(!q.empty()){root->left=NULL;root->right=q.front();q.pop();root=q.front();} } private:queue<TreeNode*>preOrder(TreeNode *root){stack<TreeNode *> s;queue<TreeNode *> q;s.push(root);while(!s.empty()){TreeNode *temp=s.top();s.pop();q.push(temp);if(temp->right){s.push(temp->right);}if(temp->left){s.push(temp->left);}}return q;} };// 參考別人的代碼 // 這個寫的真的是很漂亮的代碼 // 直接利用二叉樹的性質(zhì)來進(jìn)行結(jié)點相互交換完成排序的實現(xiàn) // 真的牛皮!!!!! class Solution { public:void flatten(TreeNode *root) {TreeNode*now = root;while (now){if(now->left){//Find current node's prenode that links to current node's right subtreeTreeNode* pre = now->left;while(pre->right){pre = pre->right;}pre->right = now->right;//Use current node's left subtree to replace its right subtree(original right //subtree is already linked by current node's prenodenow->right = now->left;now->left = NULL;}now = now->right;}} };589.N-ary Tree PreOrder Traversal
/* 思路清晰: 1.利用棧來實現(xiàn)樹的前序遍歷 2.對于孩子結(jié)點,進(jìn)行pop_back()進(jìn)棧 代碼正確: 就是root不存在的返回值存在一點小問題直接返回 定義值(未初始化的值) */ // 注意 結(jié)點的定義發(fā)生了變化 /* // Definition for a Node. class Node { public:int val;vector<Node*> children;Node() {}Node(int _val, vector<Node*> _children) {val = _val;children = _children;} }; */ class Solution { public:vector<int> preorder(Node* root) {vector<int> result;stack<Node*> s; // 利用棧來實現(xiàn)樹的前序遍歷s.push(root);if(!root)return result;while(!s.empty()){Node *temp=s.top();s.pop();result.push_back(temp->val); while(!temp->children.empty())。// 返回孩子結(jié)點中的所有孩子{s.push(temp->children.back()); // 壓縮到棧中temp->children.pop_back();}} return result; } };872.Leaf similar trees
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ // 也可以解決,但是容易出現(xiàn)問題 class Solution { public:bool leafSimilar(TreeNode* root1, TreeNode* root2) {return Leaf(root1)==Leaf(root2)}vector<int> preorder(TreeNode *root){vector<int> leafnode;if(!root)return leafnode;if(!root->left && !root->right){leafnode.push_back(root->val);}preorder(root->left);preorder(root->right);return leafnode;} };// // 最大的不同就在于,將參數(shù)放在函數(shù)中 // 函數(shù)是一個無返回的函數(shù) class Solution { public:bool leafSimilar(TreeNode* root1, TreeNode* root2) {vector<int> leafnode1,leafnode2;preorder(root1,leafnode1);preorder(root2,leafnode2);return leafnode1==leafnode2;}void preorder(TreeNode *root,vector<int> &leafnode){if(!root)return ;if(!root->left && !root->right){leafnode.push_back(root->val);}preorder(root->left,leafnode);preorder(root->right,leafnode); } };129.Sum Root to Leaf Numbers
// 理解錯誤,沒有分開左右子樹 // 這個是計算所有結(jié)點(前序)的路徑和 class Solution { public:int sumNumbers(TreeNode* root) {int sum=0;preorder(root,sum);return sum; }void preorder(TreeNode *root,int &sum){if(!root)return ;sum=sum*10+root->val;preorder(root->left,sum);preorder(root->right,sum);} }; // 正確版本 // 就是思考的方向不對 // 1.要分左右子樹 // 2.現(xiàn)考慮左右子樹都不存在的情況 class Solution { public:int sumNumbers(TreeNode* root) {if(!root)return 0;return sumAll(root,0);}int sumAll(TreeNode *root,int x){if(root->left==NULL && root->right==NULL)return x*10+root->val;int lrSum=0; // 這個用來計算左右子樹的總和if(root->left!=NULL)lrSum+=sumAll(root->left,x*10+root->val);if(root->right!=NULL)lrSum+=sumAll(root->right,x*10+root->val);return lrSum;} };226.Invert Binary Tree
// 這道題的思想其實很簡單 // 就是最基本的DFS,深度優(yōu)先遍歷 // 先解決一個一個分支,這個思想我還是有點缺乏 // 自己寫的 class Solution { public:TreeNode* invertTree(TreeNode* root) {if(!root)return root;TreeNode *var=root;Helper(var);return root;}void Helper(TreeNode *var){// 再寫個結(jié)束條件TreeNode *temp=var->left;var->left=var->right;var->right=temp; Helper(var->left);Helper(var->right); } }; // 這個是正確利用深度優(yōu)先遍歷的代碼 class Solution { public:TreeNode* invertTree(TreeNode* root) {if(!root)return root;if(!root->left && !root->right)return root;TreeNode *temp;temp=invertTree(root->left);root->left=invertTree(root->right);root->right=temp;return root;} };轉(zhuǎn)載于:https://www.cnblogs.com/GeekDanny/p/9771475.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
- 上一篇: cv2.minAreaRect() 生成
- 下一篇: 【洛谷 P2303】 [SDOi2012