This is my first go at building a graph and i've decide to use a LL to connect my vectors (or nodes or elements, whatever they're called) and each one of my nodes has a vector that holds pointers to nodes. I've created a "addEdge" function in my graph class but it seems to be breaking my program. My addElement class seems to be working fine, as it will add and print them out perfectly. But when I try to add an edge, it breaks. I went through the debugger and it breaks at
while(curr->next != NULL || curr->val != n)
Any ideas why?
#include "element.h"
#include "vector"
#include "iostream"
#include "functional"
using namespace std;
class Graph
{
public:
element *head;
Graph(int V)
{
head = NULL;
vector <element*> nodes;
}
void addElement(int val)
{
if (head == NULL)
{
element *newelement = new element(NULL, NULL, val);
head = newelement;
return ;
}
element *newelement = new element(NULL,NULL, val);
element *curr = head;
while(curr->next != NULL)
{
curr = curr->next;
}
curr->next = newelement;
newelement->prev = curr;
return;
}
void addEdge(int n, int edge)
{
element *e = head;
element *curr = head;
if(curr = NULL)
{
cout<<"There are no elements in your graph to connect";
return;
}
while(e->next != NULL || e->val != edge)
{
cout<<"Looking";
e = e->next;
}
if(e->val != edge)
{
cout<<"Your edge node doesn't exist";
return;
}
while(curr->next != NULL || curr->val != n)
{
cout<<"Looking for main node";
curr = curr->next;
}
if(curr->val != n)
{
cout<<"Could not find the main node";
return;
}
curr->edges.push_back(e);
cout<<"Edge connected";
return;
}
node class
#include "vector"
#include "iostream"
#include "functional"
using namespace std;
class element {
public:
element(element* n = NULL, element *p = NULL, int num = NULL)
{
val = num;
next = n;
prev = p;
}
int val;
element *prev;
element *next;
vector<element*> edges;
};
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed yesterday.
Improve this question
I am trying to make a quicksort algorithm for singly-linked lists. I, however, must be somehow creating a cyclical list in the process. In the concatenate function, the while loop gets stuck printing out 2 and 22 continuously. So, I assume that I must somehow be creating a list where Node 2 points to Node 22 and vice versa. Unfortunately, I have no idea how, since I feel like I have added nullptr to the end of every list where it would matter. I have reviewed my partition function so many times I add more bugs than I fix. Is there something I am missing with how linked lists work?
I have been stuck on this for a while so any help would be greatly appreciated.
Here is my quicksort code.
// quick.cpp
#include "volsort.h"
#include <iostream>
#include <string>
using namespace std;
// Prototypes
Node *qsort(Node *head, bool numeric);
void partition(Node *head, Node *pivot, Node *&left, Node *&right, bool numeric);
Node *concatenate(Node *left, Node *right);
// Implementations
void quick_sort(List &l, bool numeric) {
l.head = qsort(l.head, numeric);
}
Node *qsort(Node *head, bool numeric) {
if (head == nullptr || head->next == nullptr) {
return head;
}
Node *l = nullptr;
Node *r = nullptr;
partition(head, head, l, r, numeric);
l = qsort(l, numeric);
r = qsort(r, numeric);
head = concatenate(l, head);
head = concatenate(head, r);
return head;
}
void partition(Node *head, Node *pivot, Node *&left, Node *&right, bool numeric) {
Node *cur = pivot->next;
bool c;
Node *tl=nullptr, *tr=nullptr;
while (cur != pivot && cur != nullptr) {
if (numeric) {
c = node_number_compare(cur, pivot);//compare numeric elements of the Nodes
}
else {
c = node_string_compare(cur, pivot);//compare string elements of the code
}
if (c) {
if (left == nullptr) {
left = cur;
cur = cur->next;
tl = left;
}
else {
tl->next = cur;
cur = cur->next;
tl = tl->next;
tl->next = nullptr;
}
}
else {
if (right == nullptr) {
right = cur;
cur = cur->next;
tr = right;
}
else {
tr->next = cur;
cur = cur->next;
tr = tr->next;
tr->next = nullptr;
}
}
}
}
Node *concatenate(Node *left, Node *right) {
if (right == nullptr && left == nullptr) {
return nullptr;
}
else if (left == nullptr) {
right->next = nullptr;
return right;
}
else if (right == nullptr) {
left->next = nullptr;
return left;
}
Node *t = left;
while (t->next != nullptr) {
cout << t->number << endl;
t = t->next;
}
t->next = right;
while (t->next != nullptr) {
cout << t->number << endl;
t = t->next;
}
t->next = nullptr;
return left;
}
Input:
45
4
9
22
2
Here's the list class functions if it helps.
#include "volsort.h"
#include <string>
#include <iostream>
List::List() {
head = NULL;
size = 0;
}
List::~List() {
if (head != NULL) { // follow the links, destroying as we go
Node *p = head;
while (p != NULL) {
Node *next = p->next; // retrieve this node's "next" before destroy it
delete p;
p = next;
}
}
}
bool node_number_compare(const Node *a, const Node *b) {
if (a->number <= b-> number) {
return true;
}
else {
return false;
}
}
bool node_string_compare(const Node *a, const Node *b) {
return a->string <= b->string;
}
void List::push_front(const std::string &s) {
Node *node = new Node();
node->next = NULL;
node->string = s;
node->number = std::stoi(s);
if (head == NULL) {
head = node;
size = 1;
}
else {
Node *p = head;
while (p->next != NULL) {p = p->next;} // go to end of list
p->next = node;
size++;
}
}
void List::dump_node(Node *n) {
while (n->next != NULL) {
std::cout << n->number << " " << n->string << std::endl;
}
}
I have implemented a method to insert a new node before a specific node.
#ifndef FORWARD_SINGLY_LINKED_LIST_H
#define FORWARD_SINGLY_LINKED_LIST_H
#include <cstdlib>
#include <string.h>
#include <iostream>
namespace forward_singly_linked_list {
typedef struct Node {
std::string data;
struct Node *nextPointer;
} Node;
typedef Node *NodeP;
class LinkedList {
private:
int elementsCount;
Node *head;
public:
LinkedList() {
head = NULL;
elementsCount = 0;
}
int get_length() const
{
return elementsCount;
}
// ... ... ...
void add_before(std::string value, std::string before)
{
// empty an area in the memory, and
// save the address of the empty area in 'newNode'
Node *newNode = new Node();
// assign 'value' to the 'data' section of the
// area pointed by 'newNode'
newNode->data = value;
Node * copyOfHead = head;
if (copyOfHead == nullptr)
{
// the list is empty.
// there is no possibility to find 'before'.
// so, return.
return;
}
else
{
bool found = false;
Node * previousNode = nullptr;
while (copyOfHead != nullptr)
{
if (copyOfHead->data == before)
{
found = true;
break;
}
else
{
previousNode = copyOfHead;
copyOfHead = copyOfHead->nextPointer;
}
}
if (!found)
{
return;
}
if (previousNode != nullptr)
{
newNode->nextPointer = previousNode->nextPointer;
previousNode->nextPointer = newNode;
}
else
{
newNode->nextPointer = head;
head = newNode;
}
}
elementsCount++;
}
// ... ... ...
void print() {
Node *copyOfHead = head;
while (copyOfHead != NULL) {
std::cout << copyOfHead->data;
copyOfHead = copyOfHead->nextPointer;
}
std::cout<<"\n\n";
}
public:
static int Test() {
forward_singly_linked_list::LinkedList list;
list.print();
// list.add_at_tail("A");
// list.add_at_tail("B");
// list.add_at_tail("C");
list.print();
list.add_at("-XXX-", 1);
list.print();
return 0;
}
};
}
#endif
Personally, I don't like it because it uses an extra pointer previousNode. I have a feeling that it could be improved.
How can I improve the implementation?
The idea is about link the previous node to input/target node, then link the target/input node to current node.
Here is my code using simple loop index(i) instead of using extra pointer
void Sll::add_at_index( int ind , int value ){
Node *target = new Node( value ) ;
if( ind == 1){
target->next = head ;
head = target ;
}else if( ind == length){
tail->next = target ;
tail = target ;
tail->next = nullptr ;
}else{
Node *curr =head ;
for( int i = 1 ; i < length ; i++ ){
if( i+1 == ind){
Node *Mynext = curr->next ;
curr->next = target ;
target->next = Mynext ;
break ;
}
curr = curr->next ;
}
}
length++ ;
}
Become a two-star programmer:
void add_before(std::string value, std::string_view before) {
auto p = &head;
while (*p && (*p)->data != before)
p = &(*p)->nextPointer;
if (!*p)
return;
*p = new Node {
.data = std::move(value),
.nextPointer = *p,
};
++elementsCount;
}
I implemented a linked list in a class with addToHead, addToTail, deleteFromHead, deleteFromTail, isEmpty, and display functions, and I want to sort the linked list in ascending order in an inherited class, so I made a class TSortedList with two functions; the sortList function that compares the elements of the linked list with each other, and the display() function that display the linked list after sorting it. But when I run the code nothing appear to me, however when I sort it through a function in the parent class, not the inherited class it works, so I do not know where is the problem
#include <iostream>
using namespace std;
class Node {
public:
Node() {
next = 0;
//write your modification here
}
Node(int el, Node *ptr = 0) { //write your modification for the constructor arguments here
info = el;
next = ptr;
}
int info;
Node *next;
//write your modification here
};
class LList {
protected:
Node *head, *tail;
public:
LList() {
head = tail = 0;
}
~LList(){
for (Node *p; !isEmpty(); ) {
p = head->next;
delete head;
head = p;
}
}
int isEmpty() {
return head == 0;
}
virtual void addToHead(int el){
head = new Node(el,head);
if (tail == 0)
tail = head;
}
virtual void addToTail(int el){
if (tail != 0) { // if list not empty;
tail->next = new Node(el);
}
else head = tail = new Node(el);
}
int deleteFromHead(){ // delete the head and return its info;
int el = head->info;
Node *tmp = head;
if (head == tail) // if only one node in the list;
head = tail = 0;
else head = head->next;
delete tmp;
return el;
}
int deleteFromTail(){ // delete the tail and return its info;
int el = tail->info;
if (head == tail) { // if only one node in the list;
delete head;
head = tail = 0;
}
else { // if more than one node in the list,
Node *tmp; // find the predecessor of tail;
for (tmp = head; tmp->next != tail; tmp = tmp->next);
delete tail;
tail = tmp; // the predecessor of tail becomes tail;
tail->next = 0;
}
return el;
}
bool isInList(int el) const{
Node *tmp;
for (tmp = head; tmp != 0 && !(tmp->info == el); tmp = tmp->next);
return tmp != 0;
}
virtual void displayList(){
if (head == 0) // if empty list;
return;
Node *tmp = head;
for (tmp = head; tmp != 0; tmp = tmp->next){
cout<<tmp->info<<endl;
}
}
};
class TSortedList: public LList, public Node
{
protected:
Node *current = head, *index = 0;
int temp;
public:
void sortList() {
if(head == 0) {
return;
}
else {
while(current != 0) {
//Node index will point to node next to current
index = current->next;
while(index != 0) {
//If current node's data is greater than index's node data, swap the data betweenthem
if(current->info > index->info) {
temp = current->info;
current->info = index->info;
index->info = temp;
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
//Node current will point to head
Node *current = head;
if(head == 0) {
return;
}
while(current != 0) {
//Prints each node by incrementing pointer
cout<<current->info<<endl;
current = current->next;
}
cout<<"\n"<<endl;
}
};
int main()
{
//Adds data to the list
LList myList;
myList.addToHead(1);
myList.addToHead(7);
myList.addToHead(3);
TSortedList sortt;
sortt.sortList();
sortt.display();
return 0;
}
Your TSortedList sortt; is empty; you never add anything to it.
What do you expect it to display?
This should work as you expected:
int main()
{
//Adds data to the list
TSortedList myList;
myList.addToHead(1);
myList.addToHead(7);
myList.addToHead(3);
myList.display(); // this should be in original order
myList.sortList();
myList.display(); // this should be sorted
return 0;
}
Also, why are you deriving your TSortedList from Node?
class TSortedList: public LList, public Node
I've never used smart pointers before, so I decided to try out implementing a basic little linked list, just to see how it works. The program bellow outputs only the first element of the list, i.e. 5, and then just exits.
In the print() function, the while loop iterates only once, which means that the list contains only one element even though it should contain 3.
Here's the code:
#include <iostream>
#include <memory>
class list {
private:
struct node {
int val;
std::shared_ptr<node> next;
node(int _val) : val(_val), next(nullptr) {}
};
std::shared_ptr<node> head;
public:
list() {
head = nullptr;
}
void push_back(int val) {
std::unique_ptr<node> new_node(new node(val));
if(head == nullptr) {
head = std::move(new_node);
} else {
std::shared_ptr<node> curr(head);
while(curr != nullptr) {
curr = curr->next;
}
curr = std::move(new_node);
}
}
void print() {
std::shared_ptr<node> curr(head);
while(curr != nullptr) {
std::cout << curr->val << " ";
curr = curr->next;
}
std::cout << std::endl;
}
};
int main() {
std::unique_ptr<list> lst(new list());
lst->push_back(5);
lst->push_back(10);
lst->print();
return 0;
}
You are not appending the node to the end correctly. This part of your code:
while(curr != nullptr) {
curr = curr->next;
}
curr = std::move(new_node);
should instead be:
while(curr->next != nullptr) {
curr = curr->next;
}
curr->next = std::move(new_node);
I am trying to iterate over a vector and get the data into the linked list nodes... I know I can use the STL iterator for vector, but what can I use to loop over the linked list? I don't think I can use STL list iterator, right?
List.h
class List {
public:
List();
void addNode(int addData);
void deleteNode(int delData);
void printList();
private:
typedef struct Node {
int data;
Node* next;
}* nodePtr;
nodePtr head;
nodePtr curr;
nodePtr temp;
};
List.cpp
List::List() {
head = NULL;
curr = NULL;
temp = NULL;
}
void List::addNode(int addData){
nodePtr n = new Node;
n->next = NULL;
n->data = addData;
if(head != NULL) {
curr = head;
while (curr->next != NULL) {
curr = curr->next;
}
curr->next = n;
}
else {
head = n;
}
}
void List::deleteNode(int delData) {
nodePtr delPtr = NULL;
temp = head;
curr = head;
while(curr != NULL && curr->data != delData) {
temp = curr;
curr = curr->next;
}
if(curr == NULL) {
cout << delData << " was not in the list.\n";
delete delPtr;
}
else {
delPtr = curr;
curr = curr->next;
temp->next = curr;
if(delPtr == head) {
head = head->next;
temp = NULL;
}
delete delPtr;
}
}
void List::printList() {
curr = head;
while(curr !=NULL) {
cout << curr->data << endl;
curr= curr->next;
}
}
main.cpp
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
int main(int argc, char** argv) {
cout << "Enter some integers, space delimited:\n";
string someString;
getline(cin, someString);
istringstream stringStream( someString );
vector<int> integers;
int n;
while (stringStream >> n)
List listOfInts;
listOfInts.addNode(/* stuff in here*/)
integers.push_back(n);
return 0;
}
You don't need to iterate through the linked list. Use addNode to add items to the linked list.
vector<int> vec;
...
List list;
for (vector<int>::iterator i = vec.begin(); i != vec.end() ++i)
list.addNode(*i);
That's all there is to it.