what is wrong with this reverse linklist code? - list

var reverseList = function(head) {
function reverse(cur,pre){
if(!cur) return pre
next = cur.next
cur.next = pre
return reverse(next,head)
}
return reverse(head.next,head)
}
I tried a recursion way to write this,
this code output is not correct running, whats wrong with this code?

This is what i think:
If we go by your logic for let's say this case (1->2->3->null), then end result is - first node has address of second node in its 'next' & second node has address of first in its 'next'. So, a loop is formed (1->2 and 2->1). If you want to print such a list, it'll end up in an infinite loop kind of situation in an online platform.
As Thomas Mailund has correctly pointed out, null list case also needs to be covered.
I'd also suggest you to keep your variable names distinct from each other to avoid confusion.
(e.g. you used 'next' as variable name in your inner function which is used already for linked list).
Taking these factors into consideration, here's the rectified working version of your code:
var reverseList = function(head) {
var r = null;
function reverse(p, q) {
q.next = r;
r = q;
if (p == null) return q;
return reverse(p.next, p);
}
return (!head) ? head : reverse(head.next,head)
}

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);
}

If/Else statement returns

This section of code keeps throwing an error, "not all control paths return a value". I'm not entirely sure how to rewrite this so that I can fix the error. Other than the returns, this is what I need this section of code to do. Should I create a new variable that I declare within the if/else statement and then have the return for that variable right before the ending bracket?
node * LList::search(int srchKey)
{
node * p = head;
while (p != NULL)
{
if (p->key == srchKey)
{
return p;
}
else
{
return NULL;
}
p = p->next;
}
}
If head is NULL, search() will exit without reaching any return statement. The return value will be indeterminate. That is what the compiler is complaining about.
If head is not NULL, search() will check only the first node and then return a value, it will not search the whole list. Because of that, the return NULL; statement should not be inside the loop at all. It will exit search() as soon as it encounters an element that doesn't match, rather than continuing to the next element in the list.
This is similar to the problem I describe in Searching array reports "not found" even though it's found.
You should wait until the loop ends before doing return NULL;. If you get there, it means the item being searched for really wasn't found.
node * LList::search(int srchKey)
{
node * p = head;
while (p != NULL)
{
if (p->key == srchKey)
{
return p;
}
p = p->next;
}
return NULL;
}
You need another return statement after the while loop. One possible code path is that the program never enters the while loop. A simple
return NULL;
should fix it.
EDIT: Also, your loop will only ever make one pass through. I would remove the (if p == NULL) block; it is useless. I see your intent, but the way to implement it is how I described above.
when while condition is false, then you do not have return.
Add a return outside while in case you do not enter the loop.
Moreover, p = p->next; will never be executed because you exit the loop before reaching it because of if-else.
Regarding the logic, It seems to me that you do not need the else part at all. try to omit it and place return NULL before the end of the routine.

Deleting elements from doubly bounded pointer list

I am working on a project where I create a double bounded pointer list, delete several elements, and still be able to read off the list. I have a double bounded pointer list, but am having trouble deleting elements and keeping the list double bounded. This then causes issues when trying to print the list.
Below is the IF statement I've placed in a while loop to help delete unwanted elements. I keep getting a segmentation fault (core dumped).
if ((black2 != black)||(white2 != white)) {
dump = help;
help = help ->next;
dump -> before = temp;
temp -> next = help;
help ->before = temp;
delete dump;
}//if
else { temp = help;
help = help->next;
help ->before = temp; }//else
To maintain properly the doubly linked list you should do something like :
void remove(X *elt) {
X* before = elt->before;
X* after = elt->next;
if (before != NULL) { // assuming first element points to NULL
before->next = after;
}
else {
first = after; // assuming first is a pointer to first element of list
}
if (after != NULL) { // assuming last element points to NULL
after->before = before;
}
else {
last = before; // assuming last is a pointer to last element
}
delete elt;
}
That way, you ensure that elements around current correctly point to each other dealing with special cases of removing first or last element.
But you already have a std::list template in Standard Template Library
One logical issue in your code is the line dump->before = temp.
What this does is that it sets the previous node pointer of dump to temp, as opposed to defining temp as the previous node.
The correct line should read temp = dump->before
PS: Your code is correct assuming that the node you are deleting isn't the first or last node (and you haven't padded with dummy nodes). You should introduce checks for these cases if required.

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.

BST insert in C++

I'm learning C++ and writing a binary search tree. The following is the code I wrote for my insert method.
BSTNode * BST::Insert(const std::string & v) {
BSTNode *n = !root ? root = new BSTNode(v) : Insert_Helper(v,root);
if(n) size++;
return n;
}
BSTNode * BST::Insert_Helper(const std::string & v, BSTNode *n) {
if(!n->value.compare(v))
return NULL; // already have v
else if(n->value.compare(v) > 0) // v goes to the left
if(n->left) return Insert_Helper(v,n->left);
else return n->left = new BSTNode(v);
else // v goes to the right
if(n->right) Insert_Helper(v,n->right);
else return n->right = new BSTNode(v);
}
The bug I'm getting goes like this: It all works fine and dandy, until I try to insert a duplicate node. It doesn't add a new node, yet it increments count.
By observing in GDB, I've found that when I try to add a string that I already have, Insert_Helper works correctly and returns NULL. This value however (on my machine) is something like 0x6, which is out of bounds of course, but not 0x0 like I thought it would be. I think this causes an issue at the point where I have the if(n) statement. In this case n evaluates to true, and so increments size one more than it should.
Furthermore, at this point in my program, the nodes continue to get added correctly, but my insert function continues to return 0x6 as the address, even though they really are in valid locations in memory that I can access.
Can anyone give me any pointers as to what I might be doing wrong?
Your compiler probably should have spotted this, but this line near the end of your helper:
if(n->right) Insert_Helper(v,n->right);
You probably should return whatever Insert_Helper returns:
if(n->right) return Insert_Helper(v,n->right);
You can change if(n) size++ to if (n != NULL) size++