剣指offer-二叉木
4247 ワード
【04二叉木の再建】
タイトルの説明
ツリーの前順および中順の結果を入力し、ツリーを再構築します.入力された前シーケンスおよび中シーケンスの結果に重複する数値が含まれていないと仮定します.例えば、前シーケンス遍歴シーケンス{1,2,4,7,3,5,6,8}と中シーケンス遍歴シーケンス{4,7,2,1,5,3,8,6}を入力すると、ツリーが再構築され、戻ります.
考え方:
1)二叉木の構築,付与,左右の子木の利便性?2)前順リスト,中順リストから左右のサブツリーを復元する:前順のルート,中順で左右のサブツリーを分割し,左右のサブツリーを再帰的に再構成する3)C++未知長の配列を読み出し,配列終了をリターンイン判定する
サンプル:
1 2 4 7 3 5 6 8 4 7 2 1 5 3 8 6
【17木のサブ構造】
タイトルの説明
2本の二叉木A,Bを入力し,BがAのサブ構造であるか否かを判断する.(ps:空の木は任意の木のサブ構造ではないと約束しました)
考え方:
1)まず,AとBが同じ木であるか否かを再帰的に判断する.そうでなければ左サブツリーまたは右サブツリーとBが同じツリーであるかどうかを判断する2)2つのツリーが同じツリーであるかどうかを再帰的に判断する:判断する各ノードが同じであるかどうかを判断する
【18ツリーのミラー】
タイトルの説明
指定したツリーを操作し、ソースツリーのミラーに変換します.
説明を入力:
考え方:
1)左右のサブツリーを再帰的に反転2)非再帰的に反転し,スタックを利用してノードに格納する.
【22二叉木を上から下まで印刷】
タイトルの説明
ツリーの各ノードを上から下に印刷し、同レイヤノードを左から右に印刷します.
考え方:
1)キューストレージノードの利用
【23二叉木の後序遍歴】
タイトルの説明
整数配列を入力し、その配列が二叉探索ツリーの後順に遍歴した結果であるかどうかを判断します.もしそうであればYesを出力し、そうでなければNoを出力します.入力された配列の任意の2つの数字が互いに異なると仮定します.
タイトルの説明
ツリーの前順および中順の結果を入力し、ツリーを再構築します.入力された前シーケンスおよび中シーケンスの結果に重複する数値が含まれていないと仮定します.例えば、前シーケンス遍歴シーケンス{1,2,4,7,3,5,6,8}と中シーケンス遍歴シーケンス{4,7,2,1,5,3,8,6}を入力すると、ツリーが再構築され、戻ります.
考え方:
1)二叉木の構築,付与,左右の子木の利便性?2)前順リスト,中順リストから左右のサブツリーを復元する:前順のルート,中順で左右のサブツリーを分割し,左右のサブツリーを再帰的に再構成する3)C++未知長の配列を読み出し,配列終了をリターンイン判定する
サンプル:
1 2 4 7 3 5 6 8 4 7 2 1 5 3 8 6
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
TreeNode* reConstructBinaryTree(vector pre,vector vin) {
// , 。
if(pre.empty()||vin.empty())
return NULL;
if(pre.size()!=vin.size())
return NULL;
TreeNode *p;
p = (TreeNode*)malloc(sizeof(TreeNode));
int i=0,mid=0;
for(i=0;i pre_left,pre_right,vin_left,vin_right;
for(i=0;ival = pre[0];
p->left = reConstructBinaryTree(pre_left,vin_left);
p->right = reConstructBinaryTree(pre_right,vin_right);
return p;
}
【17木のサブ構造】
タイトルの説明
2本の二叉木A,Bを入力し,BがAのサブ構造であるか否かを判断する.(ps:空の木は任意の木のサブ構造ではないと約束しました)
考え方:
1)まず,AとBが同じ木であるか否かを再帰的に判断する.そうでなければ左サブツリーまたは右サブツリーとBが同じツリーであるかどうかを判断する2)2つのツリーが同じツリーであるかどうかを再帰的に判断する:判断する各ノードが同じであるかどうかを判断する
bool SameTree(TreeNode* pRoot1, TreeNode* pRoot2) //
{
bool val;
if(pRoot2==NULL)
return true;
if(pRoot1==NULL)
return false;
if(pRoot1->val!=pRoot2->val)
return false;
else
return SameTree(pRoot1->left,pRoot2->left) && SameTree(pRoot1->right,pRoot2->right);
}
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) // 2 1
{
bool val = false;
if(pRoot1==NULL ||pRoot2==NULL)
return val;
return SameTree(pRoot1,pRoot2) | HasSubtree(pRoot1->left,pRoot2) || HasSubtree(pRoot1->right,pRoot2);
}
【18ツリーのミラー】
タイトルの説明
指定したツリーを操作し、ソースツリーのミラーに変換します.
説明を入力:
:
8
/ \
6 10
/ \ / \
5 7 9 11
8
/ \
10 6
/ \ / \
11 9 7 5
考え方:
1)左右のサブツリーを再帰的に反転2)非再帰的に反転し,スタックを利用してノードに格納する.
void Mirror(TreeNode *pRoot) //
{
TreeNode *p;
if(pRoot==NULL)
{
return;
}
else{
p= pRoot->left;
pRoot->left = pRoot->right;
pRoot->right = p;
Mirror(pRoot->left);
Mirror(pRoot->right);
//cout<left->val<right->val< s; // 。
s.push(pRoot);
while(!s.empty())
{
TreeNode *p = s.top();
cout<val<left;
p->left = p->right;
p->right = tmp;
if(p->left!=NULL)
{
s.push(p->left);
cout<val<left->val<right!=NULL){
s.push(p->right);
cout<val<right->val<
【22二叉木を上から下まで印刷】
タイトルの説明
ツリーの各ノードを上から下に印刷し、同レイヤノードを左から右に印刷します.
考え方:
1)キューストレージノードの利用
vector PrintFromTopToBottom(TreeNode* root) { //
queue q;
vector result;
if(root)
q.push(root);
while(!q.empty())
{
TreeNode* cur = q.front();
q.pop();
result.push_back(cur->val);
if(cur->left)
{
q.push(cur->left);
}
if(cur->right)
{
q.push(cur->right);
}
}
return result;
}
【23二叉木の後序遍歴】
タイトルの説明
整数配列を入力し、その配列が二叉探索ツリーの後順に遍歴した結果であるかどうかを判断します.もしそうであればYesを出力し、そうでなければNoを出力します.入力された配列の任意の2つの数字が互いに異なると仮定します.
bool VerifySquenceOfBST(vector s) {
if(s.size()==1)
return true;
if(s.size()==0) // ,[]
return false;
int mid=0,end = s.size()-1, i=0;
while(mid left,right;
for(i=0;i