【数据结构】二叉树经典习题
965. 單值二叉樹
思路:
1.若樹為空,則返回true,因為并不違反規則。
2.將根結點和左子樹右子樹的值做比較,若不相等就返回false.
3.遞歸實現先序遍歷即可,即左子樹比完再比右子樹,且都得相等。
?
bool isUnivalTree(struct TreeNode* root){//先序遍歷if(root == NULL)return true;//判斷==并沒有多大的用處,判斷相反可快速結束遞歸。if(root->left && root->val != root->left->val)//1.判斷節點是否存在,2.判斷值是否不相等。return false;if(root->right && root->val != root->right->val)return false;return isUnivalTree(root->left) && isUnivalTree(root->right);//左樹 右樹都得同時滿足才可返回真}100. 相同的樹
在兩棵樹的比較,就是看對應節點是否存在且相等。
思路:1.若兩棵樹都為空,則返回true。
2.若兩棵樹對應節點有缺失,則返回false
3.遞歸,前序遍歷即可。
bool isSameTree(struct TreeNode* p, struct TreeNode* q){//同時為空樹,返回真if(p == NULL && q == NULL)return true;//當只有其中一個為空時,返回假if(p == NULL || q == NULL)return false;//遞歸if(p->val != q->val)return false;//左樹遍歷完遍歷右樹,且對應的左右書必須完全相等return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);}對稱二叉樹
在比較兩顆樹是否相等的基礎上,進行了小范圍的改動。
這里,我們只需要比較根結點以下的根左子樹和根右子樹。
比較要注意:因為是鏡面對稱,所以比較的是左樹的左子樹與右樹的右子樹;
左樹的右子樹與右子樹的左子樹相比較。
調用相同的樹的代碼即可,
?
bool _isSameTree(struct TreeNode* p, struct TreeNode* q){//同時為空樹,返回真if(p == NULL && q == NULL)return true;//當只有其中一個為空時,返回假if(p == NULL || q == NULL)return false;//遞歸if(p->val != q->val)return false;//左樹遍歷完遍歷右樹,且對應的左右書必須完全相等return _isSameTree(p->left,q->right) && _isSameTree(p->right,q->left);}bool isSymmetric(struct TreeNode* root){//為空樹if(root == NULL)return true;//調用相同樹的代碼return _isSameTree(root->left,root->right);}二叉樹的前序遍歷
復習:前序遍歷:根 - 左子樹 - 右子樹
總之還是遞歸分治的思想,但是,這道題又有點不同。
這道題要自己申請一個數組空間來存儲數據,使用靜態的數組會因為函數棧幀的緣故,當函數出了作用域時,就會被銷毀,返回的值可能就根本”不存在“。而static修飾的靜態局部變量,多次調用,就會出現數據覆蓋的問題,最優解就是:在堆上開辟空間,那開多大的空間?
我們可以先遍歷一遍二叉樹,獲得二叉樹的節點個數,相應的代碼及思路已經在之前的博客中提及過了。
思路:1.先序遍歷的思想
2.遞歸求節點的個數。
2.動態開辟數組。
?
int BTreeSize(struct TreeNode* root) {return root == NULL? 0:BTreeSize(root->left)+BTreeSize(root->right)+1; } void _preorder(struct TreeNode* root,int* a,int* pi) {if(root == NULL)return ;a[(*pi)++] = root->val;_preorder(root->left,a,pi);_preorder(root->right,a,pi); } int* preorderTraversal(struct TreeNode* root, int* returnSize){//確定樹的大小*returnSize = BTreeSize(root);int* a = (int*)malloc(sizeof(int)*(*returnSize));int i =0;_preorder(root,a,&i);return a; }二叉樹的后序遍歷
后序遍歷:左子樹 - 右子樹 - 根
思路與上面的前序遍歷一致
?
int BTreeSize(struct TreeNode* root) {return root == NULL? 0:BTreeSize(root->left)+BTreeSize(root->right)+1; } void _preorder(struct TreeNode* root,int* a,int* pi) {if(root == NULL)return ;_preorder(root->left,a,pi);_preorder(root->right,a,pi);a[(*pi)++] = root->val; } int* postorderTraversal(struct TreeNode* root, int* returnSize){*returnSize = BTreeSize(root);int* a = (int*)malloc(sizeof(int)*(*returnSize));int i =0;_preorder(root,a,&i);return a;}二叉樹的中序遍歷
int BTreeSize(struct TreeNode* root) {return root == NULL? 0:BTreeSize(root->left)+BTreeSize(root->right)+1; } void _preorder(struct TreeNode* root,int* a,int* pi) {if(root == NULL)return ;_preorder(root->left,a,pi);a[(*pi)++] = root->val;_preorder(root->right,a,pi);} int* inorderTraversal(struct TreeNode* root, int* returnSize){*returnSize = BTreeSize(root);int* a = (int*)malloc(sizeof(int)*(*returnSize));int i =0;_preorder(root,a,&i);return a; }另一棵樹的子樹
本質上就是尋找子樹的問題,當大樹的一個小樹和所給定的小樹的結構和值完全相等時,返回true
考慮調用判斷兩個數是否相同的函數代碼,采用分治的思想,先跑完左子樹尋找,再跑右子樹尋找,期間若找到了,就直接返回true。
主要還是分支的思想。
bool _isSameTree(struct TreeNode* p, struct TreeNode* q){//同時為空樹,返回真if(p == NULL && q == NULL)return true;//當只有其中一個為空時,返回假if(p == NULL || q == NULL)return false;//遞歸if(p->val != q->val)return false;//左樹遍歷完遍歷右樹,且對應的左右書必須完全相等return _isSameTree(p->left,q->left) && _isSameTree(p->right,q->right);}bool isSubtree(struct TreeNode* root, struct TreeNode* subRoot){if(root == NULL && subRoot == NULL)return true;if(root == NULL || subRoot == NULL)return false;//判斷其是否為相同的樹,找完左樹找右樹return _isSameTree(root,subRoot) || isSubtree(root->left,subRoot) || isSubtree(root->right,subRoot); }二叉樹遍歷
思路:1)建樹,遞歸分治建樹。
2)傳遞參數時,要傳遞指針,傳值調用,傳遞的是形參,形參的改變不會影響實參,所以遞歸時就會出錯。
3)中序遍歷,左子樹 - 根 - 右子樹
#include<stdio.h> #include<stdlib.h> typedef struct BTreeNode {char data;struct BTreeNode* left;struct BTreeNode* right; }BTNode; BTNode* CreatTree(char *a, int *pi)//這里必須傳遞指針 pi {//遞歸方式創建樹,那么就必須傳址調用,而不是傳值調用。//如果是‘#’就返回NULL,同時找數組下一位if(a[*pi] == '#'){(*pi)++;return NULL;}//創建樹BTNode* root = (BTNode*)malloc(sizeof(BTNode));root->data = a[(*pi)++];root->left = CreatTree(a, pi);root->right = CreatTree(a, pi);return root; } void InOrder(BTNode* root) {if(root == NULL)return;InOrder(root->left);printf("%c ",root->data);InOrder(root->right); } int main() {char a[100];scanf("%s",a);//創建樹int i = 0;BTNode* Tree = CreatTree(a,&i);InOrder(Tree);return 0; }總結
以上是生活随笔為你收集整理的【数据结构】二叉树经典习题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS——正则校验域名
- 下一篇: Error running ‘Tomca