C ++のバイナリツリーでの削除?
削除は、削除されたモードを一番下の右端のノードに置き換えることによって実行されます。
まず、データとその左右のノードの子を含むツリーノードを表す構造体を定義しましょう。これが最初に作成されるノードの場合はルートノード、それ以外の場合は子ノードです。
struct Node {
int data;
struct Node *leftChild, *rightChild;
}; 次に、int値を取得してノードのデータメンバーに割り当てるnewNode(int data)関数を作成します。この関数は、作成された構造体ノードへのポインターを返します。また、新しく作成されたノードの左右の子はnullに設定されます。
struct Node* newNode(int data){
struct Node* newNode = new Node;
newNode->data = data;
newNode->leftChild = newNode->rightChild = NULL;
return (newNode);
} 削除(struct Node * root、int data)関数は、指定されたデータ値を持つノードを削除するために使用されます。ルートノードとデータ値を検索して削除します。子ノードがなく、データ値がルートのデータ値と等しい場合はnullが返され、そうでない場合はルートノードが返されます。
Node* deletion(struct Node* root, int data){
if (root == NULL)
return NULL;
if (root->leftChild == NULL && root->rightChild == NULL) {
if (root->data == data)
return NULL;
else
return root;
} ここで、タイプstruct Node *のキューを作成し、qという名前を付けて、ルートノードをqにプッシュします。また、Nodeへのポインタであるtempとdata_nodeを宣言し、data_nodeをNULLとして設定します。
struct Node* temp; struct Node* data_node = NULL;
次に、レベル順トラバーサルを実行して、最も深いノードを見つけます。 whileループは、キューqが空でなくなるまで実行されます。キューはFIFOデータ構造であるため、レベル順トラバーサルを実行すると、キューの最後の要素が右端の最も深いノードになります。一時は常にキューの先頭を指し、要素は先頭からポップされます。
while (!q.empty()) {
temp = q.front();
q.pop();
if (temp->data == data)
data_node = temp;
if (temp->leftChild)
q.push(temp->leftChild);
if (temp->rightChild)
q.push(temp->rightChild);
} 次に、data_nodeがNULLでない場合、削除するノードをxに格納し、最も深いノードであるtempを削除します。次に、data_node値が最も深いノード値に置き換えられ、最も深いノードが削除されます。削除と置換の後、関数から新しいノードが返されます。
if (data_node != NULL) {
int x = temp->data;
deleteDeepest(root, temp);
data_node->data = x;
} deleteDeepest(struct Node * root、struct Node * deepestNode)関数は、渡されたノードが実際に最も深いノードであるか、右または左の子が最も深いノードであるかを確認します。この場合、子の値をnullに設定してから、親を削除します。最も深いノード。
void deleteDeepest(struct Node* root,
struct Node* deepestNode){
queue<struct Node*> q;
q.push(root);
struct Node* temp;
while (!q.empty()) {
temp = q.front();
q.pop();
if (temp == deepestNode) {
temp = NULL;
delete (deepestNode);
return;
}
if (temp->rightChild) {
if (temp->rightChild == deepestNode) {
temp->rightChild = NULL;
delete (deepestNode);
return;
}
else
q.push(temp->rightChild);
}
if (temp->leftChild) {
if (temp->leftChild == deepestNode) {
temp->leftChild = NULL;
delete (deepestNode);
return;
}
else
q.push(temp->leftChild);
}
}
} 例
次の実装を見て、バイナリツリーの削除を確認しましょう-
#include <iostream>
#include <queue>
using namespace std;
struct Node {
int data;
struct Node *leftChild, *rightChild;
};
struct Node* NewNode(int data){
struct Node* temp = new Node;
temp->data = data;
temp->leftChild = temp->rightChild = NULL;
return temp;
};
void inorder(struct Node* temp){
if (!temp)
return;
inorder(temp->leftChild);
cout << temp->data << " ";
inorder(temp->rightChild);
}
void deleteDeepest(struct Node* root,
struct Node* deepestNode){
queue<struct Node*> q;
q.push(root);
struct Node* temp;
while (!q.empty()) {
temp = q.front();
q.pop();
if (temp == deepestNode) {
temp = NULL;
delete (deepestNode);
return;
}
if (temp->rightChild) {
if (temp->rightChild == deepestNode) {
temp->rightChild = NULL;
delete (deepestNode);
return;
}
else
q.push(temp->rightChild);
}
if (temp->leftChild) {
if (temp->leftChild == deepestNode) {
temp->leftChild = NULL;
delete (deepestNode);
return;
}
else
q.push(temp->leftChild);
}
}
}
Node* deletion(struct Node* root, int data){
if (root == NULL)
return NULL;
if (root->leftChild == NULL && root->rightChild == NULL) {
if (root->data == data)
return NULL;
else
return root;
}
queue<struct Node*> q;
q.push(root);
struct Node* temp;
struct Node* data_node = NULL;
while (!q.empty()) {
temp = q.front();
q.pop();
if (temp->data == data)
data_node = temp;
if (temp->leftChild)
q.push(temp->leftChild);
if (temp->rightChild)
q.push(temp->rightChild);
}
if (data_node != NULL) {
int x = temp->data;
deleteDeepest(root,temp);
data_node->data = x;
}
return root;
}
// Driver code
int main(){
struct Node* root = NewNode(12);
root->leftChild = NewNode(13);
root->leftChild->leftChild = NewNode(9);
root->leftChild->rightChild = NewNode(14);
root->rightChild = NewNode(11);
root->rightChild->leftChild = NewNode(17);
root->rightChild->rightChild = NewNode(10);
cout << "Inorder traversal before deletion : ";
inorder(root);
int data = 13;
root = deletion(root, data);
cout <<endl<< "Inorder traversal after deletion : ";
inorder(root);
return 0;
} 出力
上記のコードは次の出力を生成します-
Inorder traversal before deletion : 9 13 14 12 17 11 10 Inorder traversal after deletion : 9 10 14 12 17 11
-
C++のバイナリツリーでノードの先行ノードを事前注文する
この問題では、二分木とノード値が与えられます。私たちのタスクは、ノードのプレオーダーの先行を印刷することです。 二分木 は、各ルートノードが最大2つの子ノードを持つことができる特殊なタイプのツリーです。 プレオーダートラバーサル ツリーのノードをトラバースする方法です。ここでは、最初にルートノードをトラバースし、次に左の子、次に右の子をトラバースします。 先行ノードの事前注文 ノードのプレオーダートラバーサルでノードの前に来るノードです。 問題を理解するために例を見てみましょう Input: 1 Output: 9 この問題を解決するには、 navie アプローチは、二分木の
-
C++のバイナリツリーでノードの後続を事前注文する
この問題では、二分木とノード値が与えられます。私たちのタスクは、ノードのプレオーダーサクセサを印刷することです。 二分木 は、各ルートノードが最大2つの子ノードを持つことができる特殊なタイプのツリーです。 プレオーダートラバーサル ツリーのノードをトラバースする方法です。ここでは、最初にルートノードをトラバースし、次に左の子、次に右の子をトラバースします。 後続ノードの事前注文 ノードのプレオーダートラバーサルでノードの隣に来るノードです。 問題を理解するために例を見てみましょう Input: 9 Output 0 Explanation: the preorder traver