Store link list node address - c++

Im currently writing a descending sort function for a doubly link list. I have a flag for the largest value but wondering if there is a way to store the address of a node pointer so i can set its flag outside the loop when operations are done.
Thanks
In this case, our data is relevance
float findLargest(DoublyLinkList largestdata)
{
ListPlayHolder *findbiggest = largestdata.lhead;
float largest = findbiggest ->relevance;
while (findbiggest ->next != NULL)
{
if (findbiggest ->relevance > largest && findbiggest ->largestFlag != true)
{
largest = findbiggest ->relevance;
}
findbiggest = findbiggest->next;
}
return largest;
}
This is no fancy sort, just trying to make a simplistic descending sort of my data. Once i find the largest, i want to set its nodes flag to true. Just need a way to store the address.

If you used std::list you could use std::sort with different comparison functions and not have to change the node structure for every different ordering sequence.
Another idea is to place your items into a std::vector and create std::list<item *> for each item. This would allow you to access the items in the vector in various orders. For example, one list could be for ascending by title. Another could be descending by relevance.

As I understand it, you only need to keep a pointer to the largest element, so nothing fancy, just another ListPlayHolder*(which seems like the data type of a pointer to a node - a quite confusing name if you ask me, but whatever).
Also, I would recommend not to initalize largest with something pointed to by findbiggest - haven't seen your other list code, but I guess that pointer might be NULL if the list is empty.
You actually don't need to store the relevance value separately if you instead hold on to a pointer of the currently largest object (thanks #WhozCraig). Here's the modified code:
ListPlayHolder* findbiggest = largestdata.lhead;
ListPlayHolder* largest = findbiggest;
while (findbiggest && findbiggest ->next != NULL)
{
if (findbiggest ->relevance > largest->relevance && findbiggest->largestFlag != true)
{
largest = findbiggest;
}
findbiggest = findbiggest->next;
}
// here do whatever modifications you need to do to flags? or maybe return largestPtr?
largest->largestFlag = true;
return largest->relevance;

Related

Create a checkerboard or "Interweave" two linked-lists. IE changing the pointers of two linked lists

So I have two linked lists, each holding a color:
1.black->2.black->3.black->4.black->5.black->NULL
1.red ->2.red ->3.red ->4.red ->5.red ->NULL
I want the function to return
1.black->2.red ->3.black->4.red ->5.black->NULL
1.red ->2.black->3.red ->4.black->5.red ->NULL.
Lets name the first pointers, firstBlack and firstRed. To achieve this "checkerboard" pattern, I switch the nodes that each first is pointing to with a simple swap to the other list, advance the pointer two spots, then repeat until I'm at the end of the list.
while(firstBlack->next != NULL && firstRed->next != NULL) {
Node * temp = firstBlack->next;
firstBlack->next = firstRed->next;
firstRed->next = temp;
firstBlack = firstBlack->next->next;
firstRed = firstRed->next->next;
}
However, the function isn't doing what it's supposed to although I'm fairly certain that my logic is correct. I am also getting seg faults :(
This is a simple enough code, please use a debugger and debug the code step by step.
Also please post the entire code not just what's in the while loop.
This code should work correctly.
//Some methods to create these linked lists.
pBlackHead = CreateBlackList();
pRedHead = CreateRedList();
firstBlack = pBlackHead;
firstRed = pRedHead;
while(firstBlack->next != NULL && firstRed->next != NULL){
Node * temp = firstBlack->next;
firstBlack->next = firstRed->next;
firstRed->next = temp;
firstBlack = firstBlack->next;
firstRed = firstRed->next;}
While printing the list to check the correctness use pBlackHead , pRedHead. A debugger is not currently available on the system I am using but this should work.
You are advancing two steps without checking end conditions. Because you have an odd number of items, you dereference a null pointer.
You don't need to care which tail originated in which list to swap them
for(; left->next && right->next; left = left->next, right = right->next) {
std::swap(left->next, right->next);
}

How to count no of elements before a given element in std::set

