Established data structure/pattern? List with dynamically linked children - arrays

I need a solution where I have one "master" list/array that has a number of sequentially ordered linked children, each one representing a sub-segment of the parent list. It resembles the "unrolled linked list" pattern, but here the segment-list size should be dynamic.
Here I will try to explain further. I would like to find out if there's an established term for this kind of data structure/pattern (in the same manner of "graph", "binary tree" etc.) that would be to my help when further investigating this, trying to find the best implementation.
Let's say we have a "master" list with a size of ten items, 0-9, and with three children a, b and c representing sub-segments of the master in the following way:
"master" -------------------
0-9 0 1 2 3 4 5 6 7 8 9
===== ========= ===
"children" a b c
0-2 3-7 8-9
Ideally, the solution should allow
the master to create and adjust sub-segment size of it's children (depending on rules connected to the master list data items content)
the children to change their sub-segment size, causing the linked siblings to adjust their size/positions accordingly
handle under- and overflow of total children sizes compared to master size
Any blogs, articles, code snippets etc that tackles something like this would be to great help! (My solutions will be created in php and as3, but language doesn't matter here).
Thanx!

If I understand correctly what you want. Build your data structure the other way around. List (or vector) of children nodes and each keeps a list to master node with backlink. Changing sub-segment size in such case would be simple moving of master nodes from one list to another.
1 -> 2 -> 3 -> 4 -> 5
\ / / \ /
a----- b

Related

Search for a list of elements in a list which contains lists

I have a set of elements {1,2,3},{2,3,4},{1,2,4},{7,8},{3,4,7,9},{12,16,18,19}, {1,2,4}.
I need to have a data structure which contains the list above appeared only once. If any new list appears and if it matches any of the existing list then I don't want that to be added to the resulting data structure.
For the above example the expected result should be :
{1,2,3},{2,3,4},{1,2,4},{7,8},{3,4,7,9},{12,16,18,19}.
One solution which I am having is to use Trees.
For ex: {1,2,3},{1,2,4}
In the above list I will branch out for value 3 of 1st list and value 4 of 2nd list from the node which has value 2. In this way I can trace the list from the root and find whether the list appears or not.
Root
|
|
1
|
|
------2------
| |
| |
3 4
Please suggest if is there any algorithm to make it faster and in a simple way using C.
You can achieve this using graph data structure.
To do so in c, you can use either of the following methods :
Adjacency Matrix
In this method, you need to maintain a matrix of relationship between your numbers, check out the below image :
Linked list :
In this method, you will maintain a list of connections, i.e if 2 has a connection to 1,3,4 then a list of 1,3,4 will be made with a head value of : 2
These images are taken from : http://simplestcodings.blogspot.in .
And you can find great explaination and example code on the same site at : http://simplestcodings.blogspot.in/2013/09/graphs.html link
Hope it helps.

Split Linked list

I'm new to C programming and I kinda need some help in the frontBackSplitLinkedList part,
For example, assume that given linked list is: 2 6 7 8 9
The resulting front and back are:
front: 2 6 7
back: 8 9
I've searched through some websites but most of the codings are using nodes instead of linked list.
Any idea how to do this? Thank you!
You do not actually have to count elements in list, as far as i see it, you store the number of elements in _linkedlist. You can always use that value to split however you like. I would strongly suggest to first simlify your List, so it can add elements only to the back or the front of the List, it will be easier to work with it, but won't really affect the principle of split function.
If I understand your question correcly then you want to split the list in the middle, where un uneven list will be split a frontlist that is one larger than the backlist.
First of all you must have a count of the list length. I propose that you walk the list, counting the number of list nodes.
Then you divide that number as follows:
count = (count+1)/2;
Now we need to know if you must create two new lists (so you have to make copies of all the list nodes), or whether the old list may be reused. Assume it may be reused, then you assign the old list to frontlist, walk count listnodes, asign that one to backlist and set the next member of the one before it to NULL.
You are done now, except that the caller may no longer use the original list (it has become equivalent, and actually is, frontlist).

Implementing Cloud of Communities using Linked List

Recently I came across a question, I had to code it but failed to do so effectively. So i'll try to explain the question in the best way I can, and it goes like..
There are different people belonging to different communities. Say for example, 1 belongs to C1, 2 belong to C2 and 3 belongs to C3. We can perform two operations, Query and Join. Query returns the total number of people belonging to the person's community. And Join is used to combine the communities of exactly two persons into one.
We are taking the number of people and the number of operations to be performed as an input and we need to produce the result onto the standard output.
Example Case: (Q -> Query and J -> Join)
3 // No. of People
6 // No. of Operations
Q 1 // Prints 1
J 1,2 // Joins communities of 1 and 2
Q 1 // Prints 2
J 2,3 // Joins communities of 1 and 2
Q 3 // Prints 3
Q 1 // Prints 3
So essentially, its like people are belonging to individual bubbles initially and on join, we join the bubbles of two peoples to form a larger bubble containing two people.
There are different ways to solve this problem. Using ArrayList methods of Java, its pretty easy. I was trying to solve it using arrays.
My approach was to form an array for each person initially and as we join two communities, the respective arrays are added with the people as described :
Arr1 : 1 // Array for Person 1 ; Size 1
Arr2 : 2 // Array for Person 2 ; Size 1
J 1,2 results in,
Arr1 : 1,2 // Size 2
Arr2 : 2,1 // Size 2
But I was told that this is not an effective approach, an effective approach would be to make use of Linked List. I was unable to use linked list to solve it. So I would like some inputs from you guys on the approach, how exactly do I make use of Linked List to keep track of Join operations?
Sorry for the long post, and thanks in advance :)
P.S : I am not sure if the title is appropriate, kindly suggest proper title in case its not appropriate.
I do not know why somebody felt that linked lists would be better than arrays in this instance, but joining the communities is as simple as adding all of the members of one to the other, and changing all the pointers that point to the now empty community to point to the node containing all of the members. Query should be simple enough that it goes without saying.

