What is wrong with the delete section? [closed] - c++

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.
Here is my code. The problem that I am getting is that I can't make work the deleter part. I want to delete one element of the structure. Here is a basic structure that you add, search and delete elements that are added. Also the elements are sorted in increasing order.
#include <iostream>
using namespace std;
struct el {
int key;
el *next;
} *start;
void init();
void add(int n);
void list();
void search(int n); // ima za dopylvane
void deleter(int n);
void main() {
init();
int n, num;
do {
cout << "\n Menu\n";
cout << "\n1 - Add element";
cout << "\n2 - List elements";
cout << "\n3 - Searching for element";
cout << "\n4 - Delete element";
cout << "\n5 - Exit";
cout << "\n Your choice:";
cin >> n;
switch (n) {
case 1:
{
cout << "\n Input num:";
cin >> num;
add(num);
break;
}
case 2:
{
list();
break;
}
case 3:
{
cout << "\n Input num for searching:";
cin >> num;
search(num);
break;
}
case 4:
{
cout << "\n Input num for deleting:";
cin >> num;
deleter(num);
break;
}
}
}
while (n != 5);
}
void list() {
el *p = start;
if (start) while (p) {
cout << p->key << " ";
p = p->next;
} else cout << "\n Empty list";
}
void init() {
start = NULL;
}
void add(int n) {
el *p = start;
if (!start) {
start = new el;
start->key = n;
start->next = NULL;
} else {
if (start->key > n) {
start = new el;
start->key = n;
start->next = p;
} else {
el * q;
while ((p->key < n) && (p->next)) {
q = p;
p = p->next;
}
if (p->key > n) {
el *s;
s = new el;
s->key = n;
s->next = p;
q->next = s;
} else {
el *s;
s = new el;
s->key = n;
s->next = NULL;
p->next = s;
}
}
}
}
void search(int n) {
el *p = start;
if (!start) cout << "\nEmpty list!";
else while ((p->key != n) && (p-> next))
p = p->next;
if (p->key == n) cout << "\nYes!";
else cout << "\nNo!";
}
void deleter(int n) {
el *p = start;
if (!start) cout << "Enfsad";
else while ((p->key != n) && (p->next)) {
n = start->key;
start = start->next;
delete p;
}
}

Your deleter function should be like this.
void deleter (int n)
{
el *p = start;
el *prev = p;
if (!start)
{
cout<<"Enfsad";
}
if(start->key == n)
{
start = start->next;
delete prev;
}
else
{
while (p)
{
if(p->key == n)
{
prev->next = p->next;
p->next = NULL;
delete p;
break;
}
prev = p;
p = p->next;
}
}
}
Although I think you need to check how a good linked list should be.

Related

How do I swap an element of a C++ stack

I have this task to do. Basically, I have to create a dynamic stack, then I have to choose an element and swap it with a new one which I inserted. The other elements remain the same and I have to display the new data. I've come to a dead end.
#include <iostream>
using namespace std;
struct elem
{
int key;
elem* next;
} *start = NULL, *p;
void push(int n);
int pop(int &n);
int main()
{
int num, counter = 0;
do
{
cout << "Input integers(!=0): ";
cin >> num;
if (num > 0 || num < 0)
{
push(num);
counter++;
}
}
while (num != 0);
cout << "\nStack: ";
while (pop(num))
cout << num << "\t";
cout << "\n";
int element, newValue;
cout << "Input element number: ";
cin >> element;
cout << "New value of element: ";
cin >> newValue;
here I struggle doing the swap
return 0;
}
void push(int n)
{
p = start;
start = new elem;
start->key = n;
start->next = p;
}
int pop(int &n)
{
if (start)
{
n = start->key;
p = start;
start = start->next;
delete p;
return 1;
}
else
return 0;
}
How do you swap a chosen one from a stack of (dinner) plates with the top one?
you pick the topmost, put it aside, then pick all the ones you don't want and put them on a new stack until you reach the chosen one. Pick it, exchange it with the original topmost one, put the chosen one aside.
Then re-stack, one by one, the plates from the new stack to the old one. Lastly, put the one you put aside on top.
Going through an intermediary stack like #Bathsheba suggested is the most straight forward solution here.
You can also save some execution time by simply modifying the "next" var of the previous
element to the element you're going the change.
#include <iostream>
using namespace std;
struct elem
{
int key;
elem* next;
}
*start = NULL, *p,*previous,*curr,*temp;
void push(int n);
int pop(int &n);
int main() {
int num, counter = 0;
do {
cout << "Input integers(!=0): ";
cin >> num;
if (num > 0 || num < 0) {
push(num);
counter++;
}
}
while (num != 0);
/* cout << "\nStack: ";
while (pop(num))
cout << num << "\t";
cout << "\n";
*/
int element, newValue;
cout << "Input element number: ";
cin >> element;
cout << "New value of element: ";
cin >> newValue;
curr = start ;
previous = NULL;
while(curr->next)
{
if(curr->key == element){
if(previous) {
temp = new elem;
temp->key = newValue;
temp->next = curr->next ;
previous->next = temp ;
break;
}
else {
temp = new elem;
temp->key = newValue;
temp->next = curr->next ;
start = temp ;
break;
}
}
else {
previous = curr ;
curr = curr->next;
}
}
while (pop(num))
cout << num << "\t";
cout << "\n";
return 0;
}
void push(int n) {
p = start;
start = new elem;
start->key = n;
start->next = p;
}
int pop(int &n) {
if (start) {
n = start->key;
p = start;
start = start->next;
delete p;
return 1;
}
else
return 0;
}

