Pointers in Linked List [closed] - c++

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 6 years ago.
Improve this question
I'm new to C++, so my code is not optimal, but at the moment I just want it to work.
I have to write a function that compares every 2 elements (1. and 2., 2. and 3. etc.) of linked list and deletes the first of these two elements if it's smaller than the next one. At the end I have to display the list adter editing. I found some examples of what I'm trying to do, but they make me confused and I have no idea how to adjust them to my case.
Here is my code:
#include <iostream>
#include <cstdlib>
using namespace std;
struct elements {
int value;
elements * next;
};
void f (elements * & start){
if (start == NULL || start -> next == NULL) {
return;
}
elements * p = start, * prevvalue = NULL, * previous = NULL, * del, * before = NULL, * after = NULL;
int first = start -> value;
int second = 0;
for (; p != NULL; p = p -> next){
cout << p -> value << endl;
second = p -> value;
if (first < (p -> value)) {
before = prevvalue;
del = p;
previous = p;
p -> next = after -> next;
after -> next = p;
delete del;
}
first = second;
previous = prevvalue;
}
if (previous == NULL) start = start -> next;
else prevvalue -> next = start -> next;
}
int main (){
elements * start = NULL, * last = NULL, * input;
int count;
cout << "How many elmenets would you like to input? ";
cin >> count;
for (int i = 0; i < count; i++){
cout << "Please input " << i + 1 << ". element: ";
elements * input = new elements;
cin >> input -> value;
input -> next = NULL;
if (last != NULL) {
last -> next = input;
last = input;
}
else start = last = input;
}
f (start);
elements * p = start;
while (p != NULL) {
cout << p -> value << endl;
p = p -> next;
}
input = start;
while (start != NULL){
elements * temp = start;
start = start -> next;
delete temp;
}
return 0;
}
There's something totally wrong with pointers, so it's not working.
Can someone please edit my code and throw out everything that's unnecessary?
Thank you in advance!

After some cleanup something like this
#include <iostream>
#include <cstdlib>
using namespace std;
struct elements {
int value;
elements* next;
};
elements* funkcija(elements *start) {
if (start == NULL || start->next == NULL) {
return start;
}
elements *list = start;
elements *current = start;
elements *previous = nullptr;
while(current) {
elements* next = current->next;
if (!next) {
break;
}
if (current->value < next->value) {
if (previous) {
delete current;
previous->next = next;
}
else {
list = next;
delete current;
}
current = nullptr;
}
else {
previous = current;
}
current = next;
}
return list;
}
int main() {
elements *start = NULL, *last = NULL;
int count;
cout << "How many elmenets would you like to input? ";
cin >> count;
for (int i = 0; i < count; i++) {
cout << "Please input " << i + 1 << ". element: ";
elements* input = new elements;
cin >> input->value;
input->next = NULL;
if (last != NULL) {
last->next = input;
last = input;
}
else {
start = last = input;
}
}
start = funkcija(start);
elements * p = start;
while (p != NULL) {
cout << p->value << endl;
p = p->next;
}
while (start != NULL) {
elements * temp = start;
start = start->next;
delete temp;
}
return 0;
}

Related

How to make gotoxy() function select the node in the link list the cursor is on?