I want to find no of elements present in set before the lower bound of an given element,I thought of using pointer arithmetic with std::set::iterators since they behave like pointer, here is what I tried:
set<int>q;
set<int>::iterator curr;
set<int>::iterator strt;
l = num.size();
q.insert(num[l-1]);
strt = q.begin();
temp = 1;
int x;
for(int i=l-2;i>=0;i--)
{
curr = q.lower_bound(num[i]);
if(curr == q.end())
stats.push_back({temp,0});
else
{
x = curr-strt;//ERROR
stats.push_back({x,temp-x});
}
q.insert(num[i]);
temp++;
}
is there is any way find no of elements present in set before the lower bound of an given element?
You'll have to iterate through the set from the beginning to the point you've found to count the number of elements. There's a library function for that:
x = std::distance(strt, curr);
Arithmetic like curr-strt is only defined for random access iterators, where the calculation can be done in constant time. Functions like distance will work for more general iterator types, but might be slow if the iterator doesn't directly support that operator.
Using data structure augmentation, it's possible to do dynamic order statistics in logarithmic time.
I've written once a libstdc++ extension for this, and later on mad a python version.

For Looping Link List using Templates

Having used the various search engines (and the wonderful stackoverflow database), I have found some similar situations, but they are either far more complex, or not nearly as complex as what I'm trying to accomplish.
C++ List Looping
Link Error Using Templates
C++:Linked List Ordering
Pointer Address Does Not Change In A Link List
I'm trying to work with Link List and Node templates to store and print non-standard class objects (in this case, a collection of categorized contacts). Particularly, I want to print multiple objects that have the same category, out of a bunch of objects with different categories. When printing by category, I compare an sub-object tmpCategory (= "business") with the category part of a categorized contact.
But how to extract this data for comparison in int main()?
Here's what I'm thinking. I create a GetItem member function in LinkList.tem This would initialize the pointer cursor and then run a For loop until the function input matches the iteration number. At which point, GetItem returns object Type using (cursor -> data).
template <class Type>
Type LinkList<Type>::GetItem(int itemNumber) const
{
Node<Type>* cursor = NULL;
for(cursor = first;
cursor != NULL;
cursor = (cursor -> next))
{
for(int i = 0; i < used; i++)
{
if(itemNumber == i)
{
return(cursor -> data);
}
}
}
}
Here's where int main() comes in. I set my comparison object tmpCategory to a certain value (in this case, "Business"). Then, I run a For loop that iterates for cycles equal to the number of Nodes I have (as determined by a function GetUsed()). Inside that loop, I call GetItem, using the current iteration number. Theoretically, this would let the int main loop return the corresponding Node from LinkList.tem. From there, I call the category from the object inside that Node's data (which currently works), which would be compared with tmpCategory. If there's a match, the loop will print out the entire Node's data object.
tmpCategory = "Business";
for(int i = 0; i < myCategorizedContact.GetUsed(); i++)
{
if(myCategorizedContact.GetItem(i).getCategory() == tmpCategory)
cout << myCategorizedContact.GetItem(i);
}
The problem is that the currently setup (while it does run), it returns nothing at all. Upon further testing ( cout << myCategorizedContact.GetItem(i).getCategory() ), I found that it's just printing out the category of the first Node over and over again. I want the overall scheme to evaluate for every Node and print out matching data, not just spit out the same Node.
Any ideas/suggestions are greatly appreciated.
Please look at this very carefully:
template <class Type>
Type LinkList<Type>::GetItem(int itemNumber) const
{
Node<Type>* cursor = NULL;
// loop over all items in the linked list
for(cursor = first;
cursor != NULL;
cursor = (cursor -> next))
{
// for each item in the linked list, run a for-loop
// counter from 0 to (used-1).
for(int i = 0; i < used; i++)
{
// if the passed in itemNumber matches 'i' anytime
// before we reach the end of the for-loop, return
// whatever the current cursor is.
if(itemNumber == i)
{
return(cursor -> data);
}
}
}
}
You're not walking the cursor down the list itemNumber times. The very first item cursor references will kick off the inner-for-loop. The moment that loop index reaches itemNumber you return. You never advance your cursor if the linked list has at least itemNumber items in the list.. In fact, the two of them (cursor and itemNumber) are entirely unrelated in your implementation of this function. And to really add irony, since used and cursor are entirely unrelated, if used is ever less than itemNumber, it will ALWAYS be so, since used doesn't change when cursor advances through the outer loop. Thus cursor eventually becomes NULL and the results of this function are undefined (no return value). In summary, as written you will always either return the first item (if itemNumber < used), or undefined behavior since you have no return value.
I believe you need something like the following instead:
template< class Type >
Type LinkList<Type>::GetItem(int itemNumber) const
{
const Node<Type>* cursor = first;
while (cursor && itemNumber-- > 0)
cursor = cursor->next;
if (cursor)
return cursor->data;
// note: this is here because you're definition is to return
// an item COPY. This case would be better off returning a
// `const Type*` instead, which would at least allow you to
// communicate to the caller that there was no item at the
// proposed index (because the list is undersized) and return
// NULL, which the caller could check.
return Type();
}