Sorting Names in Linked List

(This is a Homework Question)I am having trouble implementing a name sort for a linked list. I have the weight(int) sort working now i just want to sort names in ascending order.
#include<stdio.h>
#include<conio.h>
#include<iostream>
using namespace std;
int c = 0;
struct node
{
char name[20];
int weight;
node *next;
node *prev;
};
node*head = NULL;
node *tail = NULL;
node *start_ptr = NULL;
Here I create the node and insert into the list in sorted position. I want to do the same for names. A name is assigned a weight(For example a persons weight). It has to be in sorted position so when the print function is called it prints the list in sorted order.
void create(int x,char name)
{
node*p = NULL;
node*r = NULL;
node*np = NULL;
np = new node;
np->weight = x;
np->next = NULL;
np->prev = NULL;
if (c == 0)
{
tail = np;
head = np;
p = head;
p->next = NULL;
p->prev = NULL;
c++;
}
else
{
p = head;
r = p;
if (np->weight < p->weight)
{
np->next = p;
p->prev = np;
np->prev = NULL;
head = np;
p = head;
do
{
p = p->next;
} while (p->next != NULL);
tail = p;
}
else if (np->weight > p->weight)
{
while (p != NULL && np->weight > p->weight)
{
r = p;
p = p->next;
if (p == NULL)
{
r->next = np;
np->prev = r;
np->next = NULL;
tail = np;
break;
}
else if (np->weight < p->weight)
{
r->next = np;
np->prev = r;
np->next = p;
p->prev = np;
if (p->next != NULL)
{
do
{
p = p->next;
} while (p->next != NULL);
}
tail = p;
break;
}
}
}
}
}
void traverse_head()
{
node *t = head;
while (t != NULL)
{
cout << t->weight << "\t";
t = t->next;
}
cout << endl;
}
void print_node()
{
node *temp;
temp = start_ptr;
if (temp == NULL) cout << "Empty List!" << endl;
while (temp != NULL)
{
if (temp == NULL) cout << "Empty List!" << endl;
cout << "Names & weights sorted(ascending) by name. :\n";
cout << "Name : " << temp->name << endl;
cout << "Weight : " << temp->weight << endl;
cout << "Names & weights sorted(ascending) by weight. : \n";
cout << endl;
temp = temp->next;
}
}
int main()
{
int i = 0, n, x;
char names[20];
cout << "Enter the number of people: \n";
cin >> n;
A loop that reads in the weight and the name of that person
while (i < n)
{
cout << "\nEnter Weights: \n";
cin >> x;
cout<<"Enter a Name"<<endl;
cin>>names;
create(x,*names);
i++;
}
cout << "Output: \n";
traverse_head();
system("pause");
return 0;
}

Output of c++ program not coming as expected