I am writing a basic text editor as an assignment and I am having trouble. I am using linked lists and I can move the cursor around the list but every time I try to insert a letter (one letter a node) in between others it just inserts the letter at the end of the list. The code has other errors in general only looking for help on this main question but any suggestions is appreciated.
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <fstream>
#include <string>
using namespace std;
class Node
{
public:
char c;
Node* next;
Node* prev;
};
void gotoxy(int x, int y)
{
COORD pos = { x, y };
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}
void createNew()
{
Node* start = nullptr;
Node* end = nullptr;
Node* prevNode = nullptr;
int xcur = 0, ycur = 0;
char letter = ' ';
while (letter != 27)
{
letter = _getch();
if (letter == 8) // backspace
{
Node *p;
p = end;
end = end->prev;
delete p;
end->next = nullptr;
xcur--;
}
else if (letter == 57) //save press '9'
{
ofstream outdoc;
outdoc.open("TheEditor.txt");
Node* save;
char data;
save = start;
while (save->next != nullptr)
{
data = save->c;
outdoc << data;
save = save->next;
}
outdoc.close();
}
else if (letter == -32)
{
// he pressed right up left or down
letter = _getch();
if (letter == 75) //72 is up 75 left 77 right 80 down
--xcur;
if (letter == 77)
xcur++;
//if (letter == 72)
//ycur++;
//if (letter == 80)
//ycur--;
}
else if (letter == 56) //load file
{
ifstream indoc;
string fname;
cout << "Please enter the name of the file" << endl;
cin >> fname;
indoc.open(fname);
char file[sizeof(indoc)];
for (int j = 0; j < sizeof(fname); j++)
{
indoc >> file[j];
cout << file[j];
j++;
}
}
else if (letter == 13) // enter
{
xcur = 1;
ycur++;
//start = arr[ycur];
}
else // normal eltter
{
Node* p;
p = new Node();
p->c = letter;
p->next = nullptr;
p->prev = nullptr;
if (start == nullptr)
{
start = p;
end = p;
prevNode = p;
}
else if (end->next != nullptr) // insert in middle
{
Node* m = new Node();
m->next = end;
m->c = letter;
m->prev = prevNode;
end->prev = m;
prevNode = m;
}
else
{
p->prev = prevNode;
end->next = p;
end = p;
prevNode = p;
}
//xcur++;
}
system("cls");
// display your linked list here.
Node *p;
p = start;
while (p != nullptr)
{
_putch(p->c);
p = p->next;
}
gotoxy(xcur, ycur);
}
}
void loadFile()
{
string fname;
ifstream indoc;
cout << "Please enter the name of the document" << endl;
cin >> fname;
system("CLS");
indoc.open(fname);
Node* start = nullptr;
Node* end = nullptr;
Node* prevNode = nullptr;
int xcur = 0, ycur = 0;
char letter = ' ';
char file[sizeof(indoc)];
for (int j = 0; j < sizeof(fname); j++)
{
indoc >> file[j];
cout << file[j];
j++;
}
indoc.close();
while (letter != 27)
{
_putch(letter);
if (start == nullptr)
{
Node* p;
p = new Node();
p->c = letter;
p->next = nullptr;
p->prev = nullptr;
start = p;
end = p;
prevNode = p;
}
else
{
Node* t;
t = new Node();
t->c = letter;
t->next = nullptr;
t->prev = prevNode;
end->next = t;
end = t;
prevNode = t;
}
letter = _getch();
if (letter == 57) //save press '9'
{
ofstream outdoc;
outdoc.open("RereTheEditor.txt");
Node* save;
char data;
save = start;
while (save->next != nullptr)
{
data = save->c;
outdoc << data;
save = save->next;
}
outdoc.close();
}
}
}
int main()
{
int choice;
cout << "Welcome to theEditor 2.0!\n"
<< "Please select an option\n"
<< "1. Create New\n"
<< "2. Load File" << endl;
cin >> choice;
system("CLS");
switch (choice)
{
case 1: { createNew(); }
break;
case 2: { loadFile(); }
break;
}
return 0;
}
You must record the corresponding cursor coordinates in each node before you can pass through it.
class Node
{
public:
char c;
COORD pos;
Node* next;
Node* prev;
void setpos(int x, int y)
{
pos.X = x;
pos.Y = y;
}
};
Get the current cursor coordinatesbInfo.dwCursorPosition with GetConsoleScreenBufferInfo:
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO bInfo;
GetConsoleScreenBufferInfo(hOut, &bInfo);
then go to the link list to find the corresponding node of the same position, then insert, and update the coordinates of each node.

Visual studio 2017 code not outputting after a certain line

I am writing a program that takes 8 user inputted integers and makes a linked list out of them. I have the program print the linked list, then I delete the last node and print the list in reverse. Along the way I've been testing to program to make sure each part works, and it's worked up to the point of printing out the original linked list.
When I finished writing the code for the modification and then printing part, I ran into a problem - the program won't output anything after printing out the original list. So for example, if I input 1,2,3,4,5,6,7,8, it will output:
1
2
3
4
5
6
7
8
and that's it. I've tried putting cout << "testing"; at different points to see where my code stops outputting and the latest point where it successfully outputs is right before the while loop.
I'm not sure why a while loop would cause the program to straight up stop outputting anything, even an arbitrary cout statement that has nothing to do with the while loop itself, so I figured I'd ask on here. I'm using visual studio 2017 if that helps. Thanks for any and all help!
#include <iostream>
using namespace std;
void getdata(int & info); //function that assigns a user inputted value to each node
const int nil = 0;
class node_type // declaration of class
{
public:
int info;
node_type *next;
};
int main()
{
node_type *first, *p, *q, *r, *newnode;
first = new node_type;
newnode = new node_type;
int info;
getdata(info); //first node
(*first).info = info;
(*first).next = nil;
getdata(info); //second node
(*newnode).info = info;
(*first).next = newnode;
(*newnode).next = nil;
p = newnode;
for (int i = 2; i < 8; i++) //nodes 3-8
{
newnode = new node_type;
getdata(info);
(*newnode).info = info;
(*p).next = newnode;
p = newnode;
(*newnode).next = nil;
}
q = first;
while (q != nil) // printing linked list
{
cout << (*q).info << "\n";
q = (*q).next;
}
//deletes last node then reverses list
p = first;
q = (*p).next;
r = (*q).next;
if (first == nil) //if list is empty
cout << "Empty list";
else if ((*first).next == nil) //if list has one node
first = nil;
else if (r == nil) //if list has two nodes
q = nil;
else //general case
{
(*first).next = nil; //last line where when i put a cout << ""; it prints in the output window
while ((*r).next != nil)
{
(*q).next = p;
(*r).next = q;
p = q;
q = r;
r = (*r).next;
}
(*q).next = p;
first = q;
}
q = first;
while (q != nil) // printing newly modified list.
{
cout << (*q).info << "\n";
q = (*q).next;
}
return 0;
}
void getdata(int & info)
{
cout << "Enter number: \n";
cin >> info;
}
else //general case
{
(*first).next = nil; //last line where when i put a cout << ""; it prints in the output window
while ((*r).next != nil)
{
(*q).next = p;
(*r).next = q;
p = q;
q = r;
r = (*r).next;
}
(*q).next = p;
first = q;
}
You run into an infinite loop when reversing your list. That's why it doesn't output anything.
As soon as you link element 2 to element 3, you link element 3 to element 2 in the next step.
That causes an infinite loop when iterating through the list while reversing it.
A proper way to reverse it in the general case would be like that:
else //general case
{
node_type* current = first;
node_type* next = first->next;
(*first).next = nil; //last line where when i put a cout << ""; it prints in the output window
while (next)
{
node_type* temp = next->next;
next->next = current;
current = next;
next = temp;
}
first = current;
}
On a sidenote, you should use bla->foo to dereference, instead of (*bla).foo.

Bidirectional list

The following code calculates the sum of the elements of the unidirectional list items greater than 3 and smaller than 8 and the result of the sum is changed the beginning of the list.
#include <iostream>
using namespace std;
struct List
{
int num;
List* nItem;
};
int Input()
{
int number;
cout << "Enter the number: "; cin >> number;
return number;
}
void MakeList(List **head, int n)
{
if (n > 0) {
*head = new List;
(*head)->num = Input();
(*head)->nItem = NULL;
MakeList(&(*head)->nItem, n - 1);
}
}
void Print(List* head)
{
if (head != NULL) {
cout << head->num << " ";
Print(head->nItem);
}
}
List* Add_start(List* head, int index, int elm)
{
List* p = new List;
p->num = elm;
p->nItem = NULL;
if (head == NULL) {
head = p;
}
else {
List* current = head;
for (int i = 0; (i < index - 1) && (current->nItem != NULL); i++)
{
current = current->nItem;
}
if (index == 0)
{
p->nItem = head;
head = p;
}
else {
if (current->nItem != NULL) {
p->nItem = current->nItem;
}
current->nItem = p;
}
}
return head;
}
int Sum(List* head)
{
int sum = 0;
List* p = head;
while(p) {
if ((p->num > 3) && (p->num < 8))
sum += p->num;
p = p->nItem;
}
return sum;
}
void DeleteList(List* head)
{
if (head != NULL) {
DeleteList(head->nItem);
delete head;
}
}
int main()
{
int n = 10;
List* head = NULL;
cout << "Enter 10 number to the list\n" << endl;
MakeList(&head, n);
int sum = Sum(head);
head = Add_start(head, 0, sum);
cout << "\nList: ";
Print(head);
cout << endl;
DeleteList(head);
system("pause");
return 0;
}
How can I do the same operation with a bidirectional list?
Notes:
A bidirectional (or double linked) list, also has a member pointing to the previous node: this is the whole difference between the 2 list types (as a consequence the first element - or the one at the left of the list, will have this member pointing to NULL). So, when such a node is created/inserted into a list, this new member should be set as well (I commented in the code places where this happens), for the new node and for the one following it (if any).
I modified the way of how a list is created - MakeList replaced by _MakeList2 + MakeList2; the underscore(_) in _MakeList2 specifies that it's somehow private (convention borrowed from Python) - it's not very nice, but I thought it's easier this way
I don't have Visual Studio on this computer, so I used gcc. It complained about system function so I had to add #include <stdlib.h>
I renamed some of the identifiers (List -> Node, Add_start -> AddNode, nItem -> nNode) either because the new names make more sense, or their names are consistent
I tried to keep the changes to a minimum (so the solution is as close as possible to your original post)
I enhanced (by adding an additional argument: toRight (default value: 1)) the Print func, so it can iterate the list both ways - I am iterating right to left (for testing purposes) before deleting the list
I corrected some (minor) coding style issues
Here's the modified code:
#include <iostream>
#include <stdlib.h>
using namespace std;
struct Node {
int num;
Node *pNode, *nNode; // Add a new pointer to the previous node.
};
int Input() {
int number;
cout << "Enter the number: "; cin >> number;
return number;
}
Node *_MakeList2(int n, Node *last=NULL) {
if (n > 0) {
Node *node = new Node;
node->num = Input();
node->pNode = last;
node->nNode = _MakeList2(n - 1, node);
return node;
}
return NULL;
}
Node *MakeList2(int n) {
return _MakeList2(n);
}
void Print(Node *head, int toRight=1) {
if (head != NULL) {
cout << head->num << " ";
if (toRight)
Print(head->nNode, 1);
else
Print(head->pNode, 0);
}
}
Node* AddNode(Node *head, int index, int elm) {
Node *p = new Node;
p->num = elm;
p->pNode = NULL; // Make the link between this node and the previous one.
p->nNode = NULL;
if (head == NULL) {
head = p;
} else {
Node *current = head;
for (int i = 0; (i < index - 1) && (current->nNode != NULL); i++) {
current = current->nNode;
}
if (index == 0) {
p->nNode = head;
head->pNode = p; // Make link between next node's previous node and the current one.
head = p;
} else {
if (current->nNode != NULL) {
p->nNode = current->nNode;
}
p->pNode = current; // Make the link between this node and the previous one.
current->nNode = p;
}
}
return head;
}
int Sum(Node* head) {
int sum = 0;
Node *p = head;
while(p) {
if ((p->num > 3) && (p->num < 8))
sum += p->num;
p = p->nNode;
}
return sum;
}
void DeleteList(Node *head) {
if (head != NULL) {
DeleteList(head->nNode);
delete head;
}
}
int main() {
int n = 10;
Node *head = NULL, *tail = NULL;
cout << "Enter " << n << " number(s) to the list" << endl << endl;
head = MakeList2(n);
int sum = Sum(head);
head = AddNode(head, 0, sum);
cout << endl << "List: ";
Print(head);
cout << endl;
tail = head;
if (tail) {
while (tail->nNode != NULL)
tail = tail->nNode;
cout << endl << "List reversed: ";
Print(tail, 0);
cout << endl;
}
DeleteList(head);
system("pause");
return 0;
}

