Tại sao C ++ STL không cung cấp bất kỳ container nào trên cây


373

Tại sao C ++ STL không cung cấp bất kỳ thùng chứa "cây" nào và thay vào đó, thứ tốt nhất để sử dụng là gì?

Tôi muốn lưu trữ một hệ thống phân cấp của các đối tượng dưới dạng cây, thay vì sử dụng cây làm tăng cường hiệu suất ...


7
Tôi cần một cái cây để lưu trữ một đại diện của một hệ thống phân cấp.
Roddy

20
Tôi với anh chàng đã bình chọn những câu trả lời "đúng", dường như là vậy; "Cây vô dụng". Có những điều quan trọng nếu sử dụng cây che khuất.
Joe Soul-bringer

Tôi nghĩ lý do là tầm thường - chưa có ai thực hiện nó trong thư viện chuẩn. Nó giống như thư viện tiêu chuẩn không có std::unordered_mapstd::unordered_setcho đến gần đây. Và trước đó không có container STL trong thư viện tiêu chuẩn.
doc

1
Suy nghĩ của tôi (chưa bao giờ đọc tiêu chuẩn có liên quan, do đó đây là một nhận xét không phải là câu trả lời) là STL không quan tâm đến các cấu trúc dữ liệu cụ thể, nó quan tâm đến các thông số kỹ thuật về độ phức tạp và các hoạt động được hỗ trợ. Vì vậy, cấu trúc cơ bản được sử dụng có thể khác nhau giữa các triển khai và / hoặc kiến ​​trúc đích, miễn là nó thỏa mãn các thông số kỹ thuật. Tôi khá chắc chắn std::mapstd::setsẽ sử dụng một cây trong mọi triển khai ngoài đó, nhưng họ không phải làm gì nếu một số cấu trúc không phải cây cũng đáp ứng các thông số kỹ thuật.
Mark K Cowan

Câu trả lời:


182

Có hai lý do bạn có thể muốn sử dụng cây:

Bạn muốn phản ánh vấn đề bằng cách sử dụng cấu trúc giống như cây:
Đối với điều này, chúng tôi có thư viện biểu đồ tăng

Hoặc bạn muốn một thùng chứa có đặc điểm truy cập giống như cây

Về cơ bản, đặc điểm của hai container này là chúng thực tế phải được thực hiện bằng cách sử dụng cây (mặc dù đây không thực sự là một yêu cầu).

Xem thêm câu hỏi này: Thực hiện cây C


64
Có rất nhiều, rất nhiều lý do để sử dụng cây, ngay cả khi đây là những lý do phổ biến nhất. Phổ biến nhất! Bằng tất cả.
Joe Soul-bringer

3
Một lý do chính thứ ba để muốn một cây là cho một danh sách luôn được sắp xếp với việc chèn / xóa nhanh, nhưng vì đó có std: multiset.
VoidStar

1
@Durga: Không chắc độ sâu có liên quan như thế nào khi bạn sử dụng bản đồ như một container được sắp xếp. Bản đồ đảm bảo nhật ký (n) chèn / xóa / tra cứu (và chứa các phần tử theo thứ tự được sắp xếp). Đây là tất cả bản đồ được sử dụng và được triển khai (thường) dưới dạng cây đỏ / đen. Cây đỏ / đen đảm bảo rằng cây được cân bằng. Vì vậy, độ sâu của cây liên quan trực tiếp đến số lượng phần tử trong cây.
Martin York

14
Tôi không đồng ý với câu trả lời này, cả trong năm 2008 và bây giờ. Thư viện tiêu chuẩn không "có" boost, và sự sẵn có của một thứ gì đó trong boost không nên (và không phải) là một lý do để không áp dụng nó vào tiêu chuẩn. Ngoài ra, BGL là chung và đủ để tham gia vào các lớp cây chuyên biệt độc lập với nó. Ngoài ra, thực tế là std :: map và std :: set yêu cầu một cây là, IMO, một đối số khác để có một stl::red_black_treev.v ... Cuối cùng, cây std::mapstd::setcây được cân bằng, std::treecó thể không.
einpoklum