I have made a C++ program for a binary tree. But the terminal is not asking the statement for inputting the direction for where the elements are to be placed.
Also when I replace the statement from " node *temp = new node " to "node *temp=NULL" the program stops working .
#include <iostream>
#include <cstring>
using namespace std;
class node {
int data;
node * left;
node * right;
public:
node * level_order(node * first);
node * create_bt(node * first);
void display(node * first);
};
//node *first=NULL;
node * node::create_bt(node * first) {
node * temp = new node;
int ele;
//char dir;
cout << "\n Enter data ";
cin >> ele;
temp->data = ele;
temp->left = NULL;
temp->right = NULL;
if (first == NULL) {
temp = first;
return first;
} else {
char dir[20];
cout << "\n Enter the direction ";
cin >> dir;
node * cur = first;
int j = 0;
while (dir[j] != '\0') {
if (dir[j] == 'l') {
cur = cur->left;
}
if (dir[j] == 'r') {
cur = cur->right;
}
j++;
}
cur = temp;
return first;
}
}
void node::display(node * first) {
if (first == NULL)
return;
cout << "\n " << first->data;
display(first->left);
display(first->right);
}
int main() {
int n;
node s;
node * first = NULL;
cout << "\n No of elements ";
cin >> n;
for (int i = 0; i < n; i++) {
first = s.create_bt(first);
}
s.display(first);
return 0;
}
first=s.create_bt(first); does not changes state, from NULL to 'l' or 'r'. You have to change that.
node*node::create_bt(node *first)
{
node *temp=new node;
int ele;
//char dir;
cout<<"\n Enter data ";
cin>>ele;
temp->data=ele;
temp->left=NULL;
temp->right=NULL;
char dir[20];
cout<<"\n Enter the direction ";
cin>>dir;
if(first==NULL)
{
temp=first;
return first;
}
else
{
node*cur=first;
int j=0;
while(dir[j]!='\0')
{
if(dir[j]=='l')
{
cur=cur->left;
}
if(dir[j]=='r')
{
cur=cur->right;
}
j++;
}
cur=temp;
return first;
}
}
I believe you re looking something like this. This is a basic binary tree, i had to make a basic one in order to understand how it works and how it chooses left and right. I make a class inside a class, in order to have access to my data members (node class, int data, *left , *right) and have them at the same time protected, all-in-one. As you can see "newnode" just creates a node and NULL s the pointers. Thats it. "Find" searches and finds a node with a current key, and returns it when exits. All the rest, i guess, you can understand them, as they are prety much the same with your code. The only thing you have to do is to define, when you want to direct the node you want. REMINDER: You have to find a way to utilize it, so the leafs will not end far-left or far-right.("Enter the direction"). I hope i helped you understand.
#include <iostream>
#include <conio.h>
using namespace std;
class mybTree {
class node {
public:
int data;
node * left;
node *right;
};
node *root;
node *newnode(int num){
node *newnode1;
newnode1 = new (nothrow) node;
newnode1->data = num;
newnode1->left = NULL;
newnode1->right = NULL;
return newnode1;
}
public:
node *find (int key) {
node *current;
current = root;
while (current->data !=key){
if (key<current->data){
current = current->left;
} else {
current = current->right;
}
if (current == NULL){
return NULL;
}
}
return NULL;
}
void display (node *ptr);
void display_tree();
bool insert(int num);
void post_order_delete(node *ptr);
mybTree();
~mybTree();
};
int main(){
char ch = ' ';
int a;
mybTree mybTree1;
while (ch !='0'){
cout << "0->Exit"<<endl<< "1-> add"<<endl<< "2-> find" <<endl<<"3-> Show me the tree\n";
ch = getch();
switch (ch) {
case '0':
break;
case '1':
cout << "number";
cin >> a;
if (!mybTree1.insert(a)){
cout << "Not enough memory" << endl;
}
break;
case '2' :
cout << "Number:" ;
cin >> a;
if (mybTree1.find(a)!=NULL) {
cout << "Found" << endl;
} else {
cout << "Not existed" << endl;
}
break;
case '3':
mybTree1.display_tree();
cout<<endl;
break;
default:
cout << "Wrong Message";
break;
}
}
return 0;
}
void mybTree::display(node *ptr) {
if (ptr == NULL){
return;
}
display(ptr->left);
cout << ptr->data<<endl;
display(ptr->right);
}
void mybTree::display_tree() {
//Displays the Tree
display(root);
}
bool mybTree::insert(int num) {
//It inserts a node. Desides left or right.
node *next,*current,*ptr;
int isleft;
next = current = root;
ptr = newnode(num);
if (ptr == NULL) {
return false;
}
if (root == NULL) {
root = ptr;
return true;
}
while (1){
if (num < current->data){
next = current->left;
isleft = 1;
} else {
next = current->right;
isleft = 0;
}
if (next == NULL){
if (isleft){
current->left = ptr;
} else {
current->right = ptr;
}
return true;
}
current=next;
}
return false;
}
void mybTree::post_order_delete(node *ptr) {
//deletes the node. Usefull for destructor
if (ptr == NULL){
return;
}
post_order_delete(ptr->left);
post_order_delete(ptr->right);
cout << ptr->data;
delete ptr;
}
mybTree::mybTree() {
//Constructor
root = NULL;
}
mybTree::~mybTree() {
//Destructor
post_order_delete(root);
root = NULL;
}

