Data Structure for Multi-Level Traversal
I have an application that deals with data in the following structure:
struct Message
{
int time;
string name;
string details;
};
For example, I may have a data set that looks like the following:
9:00:00 Bob <Info>
9:01:00 John <Info>
9:05:00 Bob <Info>
9:11:00 Mary <Info>
9:17:00 John <Info>
9:25:00 Mary <Info>
9:30:00 Bob <Info>
And I will have a list of Message
structures that represent each line in the data set.
Some operations I will need to do on this data include:
- Collect all data in chronological order and
dostuff()
- Collect all data from
John
(or whoever) in chronological order anddostuff()
So, I need a way to traverse the list such that I can pass every messag开发者_开发问答e in chronological order, and also choose a person, and pass through only their messages in chronological order.
My thoughts are to have a struct like this:
struct Node
{
Message* message;
Node* next_time;
Node* next_name;
};
In which next_time
points to the next Node
in chronological order, and next_name
points to the next Node
that belongs to message->name
. And a Root
structure points to the first of each type.
struct Root
{
Node* first_time;
Node* first_bob;
Node* first_john;
Node* first_mary;
Node* last_time;
Node* last_bob;
Node* last_john;
Node* last_mary;
};
Here is an image to illustrate the point.
This structure allows me to fairly easily traverse through every message, or through only Bob's messages, or only John's, etc.
However, I am worried that maybe this is more complicated than it needs to be. I also have concerns about maintenance (see below). I need the search/select/read operations to be pretty fast, which I think they are. And I need insert operations to be reasonably fast. But right now, for every Message
I insert, I must (1) update some next_time
pointer and (2) update some next_name
pointer.
My question is: Does a data structure exist that provides this type of functionality already? If not, am I approaching this problem correctly?
Please provide any code samples in C++ or C#, if possible.
Thanks.
Additional: Suppose later I want to add to my Message
struct. Let's say I add a field called City
. Now, I may want to do this:
- Collect all data from a specific
City
in chronological order anddostuff()
This would require adding a next_city
, and then for every insert, I would have to update next_time
, next_name
, AND next_city
.
Further, suppose I want to do this:
- Collect all data from a specific
City
AND a specificname
in chronological order anddostuff()
I think this makes the problem incredibly more difficult unless I opt to traverse every Message
and skip the ones I don't care about.
A simple linked list of all messages (sorted by time).
struct Node
{
Message* message;
Node* next_name;
};
This will satisfy req 1. You can add() and getAll() in O(1)
A separate hashmap with User as key and a list of Node* as values.
Hashmap
{key = User, value = List(Message*)}
This will satisfy req 2. You can add a new entry to the end of the list of the specific user O(1) and getAllOfUser() can also run in O(1)
I would probably create a class to represent a user, storing users in an hash table by some identifier like the name, then have each user hold a list of Message
s sorted in chronological order, which are also stored in a single global list which holds everyone's Message
s in chronological order. For every added Message
, you'd have to insert it once in each list (by list I mean some collection), which could be log n
time, or as bad as n
, depending on the data structure.
精彩评论