1
@einpoklum: "sự sẵn có của một thứ gì đó trong boost không phải là lý do để không áp dụng nó vào tiêu chuẩn" - với một trong những mục đích của boost là hoạt động như một nền tảng chứng minh cho các thư viện hữu ích trước khi kết hợp vào tiêu chuẩn, tôi chỉ có thể nói "hoàn toàn!".
Martin Bonner hỗ trợ Monica

94

Có lẽ vì lý do tương tự mà không có thùng chứa cây trong boost. Có nhiều cách để thực hiện một container như vậy, và không có cách nào tốt để làm hài lòng tất cả những người sẽ sử dụng nó.

Một số vấn đề cần xem xét:

  • Là số lượng con cho một nút cố định hoặc biến?
  • Bao nhiêu chi phí cho mỗi nút? - tức là, bạn có cần con trỏ cha mẹ, con trỏ anh chị em, vv
  • Những thuật toán để cung cấp? - các trình vòng lặp khác nhau, các thuật toán tìm kiếm, v.v.

Cuối cùng, vấn đề cuối cùng là một thùng chứa cây đủ hữu ích cho mọi người, sẽ quá nặng để làm hài lòng hầu hết những người sử dụng nó. Nếu bạn đang tìm kiếm thứ gì đó mạnh mẽ, Thư viện đồ thị Boost về cơ bản là siêu bộ của những gì mà thư viện cây có thể được sử dụng.

Dưới đây là một số triển khai cây chung khác:


5
"... không có cách nào tốt để làm hài lòng tất cả mọi người ..." Ngoại trừ vì stl :: map, stl :: multimap và stl :: set dựa trên rb_tree của stl, nó sẽ đáp ứng nhiều trường hợp như những loại cơ bản đó .
Catskul

44
Xem xét không có cách nào để lấy con của một nút std::map, tôi sẽ không gọi những thùng chứa cây đó. Đó là những container kết hợp thường được thực hiện như cây. Sự khác biệt lớn.
Vịt Mooing

2
Tôi đồng ý với Vịt Mooing, làm thế nào bạn thực hiện tìm kiếm đầu tiên trên bản đồ std ::? Nó sẽ rất tốn kém
Marco A.

1
Tôi đã bắt đầu sử dụng cây.hh của Kasper Peeters, tuy nhiên sau khi xem xét cấp phép cho GPLv3 hoặc bất kỳ phiên bản GPL nào khác, nó sẽ làm nhiễm bẩn phần mềm thương mại của chúng tôi. Tôi sẽ khuyên bạn nên xem treetree được cung cấp trong nhận xét của @hplbsh nếu bạn cần một cấu trúc cho mục đích thương mại.
Jake88

3
Các yêu cầu cụ thể về cây là một đối số để có các loại cây khác nhau, không có gì cả.
André

50

Triết lý của STL là bạn chọn một container dựa trên các đảm bảo và không dựa trên cách thức triển khai container. Ví dụ, sự lựa chọn container của bạn có thể dựa trên nhu cầu tra cứu nhanh. Đối với tất cả những gì bạn quan tâm, container có thể được triển khai như một danh sách đơn hướng - miễn là tìm kiếm rất nhanh, bạn sẽ rất vui. Đó là bởi vì dù sao bạn cũng không chạm vào bên trong, bạn đang sử dụng các hàm lặp hoặc hàm thành viên để truy cập. Mã của bạn không bị ràng buộc với cách thức container được triển khai mà là tốc độ của nó, hoặc liệu nó có một thứ tự cố định và được xác định hay không, liệu nó có hiệu quả trên không gian hay không, v.v.


12
Tôi không nghĩ anh ta đang nói về việc triển khai container, anh ta đang nói về chính một container thực tế.
Vịt Mooing

3
@MooingDuck Tôi nghĩ rằng wilmustell có nghĩa là thư viện chuẩn C ++ không định nghĩa các thùng chứa dựa trên cấu trúc dữ liệu cơ bản của chúng; nó chỉ định nghĩa các container theo giao diện của chúng và các đặc điểm có thể quan sát được như hiệu suất tiệm cận. Khi bạn nghĩ về nó, một cái cây không thực sự là một thùng chứa (như chúng ta biết). Họ thậm chí không có một bước tiến thẳng end()begin()bạn có thể lặp lại tất cả các yếu tố, v.v.
Jordan Melo

7
@JordanMelo: Vô nghĩa trên tất cả các điểm. Đó là một thứ có chứa các đối tượng. Thật là tầm thường khi thiết kế nó để có một trình lặp bắt đầu () và kết thúc () và hai chiều để lặp lại. Mỗi container có những đặc điểm khác nhau. Nó sẽ hữu ích nếu người ta có thể có đặc điểm của cây. Nên khá dễ dàng.
Vịt mướp

Do đó, người ta muốn có một thùng chứa cung cấp tra cứu nhanh cho các nút con và cha mẹ, và các yêu cầu bộ nhớ hợp lý.
doc

@JordanMelo: Từ quan điểm đó, các bộ điều hợp như hàng đợi, ngăn xếp hoặc hàng đợi ưu tiên sẽ không thuộc về STL (chúng cũng không có begin()end()). Và hãy nhớ rằng một hàng đợi ưu tiên thường là một đống, mà ít nhất trong lý thuyết là một cây (mặc dù thực hiện thực tế). Vì vậy, ngay cả khi bạn triển khai cây dưới dạng bộ điều hợp sử dụng một số cấu trúc dữ liệu cơ bản khác nhau, nó sẽ đủ điều kiện để được đưa vào STL.
andreee

48

"Tôi muốn lưu trữ một hệ thống phân cấp của các đối tượng như một cái cây"

C ++ 11 đã đến và biến mất và họ vẫn không thấy cần phải cung cấp std::tree, mặc dù ý tưởng đã xuất hiện (xem tại đây ). Có lẽ lý do họ chưa thêm điều này là vì việc xây dựng của riêng bạn trên các container hiện có rất dễ dàng. Ví dụ...

template< typename T >
struct tree_node
   {
   T t;
   std::vector<tree_node> children;
   };

Một giao dịch đơn giản sẽ sử dụng đệ quy ...

template< typename T >
void tree_node<T>::walk_depth_first() const
   {
   cout<<t;
   for ( auto & n: children ) n.walk_depth_first();
   }

Nếu bạn muốn duy trì một hệ thống phân cấp bạn muốn nó hoạt động với các thuật toán STL , thì mọi thứ có thể trở nên phức tạp. Bạn có thể xây dựng các trình vòng lặp của riêng mình và đạt được một số khả năng tương thích, tuy nhiên nhiều thuật toán chỉ đơn giản là không có ý nghĩa gì đối với hệ thống phân cấp (ví dụ, bất cứ điều gì thay đổi thứ tự của một phạm vi). Ngay cả việc xác định một phạm vi trong một hệ thống phân cấp có thể là một doanh nghiệp lộn xộn.


2
Nếu dự án có thể cho phép sắp xếp các phần tử con của Tree_node, thì việc sử dụng std :: set <> thay cho std :: vector <> và sau đó thêm toán tử <() vào đối tượng tree_node sẽ cải thiện đáng kể 'tìm kiếm' hiệu suất của một đối tượng giống như 'T'.
J Jorgenson

4
Hóa ra họ lười biếng và thực sự đã đưa ra ví dụ đầu tiên Hành vi không xác định của bạn.
dùng541686

2
@Mehrdad: Cuối cùng tôi quyết định hỏi chi tiết đằng sau bình luận của bạn ở đây .
tộc

many of the algorithms simply don't make any sense for a hierarchy. Một vấn đề giải thích. Hãy tưởng tượng một cấu trúc của người dùng stackoverflow và mỗi năm bạn muốn những người có số điểm danh tiếng cao hơn để làm chủ những người có điểm danh tiếng thấp hơn. Do đó cung cấp BFS iterator và so sánh phù hợp, mỗi năm bạn chỉ cần chạy std::sort(tree.begin(), tree.end()).
doc

Với cùng một mã thông báo, bạn có thể dễ dàng xây dựng một cây kết hợp (để mô hình hóa các bản ghi giá trị khóa không cấu trúc, như JSON chẳng hạn) bằng cách thay thế vectorbằng maptrong ví dụ trên. Để hỗ trợ đầy đủ cấu trúc giống như JSON, bạn có thể sử dụng variantđể xác định các nút.
tộc

43

Nếu bạn đang tìm kiếm một triển khai cây RB, thì stl_tree.h cũng có thể phù hợp với bạn.


14
Kỳ lạ thay, đây là câu trả lời duy nhất thực sự trả lời câu hỏi ban đầu.
Catskul

12
Xem xét anh ta muốn có một "Heiarchy", có vẻ an toàn khi cho rằng bất cứ điều gì với "cân bằng" là câu trả lời sai.
Vịt Mooing

11
"Đây là một tệp tiêu đề nội bộ, được bao gồm bởi các tiêu đề thư viện khác. Bạn không nên cố gắng sử dụng nó trực tiếp."
Dan

3
@Dan: Sao chép nó không cấu thành sử dụng trực tiếp.
einpoklum

12

bản đồ std :: dựa trên cây đen đỏ . Bạn cũng có thể sử dụng các thùng chứa khác để giúp bạn thực hiện các loại cây của riêng mình.


13
Nó thường sử dụng cây đỏ-đen (Không bắt buộc phải làm như vậy).
Martin York

1
GCC sử dụng cây để thực hiện bản đồ. Bất cứ ai cũng muốn nhìn vào thư mục bao gồm VC của họ để xem microsoft sử dụng cái gì?
JJ

// Lớp cây đỏ-đen, được thiết kế để sử dụng trong việc thực hiện STL // các thùng chứa kết hợp (bộ, multiset, bản đồ và multimap). Lấy từ tệp stl_tree.h của tôi.
JJ

@JJ Ít nhất trong Studio 2010, nó sử dụng một ordered red-black tree of {key, mapped} values, unique keyslớp bên trong , được định nghĩa trong <xtree>. Hiện tại không có quyền truy cập vào một phiên bản hiện đại hơn.
Thời gian của Justin - Phục hồi lại

8

Theo một cách nào đó, std :: map là một cây (bắt buộc phải có các đặc tính hiệu suất tương tự như cây nhị phân cân bằng) nhưng nó không làm lộ chức năng của cây khác. Lý do có khả năng đằng sau không bao gồm cấu trúc dữ liệu cây thật có lẽ chỉ là vấn đề không bao gồm mọi thứ trong stl. Stl có thể được xem như là một khung để sử dụng trong việc thực hiện các thuật toán và cấu trúc dữ liệu của riêng bạn.

Nói chung, nếu có một chức năng thư viện cơ bản mà bạn muốn, đó không phải là trong stl, cách khắc phục là xem BOOST .

Mặt khác, có rất nhiều thư viện ngoài kia , tùy thuộc vào nhu cầu của cây của bạn.


6

Tất cả các thùng chứa STL được thể hiện bên ngoài dưới dạng "chuỗi" với một cơ chế lặp. Cây không theo thành ngữ này.


7
Một cấu trúc dữ liệu cây có thể cung cấp preorder, inorder hoặc postorder traversal thông qua các vòng lặp. Trong thực tế đây là những gì std :: map làm.
Andrew Tomazos

3
Có và không ... nó phụ thuộc vào ý nghĩa của "cây". std::mapđược triển khai trong nội bộ dưới dạng btree, nhưng bên ngoài nó xuất hiện dưới dạng SEQUENCE được sắp xếp của PAIRS. Cho bất cứ yếu tố nào bạn có thể hỏi ai là người trước và người đến sau. Một cấu trúc cây nói chung chứa các phần tử mà mỗi phần tử chứa khác không áp đặt bất kỳ sự sắp xếp hoặc hướng nào. Bạn có thể định nghĩa các trình vòng lặp đi bộ cấu trúc cây theo nhiều cách (sallow | sâu trước | cuối ...) nhưng một khi bạn đã thực hiện nó, một std::treecontainer phải trả về một trong số chúng từ một beginhàm. Và không có lý do rõ ràng để trả lại cái này hay cái khác.
Emilio Garavaglia

4
Bản đồ std :: thường được biểu thị bằng cây tìm kiếm nhị phân cân bằng, không phải cây B. Đối số tương tự mà bạn đã đưa ra có thể áp dụng cho std :: unordered_set, nó không có thứ tự tự nhiên, nhưng trình bày các trình lặp bắt đầu và kết thúc. Yêu cầu của bắt đầu và kết thúc chỉ là nó lặp đi lặp lại tất cả các yếu tố theo một thứ tự xác định, không phải là phải có một yếu tố tự nhiên. preorder là một thứ tự lặp hoàn toàn hợp lệ cho một cây.
Andrew Tomazos

4
Hàm ý của câu trả lời của bạn là không có cấu trúc dữ liệu stl n-tree vì nó không có giao diện "chuỗi". Điều này chỉ đơn giản là không chính xác.
Andrew Tomazos

3
@EmiloGaravaglia: Bằng chứng là std::unordered_set, không có "cách duy nhất" lặp lại các thành viên của nó (thực tế là thứ tự lặp là giả ngẫu nhiên và được thực hiện xác định), nhưng vẫn là một thùng chứa stl - điều này từ chối quan điểm của bạn. Lặp lại từng phần tử trong một container vẫn là một thao tác hữu ích, ngay cả khi thứ tự không được xác định.
Andrew Tomazos

4

Bởi vì STL không phải là thư viện "mọi thứ". Nó chứa, về cơ bản, các cấu trúc tối thiểu cần thiết để xây dựng mọi thứ.


13
Cây nhị phân là một chức năng cực kỳ cơ bản và trên thực tế, cơ bản hơn các thùng chứa khác vì các loại như std :: map, std :: multimap và stl :: set. Vì các loại đó dựa trên chúng, bạn sẽ mong đợi loại cơ bản được phơi bày.
Catskul

2
Tôi không nghĩ OP đang yêu cầu cây nhị phân , anh ta yêu cầu một cây để lưu trữ thứ bậc.
Vịt Mooing

Không chỉ vậy, việc thêm một "thùng chứa" cây vào STL sẽ có nghĩa là thêm nhiều khái niệm mới, ví dụ như một bộ điều hướng cây (khái quát hóa Iterator).
alfC

5
"Cấu trúc tối thiểu để xây dựng mọi thứ" là một tuyên bố rất chủ quan. Bạn có thể xây dựng mọi thứ với các khái niệm C ++ thô, vì vậy tôi đoán tối thiểu thực sự sẽ không có STL.
doc


3

IMO, một thiếu sót. Nhưng tôi nghĩ có lý do chính đáng để không đưa cấu trúc Cây vào STL. Có rất nhiều logic trong việc duy trì một cây, được viết tốt nhất là các hàm thành viên vào TreeNodeđối tượng cơ sở . Khi nàoTreeNode được gói trong một tiêu đề STL, nó sẽ trở nên rắc rối hơn.

Ví dụ:

template <typename T>
struct TreeNode
{
  T* DATA ; // data of type T to be stored at this TreeNode

  vector< TreeNode<T>* > children ;

  // insertion logic for if an insert is asked of me.
  // may append to children, or may pass off to one of the child nodes
  void insert( T* newData ) ;

} ;

