C++11 对特定二叉树算法使用共享ptr与唯一ptr
我一直在使用智能指针而不是原始指针来实现各种二叉树算法。我对共享/唯一指针之间的差异以及何时使用这些指针有着非常深入的理解,但是这个特定的算法给我带来了很多麻烦 这是我的TreeNode实现,其左、右子级都有唯一的_ptrC++11 对特定二叉树算法使用共享ptr与唯一ptr,c++11,c++14,binary-tree,shared-ptr,unique-ptr,C++11,C++14,Binary Tree,Shared Ptr,Unique Ptr,我一直在使用智能指针而不是原始指针来实现各种二叉树算法。我对共享/唯一指针之间的差异以及何时使用这些指针有着非常深入的理解,但是这个特定的算法给我带来了很多麻烦 这是我的TreeNode实现,其左、右子级都有唯一的_ptr struct UniqueTreeNode { /*Construction via int value*/ explicit UniqueTreeNode(const int v) : val(v), left(nullptr), right(nullpt
struct UniqueTreeNode {
/*Construction via int value*/
explicit UniqueTreeNode(const int v) : val(v), left(nullptr), right(nullptr), parent(nullptr) {}
~UniqueTreeNode() { std::wcout << L"Destroy: " << val << std::endl; }
/*Printing Utility for unique_ptr to tree node.*/
friend std::wostream& operator<<(std::wostream& wout, const std::unique_ptr<UniqueTreeNode>& n) {
std::wstringstream wss;
print(n.get(), std::wstring(), wss, Child::LEFT);
return wout << wss.rdbuf();
}
/*Printing Utility shared_ptr to tree node.*/
friend std::wostream& operator<<(std::wostream& wout, const std::shared_ptr<UniqueTreeNode>& n) {
std::wstringstream wss;
print(n.get(), std::wstring(), wss, Child::LEFT);
return wout << wss.rdbuf();
}
/*Printing Utility for tree node pointer.*/
friend std::wostream& operator<<(std::wostream& wout, UniqueTreeNode* n) {
std::wstringstream wss;
print(n, std::wstring(), wss, Child::LEFT);
return wout << wss.rdbuf();
}
/*Enum utility to pick child*/
enum class Child { LEFT, RIGHT };
static void print(UniqueTreeNode* n, std::wstring ws, std::wstringstream& wss, const Child& c);
/*Construction level-by-level via vector*/
static std::unique_ptr<UniqueTreeNode> construct(const std::vector<int>& v);
int val; // Data element in node.
std::unique_ptr<UniqueTreeNode> left, right; // left & right child pointers.
UniqueTreeNode* parent; // parent raw pointer.
};
/**
* \brief Prints the tree level by level.
* \param n current node being processed.
* \param ws wide-string for storing prefix.
* \param wss appends result incrementally.
* \param c child being considered currently.
*/
inline void UniqueTreeNode::print(UniqueTreeNode* n, const std::wstring ws, std::wstringstream& wss, const Child& c) {
if (!n) wss << L"Empty Tree";
else {
if (n->right) print(n->right.get(), ws + (c == Child::LEFT ? L"│ " : L" "), wss, Child::RIGHT);
wss << ws << (c == Child::LEFT ? L"└── " : L"┌── ") << std::to_wstring(n->val) << L"\n";
if (n->left) print(n->left.get(), ws + (c == Child::LEFT ? L" " : L"│ "), wss, Child::LEFT);
}
}
/**
* \brief Construction of tree via vector elements.
* \param v vector of elements to add.
* \return the tree after its constructed.
*/
inline std::unique_ptr<UniqueTreeNode> UniqueTreeNode::construct(const std::vector<int>& v) {
if (v.empty()) return nullptr;
auto it = v.cbegin();
auto n = std::make_unique<UniqueTreeNode>(*it);
std::queue<UniqueTreeNode*> q({ n.get() });
while (++it != v.cend()) {
auto *x = q.front(); q.pop();
x->left = std::make_unique<UniqueTreeNode>(*it), q.push(x->left.get());
if (++it == v.cend()) break;
x->right = std::make_unique<UniqueTreeNode>(*it), q.push(x->right.get());
}
return n;
}
struct UniqueTreeNode{
/*通过int值构造*/
显式UniqueTreeNode(const int v):val(v)、left(nullptr)、right(nullptr)、parent(nullptr){
~UniqueTreeNode(){std::wcout使用智能指针并不禁止原始指针。在使用非拥有指针的地方,您仍然可以使用它们。在这里,我认为使用deque s;
没有什么错。当它超出范围时,您仍然可以将所有对象干净地保存在您创建的树中。@spectras我确实尝试过这一点。但是,当我执行此操作n->left=move(s.back());
我将无法将原始指针移动到左子对象,因为它是唯一的\u ptr。即使我能够以某种方式将子对象移动到左。由于某些原因,此操作仍然不起作用。指向n的原始指针仍然超出范围,如果我尝试添加{3,2,1}(从未进入while循环),结果并不像预期的那样。在这种情况下,我可能对指向对象的原始指针的作用域没有完全理解。它只是没有按照预期工作。
uTreeNode ConstructMaxTree(const vector<int>& v) {
deque<uTreeNode> s;
for (const auto val : v) {
auto n = make_unique<UniqueTreeNode>(val);
while (!s.empty() && s.back()->val < val) {
n->left = move(s.back());
s.pop_back();
}
if (!s.empty()) {
s.back()->right = move(n);
}
s.emplace_back(move(n));
}
return move(s.front());
}