Level Order Traversal: Deleting a Subtree

#include <iostream>
using namespace std;
struct node {
int item;
node* l;
node* r;
node (int x) {
item = x;
l = 0;
r = 0;
}
node(int x, node* l, node* r) {
item = x;
this->l = l;
this->r = r;
}
};
typedef node* link;
class QUEUE {
private:
link* q;
int N;
int head;
int tail;
public:
QUEUE(int maxN) {
q = new link[maxN + 1];
N = maxN + 1;
head = N;
tail = 0;
}
int empty() const {
return head % N == tail;
}
void put(link item) {
q[tail++] = item;
tail = tail % N;
}
link get() {
head = head % N;
return q[head++];
}
};
link head = 0; // Initial head of the tree
link find(int x) {
if (head == 0) {
cout << "\nEmpty Tree\n";
return 0;
}
link temp = head;
// To find the node with the value x and return its link
QUEUE q(100);
q.put(temp);
while (!q.empty()) {
temp = q.get();
if (temp->item == x) {
return temp;
}
if (temp->l != 0) q.put(temp->l);
if (temp->r != 0) q.put(temp->r);
}
return 0;
}
void print(link temp) {
QUEUE q(100);
q.put(temp);
while (!q.empty()) {
temp = q.get();
cout << temp->item << ", ";
if (temp->l != 0) q.put(temp->l);
if (temp->r != 0) q.put(temp->r);
}
}
void deleteAll(link h) {
// This deletes the entire binary tree
QUEUE q(100);
q.put(h);
while (!q.empty()) {
h = q.get();
if (h->l != 0) q.put(h->l);
if (h->r != 0) q.put(h->r);
delete h;
}
}
int main() {
link temp = 0;
char c;
int n1, n2;
cout << "\n\nPlease enter the input instructions (X to exit program) : \n\n";
do {
cin >> c;
switch (c) {
case 'C': cin >> n1;
if (head == 0) {
head = new node(n1);
cout << "\nRoot node with item " << n1 << " has been created\n\n";
} else {
cout << "\nError: Tree is not empty\n\n";
}
break;
case 'L': cin >> n1 >> n2;
temp = find(n1);
if (temp != 0) {
if (temp->l == 0) {
temp->l = new node(n2);
cout << "\nNode with item " << n2 << " has been added\n\n";
}
else {
cout << "\nError: The specified node already has a left child\n\n";
}
}
else {
cout << "\nError: The specified node doesn't exist\n\n";
}
break;
case 'R': cin >> n1 >> n2;
temp = find(n1);
if (temp != 0) {
if (temp->r == 0) {
temp->r = new node(n2);
cout << "\nNode with item " << n2 << " has been added\n\n";
}
else {
cout << "\nError: The specified node already has a right child\n\n";
}
}
else {
cout << "\nError: The specified node doesn't exist\n\n";
}
break;
case 'P': cin >> n1;
temp = find(n1);
if (head != 0) {
cout << "\nLevel-order traversal of the entire tree: ";
print(temp);
}
else {
cout << "\nError: No elements to print\n\n";
}
break;
case 'D': cin >> n1;
temp = find(n1);
deleteAll(temp);
temp = 0;
break;
case 'X': cout << "\nExiting Program\n\n";
break;
default: cout << "\nInvalid input entered. Try again.\n\n";
}
} while (c != 'X');
system("pause");
return 0;
}
Sample Input:
C 9
L 9 8
R 9 6
L 8 3
R 8 5
R 6 2
L 3 4
L 4 10
L 5 1
R 5 11
L 1 12
R 1 7
It all works fine until I delete a subtree and print when it prints garbage value before crashing. Please help me figure out the bug because I've been trying in vain for hours now.
It all works fine until I delete a subtree and print when it prints garbage value before crashing. Please help me figure out the bug because I've been trying in vain for hours now.
Try the recursive function:
void Delete(link h)
{
if(h)
{
if(h->l) Delete(h->l);
if(h->r) Delete(h->r);
delete(h);
}
}
When you delete a node, you call deleteAll(temp) which deletes temp, but it doesn't remove the pointer value from the l or r of temp's parent node.
This leaves you with a invalid pointer, causing garbage printing and crashing.
Unfortunately, the way your find works currently, you don't know what the current temp node's parent is when you get around to checking its value.
One way to fix it is to have a different type of find (called something like remove) that looks in l and r at each iteration for the value and sets l or r to NULL before returning the pointer. You might have to have a special case for when the value is found in the root.
Edit (sample code added):
I am assuming you are not using recursion for some reason, so my code uses your existing queue based code. I only changed enough to get it working.
findAndUnlink find the node with the value given and "unlinks" it from the tree. It returns the node found, giving you a completely separate tree. Note: it is up to the caller to free up the returned tree, otherwise you will leak memory.
This is a drop in replacement for find in your existing code, as your existing code then calls deleteAll on the returned node.
link findAndUnlink(int x) {
if (head == 0) {
cout << "\nEmpty Tree\n";
return 0;
}
link temp = head;
if (temp->item == x) {
// remove whole tree
head = NULL;
return temp;
}
// To find the node with the value x and remove it from the tree and return its link
QUEUE q(100);
q.put(temp);
while (!q.empty()) {
temp = q.get();
if (temp->l != NULL) {
if (temp->l->item == x) {
link returnLink = temp->l;
temp->l = NULL;
return returnLink;
}
q.put(temp->l);
}
if (temp->r != NULL) {
if (temp->r->item == x) {
link returnLink = temp->r;
temp->r = NULL;
return returnLink;
}
q.put(temp->r);
}
}
return 0;
}

C++ Linked list issue

I have been working on a little personal project, and have run into a snag. The purpose of the project is to add to my Github, but I have been staring at my code off and on for the last week and cannot find where it goes wrong. The project is a test of my own ability, and my understanding of Linked Lists in C++. Before I go on, here is my code
#include <iostream>
using namespace std;
struct payload {
int ID;
int x;
int y;
string name;
};
struct node {
node* prev;
node* next;
bool isRoot;
payload data;
};
node* fillStruct(node* tmp);
void print(node* tmp);
int main(void) {
node* temp;
node* list;
node* iterator;
bool done = false;
int count = 0;
char answer;
do {
temp = new node();
temp = fillStruct(temp);
if (count == 0) {
list = new node();
list = temp;
list->prev = NULL;
list->next = NULL;
list->isRoot = true;
} else {
list->next = temp;
temp->prev = list;
list = new node();
list = temp;
}
count++;
cout << "Will more elements be added to the list?\n [Y or N]\n";
cin >> answer;
switch (answer) {
case 'y':
case 'Y':
break;
case 'n':
case 'N':
list->next = NULL;
done = true;
break;
default:
break;
}
} while (!done);
while (list->prev != NULL) {
list = list->prev;
}
int identifier = 100;
while (1) {
list->data.ID = identifier;
identifier++;
if (list->next == NULL)
break;
list = list->next;
}
while (list->prev != NULL) {
list = list->prev;
}
while (1) {
print(list);
if (list->next == NULL)
break;
list = list->next;
}
return 0;
}
node* fillStruct(node* tmp) {
if (!tmp) {
cerr << "Unauthorized access. Terminating program";
return tmp;
}
cout << "Please enter the X value.\n";
cin >> tmp->data.x;
cout << "Please enter the Y value.\n";
cin >> tmp->data.y;
cout << "Please enter the data name\n";
cin >> tmp->data.name;
return tmp;
}
void print(node* tmp) {
cout << "Identifier: " << tmp->data.ID << endl;
cout << " X: " << tmp->data.x << endl;
cout << " Y: " << tmp->data.y << endl;
cout << " Name: " << tmp->data.name << endl;
}
The code compiles and executes fine. The problem I am having is in the printing phase of the code. It cuts off the last element, and I cannot tell why. The second while(1), as I understand it, should terminate after it prints the final element. If anyone can offer guidance, I would greatly appreciate it. Thanks in advance, and as usual, if there's anything I can add to clarify, I will.
Following your code, it would seem better to keep list at the list head, and use a pointer for walking the list.
node* list = NULL;
node* ptr = NULL; // tail
do {
temp = new node();
temp = fillStruct(temp);
temp->prev = ptr;
temp->next = NULL;
if (ptr) {
ptr->next = temp;
}
ptr = temp;
if (!list) {
list = ptr;
}
count++;
cout << "Will more elements be added to the list?\n [Y or N]\n";
cin >> answer;
switch (answer) {
case 'y':
case 'Y':
break;
case 'n':
case 'N':
done = true;
break;
default:
break;
}
} while (!done);
int identifier = 100;
for (ptr = list; ptr; ptr = ptr->next) {
ptr->data.ID = identifier;
identifier++;
}
for (ptr = list; ptr; ptr = ptr->next) {
print(list);
}