#include<stdlib.h>
#include<stdio.h>
#include<iostream>
struct node {
int data;
node* next;
node* prev;
};
node *sentinel;
int numItem;
void pushBack(int new_data){
sentinel = new node();
while( (sentinel->next)!= NULL)
{
sentinel = sentinel->next;
}
node *toAdd = new node();
toAdd->data = new_data;
sentinel->next = toAdd;
toAdd->next = NULL;
numItem++;
}
void print(){
}
int main(){
pushBack(1);
pushBack(2);
pushBack(3);
pushBack(4);
pushBack(5);
print();
return 0;
}
I am implementing a pushBack() method which is to add items to the end of the linkedlist.
How to implement print() method in order to print out elements in linkedList?
My problem is I don't know how to start at the first index of linkedList.
Your problem is actually a lot deeper than just your print() function: your push_back() doesn't work the way you want it to work as far as I can tell! I strongly recommend you take a piece of paper and draw your list structure with the individual elements. Initially, you'd have an empty list:
=========
| head -+-->nil
=========
When inserting one element, you need to arrive at this structure, instead:
========= ===========
| head -+------>| data=1 |
========= | next --+-->nil
nil<-+- prev |
===========
Doing so only requires to create a new node and modify the head. Adding more nodes is a bit more interesting as you either need to also remember the last node or you need to walk the list to add something to its end. The picture after adding three nodes with data 1, 2, and 3 in this order should look something like this:
========= =========== =========== ===========
| head -+------>| data=1 |<-\/-->| data=2 |<-\/-->| data=3 |
========= | next --+--/\ | next --+--/\ | next --+->nil
nil<-+- prev | \--+- prev | \--+- prev |
=========== =========== ===========
Coding this up is, obviously, done in push_back() but your current push_back() wouldn't yield this structure. Once you have this structure, you'd just start your print() with the head and print the respective data fields.
Related
I was going through a tutorial on Linked Lists in C++. I found the following code for the implementation for inserting an element in the Linked List:
/* Given a reference (pointer to pointer) to the head
of a list and an int, appends a new node at the end */
void append(Node** head_ref, int new_data)
{
/* 1. allocate node */
Node* new_node = new Node();
Node *last = *head_ref; /* used in step 5*/
/* 2. put in the data */
new_node->data = new_data;
/* 3. This new node is going to be
the last node, so make next of
it as NULL*/
new_node->next = NULL;
/* 4. If the Linked List is empty,
then make the new node as head */
if (*head_ref == NULL)
{
*head_ref = new_node;
return;
}
/* 5. Else traverse till the last node */
while (last->next != NULL)
last = last->next;
/* 6. Change the next of last node */
last->next = new_node;
return;
}
In step 1, we are declaring a pointer with name new_node and it is pointing to a dynamically created block.
What I couldn't understand is that, if the function is called 4 times then how can a new pointer variable with the same name be created on each call? Since we are using dynamic memory allocation, therefore it won't be dumped when we return from function.
So, how is this piece of code working?
Variable names don't exist at runtime, only at compile-time.
The new_node variable represents a chunk of memory that is local to the append() function. Each time append() is called, a new memory chunk is created when it enters scope, and that chunk is released when it goes out of scope.
Each call to new allocates a new block of dynamic memory. In this case, the memory address of that block is being stored inside that local memory chunk that new_node represents.
append()
+----------------+
| new_node |
| +------------+ | +-------------+
| | 0xABCDABCD |-|------| Node object |
| +------------+ | +-------------+
+----------------+
I am getting a segmentation fault in my Separate Chaining Hash Table object.
bool hashTable::addNode(int id, string information){
bool inserted = false;
int position = hash(id);
cout << &hashtable[position]<<endl;
if(hashtable[position]==NULL){
hashtable[position]->data.id = id;
hashtable[position]->data.information = information;
hashtable[position]->next = NULL;
inserted = true;
} else {
Node* current = new Node;
current = hashtable[position];
while(current!=NULL){
if(id < hashtable[position]->data.id){
current->data.id = id;
current->data.information = information;
current->next = hashtable[position];
hashtable[position] = current;
inserted = true;
} else if(id < current->data.id){
current->data.id = id;
current->data.information = information;
current->next = hashtable[position]->next;
hashtable[position]->next = current;
inserted = true;
} else if(current->next==NULL){
Node *temp;
temp->next = NULL;
temp->data.id = id;
temp->data.information = information;
current->next = temp;
inserted = true;
}
current = current->next;
}
}
return inserted;
}
Essentially, I have an array of head pointers to handle the separate chaining, but the segmentation fault in addNode is messing me up. To be clear, I am calling a public AddEntry first which calls the AddNode for each individual LinkedList in the array.
#ifndef HASH_H
#define HASH_H
#include <iostream>
#include <string>
#include "data.h"
using std::string;
using std::cout;
using std::endl;
#define SIZE 15
class hashTable{
public:
hashTable();
~hashTable();
bool addEntry(int id, string information);
string getEntry(int id);
bool removeEntry(int id);
int getCount();
void displayTable();
private:
bool removeNode(int id, int position);
bool addNode(int id, string information);
int count = 0;
Node* hashtable = new Node[SIZE]; //array of head pointers
int hash(int id);
};
#endif
Sorry if I didn't word this the best this is my first time on Stack Overflow.
There are a few spots in your code where it looks like you're using the address-of operator & incorrectly. Let's start with this one:
if (&hashtable[position] == NULL) {
...
}
I completely see what you're trying to do here - you're trying to say "if the slot at index position holds a null pointer." However, that's not what this code actually does. This says "if the location in memory where hashtable[position] exists is itself a null pointer." That's not possible - hashtable[position] refers to a slot in an array - so this if statement never fires.
It might be helpful to draw pictures here to get a better sense of what's going on. For example, suppose you have an empty hash table, as shown here:
+-------+ +------+------+------+------+ +------+
| |------>| null | null | null | null | ... | null |
+-------+ +------+------+------+------+ +------+
hashtable
Here, hashtable[position] refers to the pointer at index position in the array pointed at by hashtable. With an empty hash table, hashtable[position] will evaluate to NULL because that's the contents of the pointer at that slot. On the other hand, &hashtable[position] refers to something like this:
&hashtable[position]
+-------+
| |
+-------+
|
v
+-------+ +------+------+------+------+ +------+
| |------>| null | null | null | null | ... | null |
+-------+ +------+------+------+------+ +------+
hashtable
Here, &hashtable[position] points to one of the pointers in the array. And while the pointer &hashtable[position] is pointing at something that is a null pointer, it itself is not a null pointer, since it's pointing to a valid object in memory.
Changing the code to read
if (hashtable[position] == NULL) {
...
}
correctly expresses the idea of "if the entry at index position within the hashtable array isn't a null pointer."
There are similar errors in your code at a few other points. Read over what you have with an eye toward the following question: do I want the pointer stored in the array at some index, or do I want the location in memory where that pointer happens to live?
I've been doing this as an exercise on my own to get better at C++ (messing around with a linked list I wrote). What I want to do is to reverse the list by twisting the pointers around, rather than just 'printing' the data out in reverse (which is relatively straightforward).
I have an array of pointers-to-pointers, each pointing to a node in a linked list. But this is less a question about linked-list dynamics (which I understand), and more about pointer magick.
A node looks like this,
template<class T>
struct node {
T data;
node *next;
node(T value) : data(value), next(nullptr) {}
};
And the code in question,
node<T> **reverseArr[listLength];
node<T> *parser = root;
for (auto i : reverseArr) {
i = &parser;
parser = parser->next;
}
root = *(reverseArr[listLength - 1]);
for (int ppi = listLength - 1; ppi >= 0; --ppi) {
if (ppi == 0) {
(*reverseArr[ppi])->next = nullptr;
//std::cout << "ppi is zero!" << "\t";
}
else {
(*reverseArr[ppi])->next = (*reverseArr[ppi - 1]);
//std::cout << "ppi, 'tis not zero!" << "\t";
}
}
My logic:
The new root is the last element of the list,
Iterate through the array in reverse,
Set the current node's next pointer to the previous one by setting the current node's nextNode to the next node in the loop.
What's happening:
If I leave the debug print statements commented, nothing. The function's called but the linked list remains unchanged (not reversed)
If I uncomment the debug prints, the program seg-faults (which doesn't make a whole lot of sense to me but seems to indicate a flaw in my code)
I suspect there's something I'm missing that a fresh pair of eyes might catch. Am I, perhaps, mishandling the array (not accounting for the decay to a pointer or something)?
You're overthinking the problem. The correct way to reverse a single-linked list is much simpler than you think, and does not involve arrays at all.
All you need to do is walk through the list setting each node's next pointer to the head of the list, then set the head of the list to that node. Essentially, you are unlinking each node and inserting it at the start of the list. Once you reach the end, your list is reversed.
It just requires a bit of care, because the order that you do things is important. Something like this should do it:
template <class T>
node<T> * reverse( node<T> * head )
{
node<T> *current = head;
head = NULL;
while( current != NULL )
{
// store remainder of list
node<T> *remain = current->next;
// re-link current node at the head
current->next = head;
head = current;
// continue iterating remainder of list
current = remain;
}
return head;
}
The operation has a linear time complexity. You would invoke it by passing your list's head node as follows:
root = reverse( root );
It should go without saying that it would be a bad idea to call this function with any node that is not the head of a list, or to pass in a list that contains cycles.
So I have a pretty good understanding of iterating through a linked list, and also obtaining the next node in the list. Now I trying to go in the other direction, but I soon realized its not as easy as it appears. Unlike an array where you can iterate forwards and backwards. I seem to be stumped.
So If I have a list of 1 -> 2 -> 3 -> 4 -> NULL How would I go about obtaining the address of node 2 given the location of node 3?
I started messing around with this code below which returns all items up to node 3. I just don't see how I can get that previous node? By the way searchList() returns the address of a node if you give it the node->data value. Using the list above searchList(3) returns the address of the node which has 3 as its data member.
struct node {
int data;
node* next;
};
void llclass::getPrevious() {
node *stop = searchList(nodeItem),
*start = head;
while (start != stop) {
cout << start->data << endl;
start = start->next;
}
}
With a singly-linked list like yours, it is not possible to obtain the address of node 2 if you're given only the address of node 3. You would have to start at the head node and iterate forward until reaching 3, keeping track of the previous node (2 in this case). Alternately, you could use a doubly-linked list that includes a "node *previous;" member.
Sounds like you want to get the previous node of a node whose value is given as input to you. This should do that for you:
node* llclass::getPrevious(int item)
{
node* previous = NULL;
node* current = head;
while(current)
{
if (current->data == item)
{
return previous;
}
else
{
previous = current;
current = current->next;
}
}
return NULL;
}
I'm trying to sort a linked-list. I have a Node called head and it's pointing to the next node, etc.
But when I try to sort the Nodes by the value they carry, I get the sort working because I see it printing out the stuff in the if-statement, but I'm not getting back the linked-list. Where did I go wrong?
Node* head;
void sortlist(){
Node * runner = head;
Node * runner2;
for(runner = head; runner->next != NULL; runner = runner->next){
for(runner2 = runner->next; runner2->next != NULL; runner2 = runner2->next){
if(runner->freq < runner2->freq){
cout<< runner->freq<< " is LT "<<runner2->freq<< endl;
Node * temp = runner;
runner = runner2;
runner2 = temp;
}
}
}
head = runner;
}
I'm only getting back the first Node.
In order to swap two elements in a linked list, consider what you need to change. For example, to get from
Head -> First -> Second -> (NULL)
to
Head -> Second -> First -> (NULL)
you need to update: Head.next, First.next and Second.next. You don't change any of those things when trying to swap nodes, so it can't possibly do what you expect.
Just swapping the values (ie, swap(runner->freq, runner2->freq)) would be much simpler.
you will stop when runner->next == NULL;, which is supposed to be the last element. And then you set head = runner;, which means the head will always be the last element after this routine. Furthermore, I do not trust this swapping.
It seems you vaguely want to do an insertion sort. If you want to do a simple sorting on linked lists, I suggest you to use selection sort: You create another empty list l2, and each time you remove the minimum element from your first list, and add it as the head of l2. The code for the second list is simple:
void prepend(Node* node, Node** list){
//null checks if you want
node->next = *list;
*list=node->next;
}