Data structure to handle the requirement of following use case

All the records in a database is saved in (key, value) pair formats.Records can always be retrieved by specifying key value. Data structure needs to be developed to handle following scenarios
Access all the records in a linear fashion (Array or linked list is best data structure for this scenario to access in O(N) time)
retrieve the record by providing the key (hash table can be implemented to index it in O(1) complexity)
Retrieve set of records for a value at a particular byte in the key . Ex: List of all records for which 2nd number(10's place) in the key should be 5 and if the keys are 256, 1452, 362, 874, the records for keys , 256 and 1452 should be returned
I am assuming you keys are at most d digits long (in decimal).
How about a normal hashtable and an additional 10*d two dimensional array (let's call it A) of sets. A[i][j] is the set of keys which have digit i in the jth position. The sets can support O(1) insert/delete if implemented themselves as hashtables.
For 1 and 2, I think Linked Hash Map is a good choice.
For the point 3, an additional Hash map with (digit, position) tuple as key and list of pointers to the values.
Both data structures can be wrapped inside one, and both will point to the same data, of course.
Store the keys in a trie. For the numbers in your example (assuming 4 digit numbers) it looks like this:
*root*
|
0 -- 2 - 5 - 6
| |
| +- 3 - 6 - 2
| |
| +- 8 - 7 - 4
|
1 - 4 - 5 - 2
This data structure can be traversed in a way that returns (1) or (3). It won't be quite as fast for (3) as would maintaining an index for each digit, so I guess it's a question of whether space or lookup time is your primary concern. For (2), it is already O(log n), but if you need O(1), you could store the keys in both the trie and a hash table.
The first thing that comes to mind is embedding a pair of nodes in each record. One of the nodes would be a part of a tree sorted by the record index and the other, part of a tree sorted by the record key. You can then have quick access to the records by index or key using these trees. With this you can also quickly visit records in sequential index or key order. This covers the first and second requirement.
You can add another node for a tree of records whose values contain 5 in the tens position. That covers the third requirement.
Extra benefit: the same tree handling code will be used in all cases.
A dictionary (hash map, etc.) would easily handle those requirements, although your third requirement would be an O(N) operation. You just iterate over the keys and select those that match your criteria. You don't say what your desired performance is for that case.
But O(N) might be plenty fast enough. How many items are in your data set, and how often will you be performing that third function?

Queue using two stacks

I implemented it as an array with two stacks adjacent to each other, but their tops on the either ends. That is, if top(stack1) is at the beginning of keys, top(stack2) is at the end of keys. Bottom(Stack1) and Bottom(Stack2) should be adjacent, but anywhere between top(Stack1) and top(Stack2). To delete, I am poping from Top(Stack1), and for inserting, I am pushing in Top(stack2). Could somebody pls tell me if it is correct to do it this way?
When I read CLRS, I solved the que this way, and had no way to know that it was ryt or not. But it was asked in today's exam, and everyone later on was discussing the way given officially (here and everywhere else on net), so it seems I am the only one to do it such a way. I really wanna know if this is wrong or right ? Please help
Queues and stacks are abstract data structures which have well defined behaviors and any implementation of these data structures should respect this contract.
Your idea of using a single array to implement two stacks is good. But, the inserts and deletes should happen on both stacks.
For eg. lets say you have this setup
2 3 4 5 6
top(stack1) is 2
bottom(stack1) is 4
top(stack2) is 6
bottom(stack2) is 5
after popping from stack1 3 times you would have reached the bottom of your stack i.e 4 and no longer able to pop anything even though there are two more elements in your QUEUE implementation. So, a few corrections to your implementation is required.
So, if I were to implement two stacks which emulate a QUEUE, this is how I would do it.
Stack1: 2 3 4 5 6 which is essentially an array
2 is the bottom of the stack and 6 is the top of the stack.
Stack2: empty
Insert an element to Queue:
This is very simple. Just add to the end of array i.e stack1
stack1:2 3 4 5 6 7
Now 7 is the top of the stack.
Delete an element from Queue:
1. Pop all elements in stack1 and insert them to stack2. So, your array will be reversed
stack1:empty
stack2: 7 6 5 4 3 2 . Now 2 is at the top of the stack.
2. Now your top(stack2) will be pointing to 2. Just pop it.
7 6 5 4 3
3. Now for the remaining elements in stack2, pop from stack2 and insert them to stack1.
stack2:empty
stack1:3 4 5 6 7
PS: The above algorithm assumes that you know how to manage memory for arrays as it shrinks or expands.
I think you actually can implement a queue using two adjacent stacks as you described. The problem is that you cannot implement those two adjacent stacks with an array efficiently. I mean your queue seems OK, but when you try to use the underlying stacks, you encounter the problem how to insert a new item at the beginning of the array (i.e. push to stack1). You need to move (copy) all items in your array to push an item into stack1. And that's ill design.
For those who are looking for the solution, a sample one is this:
Let's say we have two stacks S1 and S2.
A queue has the given two behaviours:
Enqueue: Insert an element into the queue. For this, simply push into S1.
Dequeue: Pop all elements from from S1 one by one, simultaneously pushing them into S2. Now pop from S2. The popped element is the desired result of Dequeue.
Readers are encouraged to find more optimized solutions to this and post them here if possible :)
Here is an example in python using the built in array/list for two stacks.
class Queue2Stacks(object):
def __init__(self):
self.in_stack = []
self.out_stack = []
def enqueue(self, element):
self.in_stack.append(element)
def dequeue(self):
if not self.out_stack:
while self.in_stack:
self.out_stack.append(self.in_stack.pop())
return self.out_stack.pop()

Resources