最近、自分が取り組んでいるプロジェクトのバイナリ検索ツリーの実装を終了しました。それはうまくいき、私は多くを学びました。しかし、今は通常のバイナリツリーを実装する必要があります...なんらかの理由で困惑しています。
InsertNode関数を実行する方法を探しています。
通常、BSTでは、データ<ルートかどうかを確認してから、左に挿入し、逆も同様です。ただし、通常のバイナリツリーでは、左から右に一度に1レベルずつ塗りつぶされます。
新しいNodeを左から右にバイナリツリーに特定の順序なしで追加するだけの関数を実装するのを手伝ってくれませんか?
これが私のBSTの挿入です:
void Insert(Node *& root, int data)
{
if(root == nullptr)
{
Node * NN = new Node;
root = NN;
}
else
{
if(data < root->data)
{
Insert(root->left, data);
}
else
{
Insert(root->right, data);
}
}
}
これは少し前に投稿された質問であることは承知していますが、私の考えを共有したいと思います。
私が行うこと(これは実際に十分に文書化されていないため)は、幅優先検索(キューを使用)を使用し、最初に検出したnullに子を挿入します。これにより、ツリーが別のレベルに進む前に、最初にレベルが満たされます。適切な数のノードがあれば、常に完全になります。
私はc ++ではあまり作業していなかったので、それが正しいことを確認するために、私はJavaでそれを行いましたが、あなたはアイデアを得ます:
public void insert(Node node) {
if(root == null) {
root = node;
return;
}
/* insert using Breadth-first-search (queue to the rescue!) */
Queue<Node> queue = new LinkedList<Node>();
queue.offer(root);
while(true) {
Node n = queue.remove();
if(!n.visited) System.out.println(n.data);
n.visited = true;
if(n.left == null) {
n.left = node;
break;
} else {
queue.offer(n.left);
}
if(n.right == null) {
n.right = node;
break;
} else {
queue.offer(n.right);
}
}
}
Javascriptの実装(Webコンソール用にコピーして貼り付け可能):
ES6実装(classキーワードを使用した新しいjavscript構文)
class BinaryTree {
constructor(value){
this.root = value;
this.left = null;
this.right = null;
}
insert(value){
var queue = [];
queue.Push(this); //Push the root
while(true){
var node = queue.pop();
if(node.left === null){
node.left = new BinaryTree(value);
return;
} else {
queue.unshift(node.left)
}
if(node.right === null){
node.right = new BinaryTree(value);
return;
} else {
queue.unshift(node.right)
}
}
}
}
var myBinaryTree = new BinaryTree(5);
myBinaryTree.insert(4);
myBinaryTree.insert(3);
myBinaryTree.insert(2);
myBinaryTree.insert(1);
5
/ \
4 3
/ \ (next insertions here)
2 1
疑似古典的なパターンの実装
var BinaryTree = function(value){
this.root = value;
this.left = null;
this.right = null;
}
BinaryTree.prototype.insert = function(value){
//same logic as before
}
コードにいくつかの変更を加えて、これが役立つことを願っています:
Node * Insert(Node * root, int data)
{
if(root == nullptr)
{
Node * NN = new Node();
root = NN;
root->data = data;
root->left = root ->right = NULL;
}
else
{
if(data < root->data)
{
root->left = Insert(root->left, data);
}
else
{
root->right = Insert(root->right, data);
}
}
return root;
}
したがって、この関数は更新されたBSTのルートノードを返します。
私はbknopperコードを取り、少し変更してC++に翻訳しました。彼が述べたように、驚くべきことに、これは十分に文書化されていません。
ノード構造と挿入関数は次のとおりです。
_struct nodo
{
nodo(): izd(NULL), der(NULL) {};
int val;
struct nodo* izd;
struct nodo* der;
};
void inserta(struct nodo** raiz, int num)
{
if( !(*raiz) )
{
*raiz = new struct nodo;
(*raiz)->val = num;
}
else
{
std::deque<struct nodo*> cola;
cola.Push_back( *raiz );
while(true)
{
struct nodo *n = cola.front();
cola.pop_front();
if( !n->izd ) {
n->izd = new struct nodo;
n->izd->val = num;
break;
} else {
cola.Push_back(n->izd);
}
if( !n->der ) {
n->der = new struct nodo;
n->der->val = num;
break;
} else {
cola.Push_back(n->der);
}
}
}
}
_
次のように呼び出します:inserta(&root, val);
Rootになると、ノードの構造体へのポインタが入り、挿入する整数値がvalになります。
それが誰かを助けることを願っています。