Pointer comparision issue

I'm having a problem with a pointer and can't get around it..
In a HashTable implementation, I have a list of ordered nodes in each bucket.The problem I have It's in the insert function, in the comparision to see if the next node is greater than the current node(in order to inserted in that position if it is) and keep the order.
You might find this hash implementation strange, but I need to be able to do tons of lookups(but sometimes also very few) and count the number of repetitions if It's already inserted (so I need fasts lookups, thus the Hash , I've thought about self-balanced trees as AVL or R-B trees, but I don't know them so I went with the solution I knew how to implement...are they faster for this type of problem?),but I also need to retrieve them by order when I've finished.
Before I had a simple list and I'd retrieve the array, then do a QuickSort, but I think I might be able to improve things by keeping the lists ordered.
What I have to map It's a 27 bit unsigned int(most exactly 3 9 bits numbers, but I convert them to a 27 bit number doing (Sr << 18 | Sg << 9 | Sb) making at the same time their value the hash_value. If you know a good function to map that 27 bit int to an 12-13-14 bit table let me know, I currently just do the typical mod prime solution.
This is my hash_node struct:
class hash_node {
public:
unsigned int hash_value;
int repetitions;
hash_node *next;
hash_node( unsigned int hash_val,
hash_node *nxt);
~hash_node();
};
And this is the source of the problem
void hash_table::insert(unsigned int hash_value) {
unsigned int p = hash_value % tableSize;
if (table[p]!=0) { //The bucket has some elements already
hash_node *pred; //node to keep the last valid position on the list
for (hash_node *aux=table[p]; aux!=0; aux=aux->next) {
pred = aux; //last valid position
if (aux->hash_value == hash_value ) {
//It's already inserted, so we increment it repetition counter
aux->repetitions++;
} else if (hash_value < (aux->next->hash_value) ) { //The problem
//If the next one is greater than the one to insert, we
//create a node in the middle of both.
aux->next = new hash_node(hash_value,aux->next);
colisions++;
numElem++;
}
}//We have arrive to the end od the list without luck, so we insert it after
//the last valid position
ant->next = new hash_node(hash_value,0);
colisions++;
numElem++;
}else { //bucket it's empty, insert it right away.
table[p] = new hash_node(hash_value, 0);
numElem++;
}
}
This is what gdb shows:
Program received signal SIGSEGV, Segmentation fault.
0x08050b4b in hash_table::insert (this=0x806a310, hash_value=3163181) at ht.cc:132
132 } else if (hash_value < (aux->next->hash_value) ) {
Which effectively indicates I'm comparing a memory adress with a value, right?
Hope It was clear. Thanks again!
aux->next->hash_value
There's no check whether "next" is NULL.
aux->next might be NULL at that point? I can't see where you have checked whether aux->next is NULL.

C++ - Single Linked List - Ideas

I want to write a method to remove consecutive items with duplicate data values from a singly linked list. The method should return the number of items removed. The method should clean up memory as required, and should assume that memory was allocated using new.
For example, passing in the list
->a->b->c->c->a->b->b->b->a->null
should result in
->a->b->c->a->b->a->null
and return 3
The list item definition and function declaration are given below
struct litem {
char data;
litem* next;
};
int remove_consecutive_duplicates( litem*& list );
I have a simple logic to check the next element recursively & removing the element if its duplicate.
But, i would like to know how many efficient ways to do this ? All ideas welcome from C++ gurus..
You can use std::list, and before pushing element on it you must check:
if ((*l.rbegin()) == next)
{
return;
}
l.push_back(next);
in meta language:
item = items.first
while (item != null) {
while (item.next != null && item.value = item.next.value) {
temp = item.next
item.next = item.next.next
temp.dispose
}
item = item.next
}
As far as I can see, there's not a lot to optimize here. Returning the number of items used is just a case of incrementing a counter. Basically, if you find that litem->data == litem->next->data, then you need to do the removal like so:
litem* tmpItem = currentItem->next;
currentItem->next = tmpItem->next;
delete tmpItem;
Keep iterating until currentItem->next == NULL, to avoid referencing beyond the end of the list.