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