Binary Search Tree sorted by two keys

I have a fictional character class with a unique string member variable, name, and a second member variable that can have duplicates. The unique key is the name of the character, and the second key is the book the character is from. I want to build a Binary Search Tree to sort it by both the unique key and the secondary key. I thought about building two different classes for fictional character, but that would create 2 binary search trees. Any ideas? Thank you!
Typical use case for Boost.MultiIndex, perhaps:
http://www.boost.org/doc/libs/1_65_1/libs/multi_index/doc/tutorial/index.html

Something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>

struct character
{
    std::string name ; // unique key
    std::string book ; // book in which the character appears

    // other stuff
};

struct by_name{}; struct by_book{}; // index tags

namespace mi = boost::multi_index ;

using bst_t = mi::multi_index_container<

                    character, // value

                    mi::indexed_by< // keys
                        mi::ordered_non_unique< mi::tag<by_name>, mi::member<character,std::string,&character::name> >,
                        mi::ordered_non_unique< mi::tag<by_book>, mi::member<character,std::string,&character::book> >
                    >
              > ;

int main()
{
    bst_t bst { { "Alice", "Adventures in Wonderland" },
                { "Alice", "Through the Looking-Glass" },
                { "Sylvie", "Sylvie and Bruno" },
                { "The Cheshire Cat", "Adventures in Wonderland" },
                { "Bandersnatch", "Through the Looking-Glass" }
              };

    bst.insert( { "Bruno", "Sylvie and Bruno" } ) ;
    bst.insert( { "The Mock Turtle", "Adventures in Wonderland" } ) ;
    bst.insert( { "Alice", "Resident Evil" } ) ;
    bst.insert( { "Humpty Dumpty", "Through the Looking-Glass" } ) ;

    // look up by name
    const std::string name = "Alice" ;
    std::cout << "books in which the character '" << name << "' appears:\n" ;
    const auto& view_names = mi::get<by_name>(bst) ;
    for( auto iter = view_names.lower_bound("Alice") ; iter != view_names.upper_bound("Alice") ; ++iter )
        std::cout << '\t' << iter->book << '\n' ;

    // look up by book
    const std::string book = "Adventures in Wonderland" ;
    std::cout << "\ncharacters in the book '" << book << "':\n" ;
    const auto& view_books = mi::get<by_book>(bst) ;
    for( auto iter = view_books.lower_bound(book) ; iter != view_books.upper_bound(book) ; ++iter )
        std::cout << '\t' << iter->name << '\n' ;

    // print ordered by name
    std::cout << "\ncharacters ordered by name:\n" ;
    for( auto iter = view_names.begin() ; iter != view_names.end() ; ++iter )
        std::cout << "\t'" << iter->name << "' in '" << iter->book << "'\n" ;

    // print ordered by book
    std::cout << "\nlist of books and the characters in them:\n" ;
    std::string last_book ;
    for( auto iter = view_books.begin() ; iter != view_books.end() ; ++iter )
    {
        if( iter->book != last_book )
            std::cout << "\tcharacters in book '" << (last_book=iter->book) << "':\n" ;

        std::cout << "\t\t'" << iter->name << "'\n" ;
    }
}

http://coliru.stacked-crooked.com/a/0f7ccd57c538a0c0
Topic archived. No new replies allowed.