Pointer error queue

Hi. I have a string of digits like in the picture above. I want to print them in decreasing order using a minimum number of queues. The input also acts like a queue.
My idea is to take first digit from the right and create a queue. Then for each other digit check if it is bigger than the first digit in any queue. If it is, add it to that queue. If it is not, create a new queue and repeat the procces.
I have written the following code:
#include<iostream>
using namespace std;
struct Nod{
int info;
Nod *urm;
};
void push(Nod *&p, Nod *&u, int info){
if (p == NULL)
{
p = new Nod;
p->info = info;
u = p;
u->urm = NULL;
}
else
{
Nod *q = new Nod;
q->info = info;
q->urm = p;
p = q;
}
}
void pop(Nod *&p, Nod *&u)
{
if (p != NULL){
Nod *q = p;
if (q->urm != NULL){
while (q->urm->urm != NULL)
{
q = q->urm;
}
delete u;
u = q;
u->urm = NULL;
}
else
p = NULL;
}
else
cout << "Empty Queue";
}
void print(Nod *p)
{
cout << endl;
Nod *q = p;
while (q != NULL)
{
cout << q->info << " ";
q = q->urm;
}
cout << endl;
}
int main()
{
Nod *p, *u;
p = u = NULL;
Nod *p1[100];
Nod *u1[100];
char * s;
s = new char[100];
cin >> s;
push(p1[0], u1[0], s[(unsigned)strlen(s) - 1]-'0');
for (int i = (unsigned)strlen(s) - 2; i >= 0; i--){
int k = 0; int ok = 0;
while (p1[k] != NULL)
{
if (s[i]-'0' >= p1[k]->info)
{
push(p1[k], u1[k], s[i]-'0');
ok = 1;
break;
}
k++;
}
if (ok == 0)
push(p1[k], u1[k], s[i]-'0');
}
//test printing first 3 lines.
print(p1[0]);
print(p1[1]);
print(p1[2]);
system("Pause");
}
I have a crash at this line which I believe it's caused by a pointer error? I'm using Visual Studio 2013. I've tried using the debugger but still I can't figure out what's the problem. I also wanted to ask if you can point me some basic resources on how to use the debugger. Thank you.
if (s[i]-'0' >= p1[k]->info)

Find first and second element in list C++

Here's my program for implementing a list in C++. I type elements untill 0. Program shows me first element correctly but second is wrong. I probably make errors in second condition
if (p -> next == first) {
secondElement = first -> data;
}
. Can you say what is wrong with it. Thanks
#include "stdafx.h"
#include "iostream"
using namespace std;
struct Node {
int data;
Node *next;
};
int firstElement;
int secondElement;
int main()
{
Node *first = 0;
Node *p;
cout << "Enter a list" << endl;
int i;
while (true) {
cin >> i;
if (i == 0) break;
p = new Node;
p -> data = i;
p -> next = first;
if (first == 0) {
first = p;
firstElement = first -> data;
}
if (p -> next == first) {
secondElement = first -> data;
}
first = p;
}
cout << "First element is: " << firstElement << endl;
cout << "Second element is: " << secondElement << endl;
cout << "List: ";
p = first;
while (p) {
cout << p -> data << " ";
p = p -> next;
}
cout << endl;
return 0;
}
You can do it like this (I just edited your while loop):
while (true) {
cin >> i;
if (i == 0) break;
p = new Node;
p -> data = i;
p -> next = 0;
if (first != 0 && first->next == 0)
secondElement = p->data;
p -> next = first;
if (first == 0) {
first = p;
firstElement = first -> data;
}
first = p;
}
Hope it is what you want to achieve...
Each time through the loop you're setting the pointer of the element to the first.
p -> next = first;
Then in the check for the second element you're checking whether the pointer is set to the first, which it always is.
if (p -> next == first) // This is always true
You'll have to use some different check to see whether it's the second entry in the list, like:
if (p->next && !p->next->next) // only true second time around
{
secondElement = p -> data; // also note the change here
}
p -> next = first;
......
enter code here
if (p -> next == first) { //it's always true here
you should have had
if (p -> next == 0) {