template <typename T>
struct Tree
{
  TreeNode<T>* root;

  // TREE LEVEL functions
  void clear() { delete root ; root=0; }

  void insert( T* data ) { if(root)root->insert(data); } 
} ;

7
Đó là rất nhiều sở hữu con trỏ thô mà bạn có ở đó, nhiều trong số đó không cần phải là con trỏ.
Vịt mướp

Đề nghị bạn rút câu trả lời này. Một lớp TreeNode là một phần của việc thực hiện cây.
einpoklum

3

Tôi nghĩ rằng có một số lý do tại sao không có cây STL. Cây chủ yếu là một dạng cấu trúc dữ liệu đệ quy, giống như một thùng chứa (danh sách, vectơ, tập hợp), có cấu trúc tốt rất khác nhau khiến cho các lựa chọn chính xác trở nên khó khăn. Chúng cũng rất dễ dàng để xây dựng ở dạng cơ bản bằng cách sử dụng STL.

Một cây gốc hữu hạn có thể được coi là một thùng chứa có giá trị hoặc tải trọng, giả sử là một thể hiện của lớp A và, một bộ sưu tập các cây gốc (phụ) có thể trống; cây với bộ sưu tập trống của cây con được coi là lá.

template<class A>
struct unordered_tree : std::set<unordered_tree>, A
{};

template<class A>
struct b_tree : std::vector<b_tree>, A
{};

template<class A>
struct planar_tree : std::list<planar_tree>, A
{};

Người ta phải suy nghĩ một chút về thiết kế lặp, v.v. và hoạt động của sản phẩm và đồng sản phẩm nào cho phép xác định và hiệu quả giữa các cây - và STL ban đầu phải được viết tốt - sao cho bộ chứa, vectơ hoặc danh sách trống thực sự trống rỗng của bất kỳ tải trọng nào trong trường hợp mặc định.

Cây xanh đóng một vai trò thiết yếu trong nhiều cấu trúc toán học (xem các bài báo cổ điển của Butcher, Grossman và Larsen; cũng là các bài báo của Connes và Kriemer để biết ví dụ về chúng có thể được tham gia và cách chúng được sử dụng để liệt kê). Thật không đúng khi nghĩ rằng vai trò của họ chỉ đơn giản là tạo điều kiện cho một số hoạt động khác. Thay vào đó, họ tạo điều kiện cho các nhiệm vụ đó vì vai trò cơ bản của chúng là cấu trúc dữ liệu.

Tuy nhiên, ngoài cây còn có "đồng cây"; các cây ở trên đều có thuộc tính mà nếu bạn xóa gốc bạn sẽ xóa mọi thứ.

Hãy xem xét các trình vòng lặp trên cây, có lẽ chúng sẽ được nhận ra như một chồng các trình vòng lặp đơn giản, đến một nút và với cha mẹ của nó, ... cho đến tận gốc.

template<class TREE>
struct node_iterator : std::stack<TREE::iterator>{
operator*() {return *back();}
...};

Tuy nhiên, bạn có thể có bao nhiêu tùy thích; gọi chung chúng tạo thành một "cây" nhưng trong đó tất cả các mũi tên chảy theo hướng về phía gốc, cây đồng này có thể được lặp qua các vòng lặp hướng tới trình lặp và gốc không quan trọng; tuy nhiên nó không thể được điều hướng qua hoặc xuống (các trình vòng lặp khác không được biết đến) cũng như không thể xóa toàn bộ các trình vòng lặp trừ khi theo dõi tất cả các trường hợp.

Cây rất hữu ích, chúng có rất nhiều cấu trúc, điều này làm cho nó trở thành một thách thức nghiêm trọng để có được cách tiếp cận chính xác. Theo quan điểm của tôi đây là lý do tại sao chúng không được thực hiện trong STL. Hơn nữa, trong quá khứ, tôi đã thấy mọi người tôn giáo và tìm thấy ý tưởng về một loại container chứa các trường hợp thuộc loại riêng của nó đầy thách thức - nhưng họ phải đối mặt với nó - đó là những gì một loại cây đại diện - đó là một nút chứa một có thể bộ sưu tập trống của cây (nhỏ hơn). Ngôn ngữ hiện tại cho phép nó mà không có thách thức khi cung cấp hàm tạo mặc định cho việc container<B>không phân bổ không gian trên heap (hoặc bất kỳ nơi nào khác) cho một B, v.v.

Tôi cho một người sẽ hài lòng nếu điều này đã làm, trong một hình thức tốt, tìm đường đến tiêu chuẩn.


0

Đọc qua các câu trả lời ở đây, lý do được đặt tên phổ biến là người ta không thể lặp qua cây hoặc cây không có giao diện tương tự với các thùng chứa STL khác và người ta không thể sử dụng thuật toán STL với cấu trúc cây như vậy.

Trong tâm trí đó, tôi đã cố gắng thiết kế cấu trúc dữ liệu cây của riêng mình, nó sẽ cung cấp giao diện giống STL và sẽ có thể sử dụng được với các đại số STL hiện có càng nhiều càng tốt.

Ý tưởng của tôi là cây phải dựa trên các container STL hiện có và nó không được ẩn container, để nó có thể truy cập được để sử dụng với các thuật toán STL.

Tính năng quan trọng khác mà cây phải cung cấp là các trình vòng lặp đi qua.

Đây là những gì tôi đã có thể đến với: https://github.com/igagis/utki/blob/master/src/utki/tree.hpp

Và đây là các bài kiểm tra: https://github.com/igagis/utki/blob/master/tests/tree/tests.cpp


-9

Tất cả các container STL có thể được sử dụng với các trình vòng lặp. Bạn không thể có một trình vòng lặp một cây, bởi vì bạn không có cách '' một quyền '' để đi qua cây.


3
Nhưng bạn có thể nói BFS hoặc DFS là cách chính xác. Hoặc hỗ trợ cả hai. Hoặc bất kỳ khác bạn có thể tưởng tượng. Jut nói với người dùng nó là gì.
tomas789

2
trong std :: map có cây lặp.
Jai

1
Một cây có thể định nghĩa loại trình lặp tùy chỉnh của riêng nó đi qua tất cả các nút theo thứ tự từ "cực" này sang cực khác (nghĩa là đối với bất kỳ cây nhị phân nào có đường dẫn 0 & 1, nó có thể cung cấp một trình vòng lặp đi từ "tất cả 0" đến "tất cả 1s "và một iterator ngược mà không ngược lại, cho một cái cây với độ sâu 3 và nút khởi động s, ví dụ, nó có thể lặp qua các nút như s000, s00, s001, s0, s010, s01, s011, s, s100, s10, s101, s1, s110, s11, s111(" tận cùng bên trái" thành "ngoài cùng bên phải"), nó cũng có thể sử dụng một mô hình sâu traversal ( s, s0, s1, s00, s01, s10, s11,
Thời gian của Justin - Hồi phục lại

, v.v.) hoặc một số mẫu khác, miễn là nó lặp đi lặp lại trên mỗi nút theo cách mà mỗi cái chỉ được truyền qua một lần duy nhất.
Thời gian của Justin - Phục hồi Monica

1
@doc, điểm rất hay. Tôi nghĩ std::unordered_setlà "tạo ra" một chuỗi bởi vì chúng ta không biết cách lặp tốt hơn các yếu tố khác hơn là một cách tùy tiện (được cung cấp nội bộ bởi hàm băm). Tôi nghĩ đó là trường hợp ngược lại của cây: việc lặp lại unordered_setkhông được xác định rõ, theo lý thuyết thì "không có cách nào" để định nghĩa một lần lặp khác hơn là "ngẫu nhiên". Trong trường hợp của cây có nhiều cách "tốt" (không ngẫu nhiên). Nhưng, một lần nữa, quan điểm của bạn là hợp lệ.
alfC
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.