简体   繁体   中英

Is there is a way to go through linked list , where instead of normall pointers will be unique?

I am trying to write a binary tree in c++ , linked list as subtrees and unique pointers as connections between those lists.Whole tree is divided on two parts : right and left. There are two pointers that reference going from head to the left and to the right leafes. Then every leaf in subtree is a structure , that stores next information :

class Leaf{
private:
    int * leaf_value; 
    int occupancy;
    std::unique_ptr<Leaf> NextLeaf;

public:
    explicit Leaf(int);
    void AppendLeaf(int,std::unique_ptr<Leaf>);

};

Leaf::Leaf(int size) {
    leaf_value = new int (size);
    NextLeaf = nullptr;
    occupancy = 0;
}

Where leaf_value is a pointer to memory that will store all numbers on that level .(because it is a binary tree we can ,know the exact size ( 2 ^ current_level ) that should be allocated for objects ). So we will fill that free space with numbers until occupancy is lesser than 2 ^ current_level .And after that we will add a new , deeper level for next row of elements. The structure will look like this:

               1
            /        \
         [2]         [ 3 ]
        /              \
   [4 , 5 ,6 ,7]  [8 , 9 , 10 , 11 ]

Where elements in square bruckets are single leafs. . I thought that it can be a good idea , to connect them all with uniwue pointers,because every node of list reference only to the next one , so in fact all pointers are unique.Here is simplified code of what i am trying to do.


int main(){
     Node head;
     head.next = nullptr;
     int value;
     cin << value;
     AddNode(value , head); 
     return 0;
}

/*TreeHead - is another leaf structure that stores pointers to left and right branches 
struct SmartTree{
    int level;
    std::unique_ptr<Leaf> LeftChild = std::make_unique<Leaf>(1);
    std::unique_ptr<Leaf> RightChild = std::make_unique<Leaf>(1);

}
*/
void AddNode(int val , std::unique_ptr<SmartTree> TreeHead){
/*problem with implemantation of this part */
     Node * currentLeaf  = TreeHead;
     Node * previousLeaf = TreeHead;
     while(current != nullptr){
        previousLeaf = currentLeaf;
        currentLeaf = currentLeaf -> next ;
     }
     currentLeaf = new Leaf;
     previous -> next = currentLeaf;
     currentLeaf -> value = val; 
}

But problem is that i can't find the right way to go through all leasts to the bottom one , because of uniquness of unique pointers .I don't sure that i can do that with move(pointer) function , because as i understood that functions work it lend ownership from TreeHead to CurrentLeafe , value stored in could be lost. So the question is : Is there is a way to go through the unique pointers or should i use different kind of pointers to complete that task? Thank you a lot !

I changed my methods for a little by changing an array leafs [ 1 2 3 ] on normal . That means that now every leaf is an object that contains one element , so tree looks now not like :

                1
            /        \
         [2]         [ 3 ]
        /              \
   [4 , 5 ,6 ,7]  [8 , 9 , 10 , 11 ]

but like :

               1
           /       \
          2           3
        /    \      /  \ 
       5      6    7     8 

New tree structure :

struct SmartTree {
    int value;
    int childrens;
    bool is_root = false;
    std::unique_ptr<SmartTree> LeftChild;
    std::unique_ptr<SmartTree> RightChild;
};

But i am sure that will works with previous method as good too.So i found , not without a help that a good solution in this case is recursion , and now function that going through the tree and adding element to the end looks like so :

std::unique_ptr <SmartTree> InsertLeftChild(std::unique_ptr<SmartTree> tree, std::unique_ptr<SmartTree> left_subtree){
    // left_subtree - node to insert
    tree -> childrens += 1;
    if (tree -> is_root and  tree -> LeftChild == nullptr) tree -> LeftChild = std::move(left_subtree);
    else if (tree -> is_root) tree -> LeftChild = InsertLeftChild(std::move(tree -> LeftChild) , move(left_subtree));
    else if (tree -> LeftChild == nullptr)tree -> LeftChild = std::move(left_subtree);
    else if (tree -> RightChild == nullptr) tree -> RightChild = std::move(left_subtree);
    else if (tree -> LeftChild -> childrens <= tree -> RightChild -> childrens) tree->LeftChild = InsertLeftChild(std::move(tree -> LeftChild) , std::move(left_subtree));
    else if (tree -> LeftChild -> childrens > tree -> RightChild -> childrens)  tree->RightChild = InsertLeftChild(std::move(tree -> RightChild) , std::move(left_subtree));
    return move(tree);
};

This one is writed only for insertion of left childs . So the first and second if checks is it a root and is this root initialize . If it has childs , than recall function InsertLeftChilld . Passinng aruments , to function with move will destroy previous pointer , so on the left side i return ownerships to the LeftChild :

tree -> LeftChild = std::move(left_subtree);

else if (tree -> LeftChild == nullptr) checks is it is the end and if it is - inserts new leaf

else if (tree -> LeftChild -> childrens <= tree -> RightChild -> childrens) checks where you should direct your leaf next in case it isn't level where you can insert it .Hope this method can help someone in future .Thanks to everyone for answers !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM