In main function, we have a vector lists of string values.
vector names;
after my input ~~~
Then I will have
names[0] = ~, names[1] = ~
right?
Then How would I put those vector values into nodes of which we have
class LinkedList
{
public: class Nodes {
public:
void ToNodeValue(const string& e) { elem = e; }
Nodes(const string& e) { elem = e; }
private:
string element;
Nodes* prev;
Nodes* next;
};
private:
Nodes* header;
Nodes* tail;
};
And I am trying to place those list of vector values to elements
so that I can form a list with nodes in which each has its own string element value
The general algorithm for the main function part of the task would be to simply use a for loop to access every value in the vector and to call an insert function on a LinkedList object.
such as
LinkedList myList;
for(int x = 0; x < vec.size(); x++) {
myList.insert(vec[x]);
}
What the actual insert function does will depend on what the problem description requires.
If you just need to tack it onto the end, then the pseduocode would be something like
make new node on heap with val from parameter
set tail->next to be this newNode
set newNode->prev to be tail
set newNode->next to be NULL
set tail to be newNode
Related
I have to face this problem: I have a doubly linked list and I have to make insertion at the tail. My list is made of Nodes such as
struct Node {
int val; // contains the value
Node * next; // pointer to the next element in the list
Node * prev; // pointer to the previous element in the list
};
and my class list declares only
private:
Node * first; // Pointer to the first (if any) element in the list
at first.
Now, I wrote such a method for inserting:
void List::insert(int n){
Node * tmp = new Node;
tmp->val = n;
tmp->next = 0;
if (!first) {
first = tmp;
}
else {
Node * p = new Node;
p = first;
while (p->next) {
p = p->next;
}
p->next = tmp;
tmp->prev = p;
}
};
and if I take several numbers from cin (say, 1 2 3 4), I call insert but I end up not having all the elements I wanted to store. I have only first and tmp, which contains the last number from the input (e.g. 4).
I struggle to figure out what's wrong - my first suggestion is variable scope.
Or is there anything wrong during the pointer setting?
OBS: I'd use a tail pointer of course, but the aim is traversing the list.
Any feedback is really appreciated.
I am trying to figure out how to sort a doubly linked list in ascending order but can't wrap my head around it. For my header, I have the follow with select_sort being the function that sorts it.
#ifndef INTLIST_H
#define INTLIST_H
struct IntNode{
int data;
IntNode *next;
IntNode(int data) : data(data), next(0) {}
};
class IntList{
private:
IntNode *head;
IntNode *tail;
public:
void select_sort();
Edit:
My horrible function
void IntList::select_sort(){
for(IntNode *holder = head; holder != NULL; holder = holder -> next){
IntNode *temp2 = holder;
for(IntNode *temp = holder -> next; temp!=NULL;temp = temp->next){
if(temp2 -> data > temp -> data){
temp2 = temp;
}
}
int holder2 = tail -> data;
tail -> data = temp2 -> data;
temp2 -> data = holder2;
}
}
Selection sort basically finds the smallest element in the remainder of the list and swaps it with the end of the sorted list, conceptually moving from left to right until you reach the end of the list. After the first pass of the outer loop, the first element of the list has the lowest value. Wikipedia has some excellent animations of selection sort in action.
You need a pointer to track the node with the lowest value starting at holder.
IntNode *min = holder;
Then if the current node, temp, is less than min, update min to point to temp. After the inner for loop you just need to swap min and holder if they aren't the same so the smallest element in the remainder of the list is now at the end of the sorted list.
I am kind of new to c++ and got headache with this pointer and stuff!
I need to iterate through list of struct which is linked list, read the data of struct and pop that entry!
this my struct :
struct node {
map<string,double> candidates;
double pathCost;
string source;
node *next; // the reference to the next node
};
by reading this post I create my list like :
list<node*> nodeKeeper;
and then initialized the first value:
node *head;
head= new node;
head->pathCost = 0.0;
head->source="head";
head->next = NULL;
thin fill the list and struct :
for(unsigned int i = 0; i < sourceSentence.size(); i++){
node *newNode= new node; //create a temporary node
//DO STUFF HERE
//push currunt node to stack
nodeKeeper.push_back(newNode);
head = newNode;
}
now I have list of struct and I want to iterate through it and pop the elements:
for (list<node*>::const_iterator it=nodeKeeper.begin();it!=nodeKeeper.end();it++){
it->pop_front();
}
which gives me this error:
error: request for member 'pop_front' in '*
it.std::_List_const_iterator<_Tp>::operator->()', which is of
pointer type 'node* const' (maybe you meant to use '->' ?) make: ***
[main3.o] Error 1
It looks like that my iterator points inside the list , not the list itself!
Can you tell me what is wrong here?!
If your goal is to have a single list of your node struct, there is no need to manage next pointers your self. Inserting would stay the same (minus the head = line)
To pop all element of the list you would do something like
int sizeOfList = nodeKeeper.size();
for( int i =0; i < sizeOfList; i++) {
//if you want to do something with the last element
node * temp = nodeKeeper.back();
//do stuff with that node
//done with the node free the memory
delete temp;
nodeKeeper.pop_back();
}
Compiling/running example here: http://ideone.com/p6UlyN
If all you need to do is remove the elements, use std::list::clear:
nodeKeeper.clear();
To read the contents of the element, then remove, try this:
for (std::list<node*>::const_iterator it = nodeKeeper.begin(); it != nodeKeeper.end(); ++it) {
std::cout << (*it)->source;
// do more reading
nodeKeeper.pop_front();
}
or with C++11:
for (const auto& a : nodeKeeper) {
std::cout << a->source;
nodeKeeper.pop_front();
}
I'm making a C++ Maze program using disjoint sets and the Union/Find operations.
I have a MakeSet(int x) function which creates a new Node for every integer element x in the maze. (i.e 1 to 16 for a 4x4 maze). Thus initially every element is in its own set.
My MakeSet looks like this
void Maze::MakeSet(int x)
{
Node *root = new Node;
root->label = x;
root->parent = NULL;
}
But in the CreateMaze() function I have to call MakeSet many times to get all the elements into their own set initially. Thus, the root will keep being overwritten. How do I dynamically allocate many different nodes? Should I keep them separated in an array?
You already allocate a new Node, you are just not keeping it. You need to change the function to return Node*, and store the results in an array or a vector.
Node* Maze::MakeSet(int x) {
Node *root = new Node;
root->label = x;
root->parent = NULL;
return root;
}
Node *nodes[16];
for (int i = 0 ; i != 16 ; i++) {
nodes[i] = Maze::MakeSet(i);
}
An even better approach would be to do Node initialization in a constructor:
Node::Node(int x) : label(x), parent(NULL) {
}
You can now create all sets in a loop, and store pointers to them in an array:
Node *nodes[16];
for (int i = 0 ; i != 16 ; i++) {
nodes[i] = new Node(i);
}
You can have a std::vector of Node objects or pointers as a class member:
class Maze
{
std::vector<Node> nodes;
};
or, if you must
class Maze
{
std::vector<Node*> nodes;
}
and add the created nodes:
void Maze::MakeSet(int x)
{
Node *root = new Node;
root->label = x;
root->parent = NULL;
nodes.push_back(root);
}
Note that you'll have to implement a destructor to clean up the memory when you're done. This also means you should have a copy constructor and assignment operator for Maze.
I am trying to implement a linked list for a data structures class and I am having some difficulty with the searching portion of the algorithm.
Below is the offending code, which I have tried to implement following the pseudo-code in the MIT introduction to algorithms text:
//
// Method searches and retrieves a specified node from the list
//
Node* List::getNode(unsigned position)
{
Node* current = m_listHead;
for(unsigned i = m_listSize-1; (current != 0) && (i != position); --i)
current = current->next;
return current;
}
The head at this point in the program is the 4th node, which contains the value of int 5. the problem appears to be in the body of the for-loop, where the pointer to the node object is assigned to the next node. But this is going beyond the head of the node, so it is essentially pointing at some random location in memory (this makes sense).
Shouldn't the algorithm be moving to the previous Node instead of the next Node in this case? Below is the pseudo-code:
LIST-SEARCH(L, k)
x <- head
while x != NIL and key != k
do x <- next[x]
return x
Also, here is the header file for my Linked list implementation. I haven't tried to implement it in Template form yet just to keep things simple:
#ifndef linkList_H
#define linkList_h
//
// Create an object to represent a Node in the linked list object
// (For now, the objects to be put in the list will be integers)
//
struct Node
{
// nodes of list will be integers
int number;
// pointer to the next node in the linked list
Node* next;
};
//
// Create an object to keep track of all parts in the list
//
class List
{
public:
// Contstructor intializes all member data
List() : m_listSize(0), m_listHead(0) {}
// methods to return size of list and list head
Node* getListHead() const { return m_listHead; }
unsigned getListSize() const { return m_listSize; }
// method for adding a new node to the linked list,
// retrieving and deleting a specified node in the list
void addNode(Node* newNode);
Node* getNode(unsigned position);
private:
// member data consists of an unsigned integer representing
// the list size and a pointer to a Node object representing head
Node* m_listHead;
unsigned m_listSize;
};
#endif
Implementation of addNode method:
//
// Method adds a new node to the linked list
//
void List::addNode(Node* newNode)
{
Node* theNode = new Node;
theNode = newNode;
theNode->next;
m_listHead = theNode;
++m_listSize;
}
Try this to construct the list:
void List::addNode(int number)
{
newNode = new Node;
newNode -> number = number;
newNode -> next = m_listHead ;
m_listHead = newNode;
++m_listSize;
}
It will add nodes to the head. Perhaps you may wish to store the pointer to the tail and insert the nodes there.
Unfortunately your code doesn't resemble the pseudo code you supply.
The pseudo-code is for searching a linked-list for a key, not a position.
The pseudo code reads as:
Assign head to (node) x.
while x isn't null and the key inside the current node (x) doesn't match k
assign x->next to x
return x
The returned value is either a pointer to the node that contains k or null
If you're trying to find the node at a given position your loop would be (note this is assuming you're going to use a zero-based index for accessing the list):
Assign head to (node) x
assign 0 to (int) pos
while x isn't null and pos not equal to given position
assign x->next to x
increment pos
return x
The result will either be a pointer to the node at the given position or null (if you hit the end of the list first)
Edit: Your code is very close to the latter if that's what you're trying to do ... can you see the difference?
Edit because I like homework where the OP asks the right questions :)
Node* List::getNodeContaining(int searchValue)
{
Node* current = m_listHead;
while (current != 0 && current->number != searchValue)
{
current = current->next;
}
return current;
}
Node* List::getNodeAtPos(int position)
{
Node* current = m_listHead;
int pos = 0;
while (current != 0 && pos != position)
{
current = current->next;
pos++;
}
return current;
}
You list is very different from what a normal list ADT looks like. Rather than returning nodes, which would require the client know about the list implementation, you return and accept the type you're making a list of.
In this case you're making a list of integers, sou you'd want
public:
void add(int num); //prepends an Item to the list
int get(int pos);
The implementations of both are simple. Add makes a new node, and links it in;
void List::add(int num)
{
Node *newNode = new Node;
newNode->number = num;
newNode->next = m_listHead;
m_listHead = newNode;
m_listSize++;
}
Then get is easy too:
int List::get(int pos)
{
if(pos>m_listSize)
;//throw an error somehow
Node *tmp = m_listHead;
while(pos-->0)
tmp=tmp->next;
return m->number
}