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 8 years ago.
Improve this question
Please help me with my code. I am trying to insert in a singly linked list.My code is compiling but it is giving a run time error.I am not able to understand where i have gone wrong.Here goes my code :-
#include <iostream.h>
#include <stdio.h>
using namespace std;
struct node
{
int info;
struct node* next;
};
typedef struct node* nodeptr;
void insert(nodeptr p,int x);
void print(nodeptr p);
int main()
{
nodeptr head;
head = NULL;
int num;
do
{
cout<<"ENTER A NUMBER(0 to terminate) :-\n";
cin >>num;
insert(head,num);
}
while (num != 0);
print(head);
}
void insert(nodeptr p,int x)
{
nodeptr tmp = new node;
tmp -> info = x;
tmp -> next = NULL;
nodeptr current;
current = p;
if (p == NULL)
{
p = tmp;
}
if (x < p -> info)
{
tmp->next = p;
p = tmp;
}
while((current->next != NULL) && (x >= (current->next)->info))
{
current = current -> next;
}
tmp->next = current->next;
current->next = tmp;
}
void print(nodeptr p)
{
nodeptr current;
current = p;
while(current != NULL)
{
int tmp = current->info;
cout << tmp;
current = current->next;
}
}
First of all, you never assign anything to head, so print(head) will not print anything.
Second, that last while in the main is useless.
Third:
nodeptr insert(nodeptr head, int x)
{
nodeptr tmp = new node;
tmp -> info = x;
tmp -> next = NULL;
nodeptr prec = null;
nodeptr current = head;
while(current != null && x < current->info)
{
prec = current;
current = current -> next;
}
tmp->next = current;
if(prec != null)
prec->next = tmp;
else
return tmp;
return head;
}
and in the main
head = insert(head, num);
When dealing with pointers, always try to keep things separated: first seek, then modify.
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;
}
}
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 3 months ago.
Improve this question
Im trying to create function to delete from single-linked list all elements with value smaller as next (following) element value. For some reason programm throws "free():double free detected in tcache 2". What is wrong with my function ?
list is not empty.
#include <iostream>
using namespace std;
struct Elem
{
int num;
Elem* next;
};
void deleteFromLinkedList(Elem* list) {
Elem* curr, * next, *prev;
curr = list;
next = list->next;
while (next != NULL)
{
if (curr->num < next->num) {
prev->next=next;
delete curr;
curr = prev;
continue;
}
prev = curr;
curr = next;
next = curr->next;
};
}
int main()
{
Elem* first = NULL, * last = NULL, * p;
int i;
cout << "Enter any number or 0 to finish: ";
cin >> i;
while (i != 0)
{
p = new Elem;
p->num = i;
p->next = NULL;
if (first == NULL)
{
first = last = p;
}
else
{
last->next = p;
last = last->next;
};
cout << "Enter any number or 0 to finish: ";
cin >> i;
};
deleteFromLinkedList(first);
There are a number of problems with your code.
next = list->next; is undefined behavior if the list is empty (ie list is null).
prev->next=next; is undefined behavior for the 1st node in the list, as prev is unassigned.
You are not updating curr after delete'ing the node it points at, which is also undefined behavior.
The list pointer is being passed in by value, so the caller's pointer can't be updated if the 1st node in the list is freed, thue the caller will be left with a dangling pointer to invalid memory.
Try this instead:
void deleteFromLinkedList(Elem* &list) {
if (!list)
return;
Elem *curr = list, *next = list->next, *prev = NULL;
while (next)
{
if (curr->num < next->num) {
if (prev)
prev->next = next;
else
list = next;
delete curr;
}
else {
prev = curr;
}
curr = next;
next = curr->next;
}
}
Online Demo
UPDATE: In comments, you changed your requirements to need the list scanned in multiple iterations. The code above works fine for 1 iteration, so you could simply call it multiple times in a loop until there are no more removals performed, eg:
bool deleteFromLinkedList(Elem* &list) {
if (!list)
return false;
Elem *curr = list, *next = list->next, *prev = NULL;
bool anyRemoved = false;
while (next)
{
if (curr->num < next->num) {
if (prev)
prev->next = next;
else
list = next;
delete curr;
anyRemoved = true;
}
else {
prev = curr;
}
curr = next;
next = curr->next;
}
return anyRemoved;
}
...
while (deleteFromLinkedList(first));
...
Online Demo
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 5 years ago.
Improve this question
I'm just learning C++ right now, so I wanted to create a simple linked list program to learn how to write C++. (I come from Java and Python). Sometimes (not every time) I get an EXC_BAD_ACCESS error.
Here is my code:
#include <iostream>
#include <string>
using namespace std;
class LinkedList
{
struct Node
{
int value;
Node *next;
};
private:
Node *head;
public:
LinkedList()
{
head = NULL;
}
void addNode(int value, int index)
{
Node *node = new Node;
node->value = value;
Node *n = head;
if (index == 0)
{
node->next = n;
head = node;
return;
}
int size = getSize();
for (int i = 0; i < size - 1; i++)
{
if (i == index - 1)
{
node->next = n->next;
n->next = node;
}
n = n->next;
}
}
void addNode(int value)
{
Node *node = new Node;
node->value = value;
if (!head)
{
node->next = NULL;
head = node;
return;
}
Node *n = head;
int size = getSize();
for (int i = 0; i < size - 1; i++)
{
n = n->next;
}
n->next = node;
}
int getSize()
{
Node *_node = new Node;
_node->value = head->value;
_node->next = head->next;
int size = 1;
while (_node != NULL)
{
_node = _node->next;
size++;
}
return size - 1;
}
string printList()
{
Node *n = head;
string output = to_string(n->value);
int size = getSize();
for (int i = 0; i < size - 1; i++)
{
n = n->next;
output.append(" -> " + to_string(n->value));
}
return output;
}
};
I get this error in the method "getSize()" on the line "_node = _node->next;" I have no idea what's wrong.
Inside addNode you are not initializing the next pointer of Node to NULL when there is a head node.
You must initialize it to NULL.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Below code takes an item as argument and delete all occurrences of the item in linked list.It works well with my testing. is there anything that i am missing? can this code be improved further?
void
LinkedList::DeleteAllOccurences(int key) {
Node *temp = head;
Node *prev = head;
while(temp!=NULL) {
if(temp->item == key){
if(temp == head) {
head = temp->next;
delete temp;
temp = head;
} else {
prev->next = temp->next;
delete temp;
temp = prev->next;
}
} else {
prev = temp;
temp = temp->next;
}
}
return;
}
I believe your code has a bug. When deleting the head node, prev is not updated correctly (i.e.) it will still point to the deleted head node.
I've annotated your code and applied a fix [please pardon the gratuitous style cleanup]:
void
LinkedList::DeleteAllOccurences(int key)
{
Node *temp = head;
Node *prev = head;
while (temp != NULL) {
if (temp->item == key) {
// NOTE/BUG: after this, prev will _still_ be pointing to the
// _deleted_ head node
// NOTE/FIX: to fix this, prev must be set to the _updated_ head
// node
if (temp == head) {
head = temp->next;
// NOTE/FIX: add this:
#if 1
prev = head;
#endif
delete temp;
temp = head;
}
else {
prev->next = temp->next;
delete temp;
temp = prev->next;
}
}
else {
prev = temp;
temp = temp->next;
}
}
return;
}
There may be another bug as well. And, I think there's a way to simplify things a bit. So, for comparison:
void
LinkedList::DeleteAllOccurences(int key)
{
Node *temp;
Node *prev = NULL;
Node *next;
for (temp = head; temp != NULL; temp = next) {
next = temp->next;
if (temp->item != key) {
prev = temp;
continue;
}
if (prev != NULL)
prev->next = next;
else
head = next;
delete temp;
}
}
Another approach would be to use std::list<> and let it do all of the heavy lifting. Below is an example implementation that should fit what you need:
#include <list>
#include <iostream>
using namespace std;
int main()
{
// Create a list.
list<int> myList;
// Add some numbers: 2, 3, 2, and 5.
myList.push_back(2);
myList.push_back(3);
myList.push_back(2);
myList.push_back(5);
// Print the contents of the list.
// Will output 2, 3, 2, 5.
for(auto item : myList)
cout << item << endl;
// Remove all numbers equal to 2.
myList.remove(2);
// Print the contents of the list.
// Will output 3 and 5.
for(auto item : myList)
cout << item << endl;
return 0;
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I implement a queue myself. when testing, I expect the dequeue to reutrn when the queue is empty by testing if the tail pointer point to the head node. However, the address of the head node and the one pointer point are different when the point indeed points to the head, hence the queue never stop dequeue even if there is nothing in it.
This confuse me a lot. Any suggestion on this?
thanks a lot.
//header
#ifndef QUEUE_H
#define QUEUE_H
struct node
{
int val;
struct node* next;
};
class queue
{
private:
node head;
node* tail;
public:
queue();
void enqueue(int val);
void dequeue(int& holder, bool& v);
};
#endif
// queue.cpp
#include "queue.h"
using namespace std;
queue::queue()
{
tail = &head;
}
void queue::enqueue(int val)
{
node* tmp = new node;
tmp->val = val;
if(tail == &head)
{
tail = tmp;
tmp->next = &head;
head.next = tmp;
}
else
{
node* holder = head.next;
head.next = tmp;
tmp->next = &head;
holder->next = tmp;
}
}
void queue::dequeue(int& holder,bool& v)
{
if(tail == &head)
{
v = false;
}
else
{
node* cur = tail;
tail = tail->next;
holder = cur->val;
v = true;
delete cur;
}
}
//test.cpp
#include <iostream>
#include "queue.h"
using std::cout;
using std::endl;
int main()
{
int ary[] = {1,2,3,4,5};
queue myq;
for(int i = 0;i< sizeof(ary);i++)
{
myq.enqueue(ary[i]);
}
int tmp;
bool flag;
for(int i = 0;i<=7;i++)
{
myq.dequeue(tmp,flag);
if(flag)
cout<<"number is "<<tmp<<endl;
else
cout<<"queue empty"<<endl;
}
return 0 ;
}
I could give you the exact fix, but that would teach you absolutely nothing, you'd just copy and paste that into your code and go away do something else. So I'm going to help you with a line of code to add to show what the current value of &head is, and thus help identify what the actual problem is...
Add this line to enqueue (at the top of the function) and dequeue:
std::cout << __FUNCTION__ << ": " << &head << std::endl;
It will print the name of the function and the address off head. (You may need to include iostream as well)
Pay particular attention to how many printouts you get!
Working code below: (Learn to use a debugger)
#include <iostream>
using namespace std;
//header
#ifndef QUEUE_H
#define QUEUE_H
struct node {
int val;
struct node* next;
};
class queue {
private:
struct node* head;
struct node* tail;
public:
queue();
void enqueue(int val);
void dequeue(int& holder, bool& v);
};
#endif
using namespace std;
queue::queue() {
tail = NULL;
head = NULL;
}
void queue::enqueue(int val) {
node* tmp = new node;
tmp->val = val;
if (head == NULL && NULL == tail) {//No nodes Empty
head = tail = tmp;
tmp->next = NULL;
}else if (tail == head) { //Single node
tail = tmp;
tmp->next = head;
head->next = tmp;
} else {
tail->next = tmp;
tmp->next = head;
tail = tmp;
}
}
void queue::dequeue(int& holder, bool& v) {
if (NULL == tail || NULL == head) {
v = false;
return;
} else if (tail == head) {// single node
holder = head->val;
delete head;
head = NULL;
tail = NULL;
v = true;
} else { //more than one node
//Go to the last but one node and chop the tail
node* cur = head;
while (cur->next != tail)
cur = cur->next;
cur->next = head;
holder = tail->val;
delete tail;
tail = cur;
v = true;
}
return;
}
using std::cout;
using std::endl;
int main() {
int ary[] = { 1, 2, 3, 4, 5 };
queue myq;
for (int i = 0; i < 5; i++) {
myq.enqueue(ary[i]);
}
int tmp;
bool flag;
for (int i = 0; i <= 7; i++) {
myq.dequeue(tmp, flag);
if (flag) {
cout << "number is " << tmp << endl;
}
else {
cout << "queue empty" << endl;
}
}
return 0;
}