Why does the above error occur when calling showNode()?
#include<iostream>
#define NULL 0
using namespace std;
class myNode{
private:
int data;
myNode* link;
myNode* first;
public:
myNode(){
data=0;
link=NULL;
first=NULL;
}
void insertNode(int value, int iposition){
myNode n;
if (iposition==1)
{
first=&n;
cout<<first<<endl;
n.data=value;
n.link=NULL;
}
if (iposition>1)
{
int nodeCounter=1;
myNode* temp=first;
while (temp->link != NULL)
{
nodeCounter++;
}// this while counts the number of inserted nodes.
if (iposition>nodeCounter)//if the position of the new node is greater than number of inserted node,
//it will be inserted at the end.
{
cout<<"Node will be inserted at end."<<endl;
myNode* ieTemp=first;
while (ieTemp->link != NULL)
{
ieTemp=ieTemp->link;
cout<<ieTemp->data<<endl;
}
ieTemp->link=&n;
n.data=value;
n.link=NULL;
cout<<&n<<" ";
}
else
{
myNode* imTemp=first;
while (iposition-1)
{
imTemp=imTemp->link;
iposition--;
}
n.link=imTemp->link;
n.data=value;
imTemp->link=&n;
}
}
}//end insertNode
void showNode(){
myNode* sTemp=first;
while (sTemp != NULL)
{
cout<<sTemp->data<<" ";
sTemp=sTemp->link;
}
}//end showNode
};
int main(){
myNode a;
a.insertNode(10,1);
a.insertNode(20,2);
a.insertNode(25,3);
a.insertNode(30,4);
a.insertNode(40,5);
a.showNode();
system("pause");
}
First you must declare myNode *n = new myNode(); because you use it outside of insertNode function. Second you may want to check if first node exist to avoid error on inserting first node on any other position than 1 (in your case if your first insert will be like inserNode(x, y != 1) will throw an error because you try to access first node (here: while (temp->link != NULL))) but this node don't exist.
This is what I think you want:
void insertNode(int value, int iposition){
myNode *n = new myNode();
myNode *cur = first;
//insert first node or on first position
if (cur == NULL || iposition <= 1) {
n->data = value;
if (cur == NULL) { //first node
n->link = NULL;
}
else { //first position
n->link = first;
}
first = n;
return;
}
for (int i = 1; i < iposition - 1; i++) { //find given position
if (cur->link == NULL) { //if end
n->data = value;
n->link = NULL;
cur->link = n;
return;
}
cur = cur->link;
}
//here we are on position = iposition-1
n->data = value;
n->link = cur->link;
cur->link = n;
}//end insertNode
Related
I have a little problem which occurs after trying to execute function delete_all(). Any idea why Visual Studio is throwing me an error:
Invalid address specified to RtlValidateHeap, instruction __debugbreak() or something similar
Everything works perfect until I want to execute this function.
#include <iostream>
using namespace std;
struct node {
string name = "n1";
node* prev = NULL;
node* next = NULL;
};
node* add(node* first, string name) {
if (first == NULL) {
return NULL;
}
node* nowy = new node;
if (first->next == NULL) {
nowy->prev = first;
first->next = nowy;
}
else {
while (first->next != NULL) {
first = first->next;
}
nowy->prev = first;
first->next = nowy;
}
nowy->name = name;
return nowy;
}
void writeout(node* first) {
if (first == NULL) cout << "first = NULL";
while (first->next != NULL) {
cout << first->name;
cout << "\n";
first = first->next;
}
if (first->next == NULL) {
cout << first->name;
cout << "\n";
}
}
void delete_all(node* first) {
node* temp;
while (first != NULL) {
temp = first->next;
delete first;
first = temp;
}
}
int main()
{
node n1;
add(&n1, "n2");
add(&n1, "n3");
writeout(&n1);
delete_all(&n1);
}
You declared an object in main() with automatic storage duration as the first node of the list:
node n1;
You may not destroy it using the delete operator.
Using your approach of the list implementation, you could define the function delete_all() the following way:
void delete_all(node* first)
{
if ( first != nullptr )
{
while ( first->next != nullptr )
{
node *temp = first->next;
first->next = temp->next;
delete temp;
}
}
}
But, it will be much better if initially in main(), you declared a pointer to a node. In this case, you will need to update the functions.
Your implementation of delete_all() is fine, but you are passing it a pointer to a node instance that was not created with new, so delete'ing that node is undefined behavior. ALL of your node instances should be created dynamically, including the 1st node.
As such, your add() function should be updated to not blindly return without creating a new node instance if first is initially NULL. You should instead update the caller's node* pointer to point at the new node that was created.
Also, writout() has undefined behavior if first is NULL, because you are unconditionally accessing first->next whether first is NULL or not.
With that said, try something more like this instead:
#include <iostream>
using namespace std;
struct node {
string name = "n1";
node* prev = nullptr;
node* next = nullptr;
};
node* add(node* &first, string name) {
if (!first) {
first = new node{name};
return first;
}
else {
node *prev = first;
while (prev->next) {
prev = prev->next;
}
prev->next = new node{name, prev};
return prev->next;
}
}
/* alternatively:
node* add(node* &first, string name) {
node **nowy = &first, *prev = nullptr;
while (*nowy) {
prev = *nowy;
nowy = &(prev->next);
}
*nowy = new node{name, prev};
return *nowy;
}
*/
void writeout(node* first) {
if (!first) {
cout << "first = NULL";
}
else {
do {
cout << first->name;
first = first->next;
if (first) cout << '\n';
}
while (first);
}
}
void delete_all(node* first) {
node* temp;
while (first) {
temp = first->next;
delete first;
first = temp;
}
}
int main()
{
node* n1 = nullptr;
add(n1, "n2");
add(n1, "n3");
writeout(n1);
delete_all(n1);
}
Alternatively:
...
node* add(node* first, string name) {
if (!first) {
return new node{name};
}
else {
while (first->next) {
first = first->next;
}
first->next = new node{name, first};
return first->next;
}
}
/* alternatively
node* add(node* first, string name) {
// same as node** further above ...
}
*/
...
int main()
{
node* n1 = add(nullptr, "n2");
add(n1, "n3");
...
delete_all(n1);
}
Please help me find what is wrong with my code
(1).
You are given a Singly Linked List with N nodes where each node next pointing to its next node. You are also given M random pointers , where you will be given M number of pairs denoting two nodes a and b i.e. a->arb = b.
The task is to complete the function copyList() which takes one argument the head of the linked list to be cloned and should return the head of the cloned linked list.
NOTE : If their is any node whose arbitrary pointer is not given then its by default null.
I tried to write code for the above problem..but it is not working
// { Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *next;
Node *arb;
Node(int x) {
data = x;
next = NULL;
arb = NULL;
}
};
void print(Node *root) {
Node *temp = root;
while (temp != NULL) {
int k;
if (temp->arb == NULL)
k = -1;
else
k = temp->arb->data;
cout << temp->data << " " << k << " ";
temp = temp->next;
}
}
Node *copyList(Node *head);
void append(Node **head_ref, Node **tail_ref, int new_data) {
Node *new_node = new Node(new_data);
if (*head_ref == NULL) {
*head_ref = new_node;
} else
(*tail_ref)->next = new_node;
*tail_ref = new_node;
}
bool validation(Node *head, Node *res, Node *cloned_addr,
Node *generated_addr) {
if (generated_addr == cloned_addr) return false;
Node *temp1 = head;
Node *temp2 = res;
int len1 = 0, len2 = 0;
while (temp1 != NULL) {
len1++;
temp1 = temp1->next;
}
while (temp2 != NULL) {
len2++;
temp2 = temp2->next;
}
/*if lengths not equal */
if (len1 != len2) return false;
temp1 = head;
temp2 = res;
while (temp1 != NULL) {
if (temp1->data != temp2->data) return false;
if (temp1->arb != NULL and temp2->arb != NULL) {
if (temp1->arb->data != temp2->arb->data) return false;
} else if (temp1->arb != NULL and temp2->arb == NULL)
return false;
else if (temp1->arb == NULL and temp2->arb != NULL)
return false;
temp1 = temp1->next;
temp2 = temp2->next;
}
return true;
}
/* Driver program to test above function*/
int main() {
int T, i, n, l, k;
Node *generated_addr = NULL;
/*reading input stuff*/
cin >> T;
while (T--) {
generated_addr = NULL;
struct Node *head = NULL, *tail = NULL;
cin >> n >> k;
for (i = 1; i <= n; i++) {
cin >> l;
append(&head, &tail, l);
}
for (int i = 0; i < k; i++) {
int a, b;
cin >> a >> b;
Node *tempA = head;
int count = -1;
while (tempA != NULL) {
count++;
if (count == a - 1) break;
tempA = tempA->next;
}
Node *tempB = head;
count = -1;
while (tempB != NULL) {
count++;
if (count == b - 1) break;
tempB = tempB->next;
}
// when both a is greater than N
if (a <= n) tempA->arb = tempB;
}
/*read finished*/
generated_addr = head;
Node *res = copyList(head);
Node *cloned_addr = res;
cout << validation(head, res, cloned_addr, generated_addr) << endl;
}
return 0;
}
// } Driver Code Ends
/* the node structure is as follows
struct Node {
int data;
Node *next;
Node *arb;
Node(int x) {
data = x;
next = NULL;
arb = NULL;
}
};
*/
// Should return the head of the copied linked list the
// output will be 1 if successfully copied
Node *copyList(Node *head) {
if(!head)
return nullptr;
Node*q=head;
Node*clone=new Node(q->data);
clone->next=0;
clone->arb=q->arb;
Node*p=clone;
Node*r=q;
q=q->next;
while(q)
{
r->next=p;
p->next=new Node(q->data);
p=p->next;
p->next=0;
p->arb=q->arb;
r=q;
q=q->next;
}
r->next=p;
p=clone;
while(p)
{
if(p->arb)
p->arb=p->arb->next;
p=p->next;
}
return clone;
}
The pointers inside the list cannot be assigned until you have constructed the cloned list itself, because until then the nodes to point will not exist.
Therefore, you need two iterations: the first one to clone the list and make a dictionary that associates the original node with the clone, and the second one to update the pointers. The code would look like this:
Node *copyList(Node *head) {
if(!head)
return nullptr;
Node* it1 = head;
Node* clone = new Node;
Node* it2 = clone;
std::map<Node*, Node*> nodeDict;
nodeDict[nullptr] = nullptr;
// first iteration: create the list and the values
while(it1){
it2->data = it1->data;
nodeDict[it1] = it2;
it1 = it1->next;
it2->next = it1 ? new Node: nullptr;
it2 = it2->next;
}
// second iteration: connect the nodes
it1 = head;
it2 = clone;
while(it1){
it2->arb = nodeDict[it1->arb];
it1 = it1->next;
it2 = it2->next;
}
return clone;
}
I am trying to write a function find(Node* node, int valueInput) that starts at the given node and returns the index of the node with the value valueInput, and return -1 if valueInput does not exist.
Here is the code
#include <iostream>
class Node {
public:
int value;
Node* next = NULL;
};
int find(Node* node, int valueInput)
{
Node* tempNode = node;
int count = 0;
while (tempNode != NULL)
{
if (tempNode->value == 0)
{
break;
}
++count;
tempNode = tempNode->next;
}
return -1;
}
int main()
{
int valueInput, currentValue;
int listValues;
char arrow;
Node* node1, * previous, * head;
std::cin >> valueInput;
std::cin >> currentValue;
node1 = new Node();
node1->value = currentValue;
node1->next = NULL;
previous = node1;
head = node1;
while (std::cin)
{
std::cin >> arrow;
std::cin >> arrow;
std::cin >> currentValue;
node1 = new Node();
node1->value = currentValue;
previous->next = node1;
previous = node1;
}
std::cout << find(head, valueInput);
}
Currently, my program returns -1 always
Sample input and outputs:
Sample Input:
5
1->2->5
Sample Output:
2
That's because your code only has a return -1 statement. You should return count instead of break. Also, you are always comparing against 0 instead of the valueInput
int find(Node* node, int valueInput)
{
Node* tempNode = node;
int count = 0;
while (tempNode != nullptr)
{
if (tempNode->value == valueInput)
{
return count;
}
++count;
tempNode = tempNode->next;
}
return -1;
}
You should also be using nullptr instead of NULL
Notice the //, the program stops taking input and that is the main problem.
root->cand = data;
Here is the full code:
#include <bits/stdc++.h>
using namespace std;
struct node
{
int cand;
node *left;
node *right;
};
class candies
{
node *root;
public:
candies();
int add(int);
int check();
};
candies::candies()
{
root = NULL;
}
int candies::add(int data)
{
if (root == NULL)
{
root->cand = data; //code stops here
root->left = NULL;
root->right = NULL;
}
else
{
node *temp = root;
while (temp != NULL)
{
if (data < temp->cand)
{
temp = temp->left;
}
else
{
temp = temp->right;
}
}
temp = new node;
temp->cand = data;
temp->left = temp->right = NULL;
}
return 1;
}
int candies::check()
{
node *temp;
temp = root;
int data;
cin >> data;
while (temp != NULL)
{
if (temp->cand == data)
{
cout << "YES\n";
return 1;
}
else if (data < temp->cand)
temp = temp->left;
else if (data > temp->cand)
temp = temp->right;
}
cout << "NO\n";
return 0;
}
int main()
{
candies c;
int n;
cin >> n;
while (n--)
{
int data;
cin >> data;
c.add(data);
}
c.check();
}
The member function add is invalid and moreover has undefined behavior.
In this if statement
if (root == NULL)
{
root->cand = data; //code stops here
root->left = NULL;
root->right = NULL;
}
there is used a null-pointer to access memory.
In this else statement
else
{
node *temp = root;
while (temp != NULL)
{
if (data < temp->cand)
{
temp = temp->left;
}
else
{
temp = temp->right;
}
}
temp = new node;
temp->cand = data;
temp->left = temp->right = NULL;
}
the created node temp is not added to the tree. So the program has a memory leak.
The function can be written the following way. It is better to make its return type void. Otherwise the returned value 1 as in your function implementation does not make sense.
class candies
{
node *root;
public:
candies();
void add(int);
int check();
};
//...
void candies::add( int data )
{
node **current = &root;
while ( *current != nullptr )
{
if ( data < ( *current )->cand )
{
current = &( *current )->left;
}
else
{
current = &( *current )->right;
}
}
*current = new node { data, nullptr, nullptr };
}
You are first checking that root is NULL. If it is, you are changing its data. This is not good at all, and will cause a crash.
if (root == NULL)
{
root->cand = data; //code stops here
If root is NULL, you must create a root node first.
if ( root == nullptr ) {
root = new node;
root->cand = data;
I'm writing a function that counts the leaf nodes of a height balanced tree using struct and pointers. The function takes 3 arguments: the tree, pointer to an array and the maximum depth of the tree. The length of the array is the maximum depth. When function is called the array is initialized to zero. The function recursively follows the tree structure,
keeping track of the depth, and increments the right counter whenever it reaches a leaf. The function does not follow any pointer deeper than maxdepth. The function returns 0 if there was no leaf at depth greater than maxdepth, and 1 if there was some pointer togreater depth. What is wrong with my code. Thanks.
typedef int object;
typedef int key;
typedef struct tree_struct { key key;
struct tree_struct *left;
struct tree_struct *right;
int height;
} tree_n;
int count_d (tree_n *tr, int *count, int mdepth)
{
tree_n *tmp;
int i;
if (*(count + 0) == NULL){
for (i =0; i<mdepth; i++){
*(count + i) = 0;
}
}
while (medepth != 0)
{
if (tr == NULL) return;
else if ( tree-> left == NULL || tree->right == NULL){
return (0);
}
else {
tmp = tr;
*(count + 0) = 1;
int c = 1;
while(tmp->left != NULL && tmp->right != NULL){
if(tmp-> left){
*(count + c) = 2*c;
tmp = tmp->left;
return count_d(tmp, count , mdepth);
}
else if(tmp->right){
*(count + c + 1) = 2*c + 1;
tmp = tmp->right;
return count_d(tmp,count, mdepth);
}
c++;
mpth--;
}
}
}
What is wrong with my code
One thing I noticed is that you are missing return in the recursive calls.
return count_d(tmp, count , mdepth);
// ^^^ Missing
There are two such calls. Make sure to add return to both of them.
Disclaimer: Fixing this may not fix all your problems.
Correct Function To Insert,Count All Nodes and Count Leaf Nodes
#pragma once
typedef int itemtype;
#include<iostream>
typedef int itemtype;
#include<iostream>
#include<conio.h>
#include<string>
using namespace std;
class Node
{
public:
Node* left;
Node* right;
itemtype data;
};
class BT
{
private:
int count = 0;
Node* root;
void insert(itemtype d, Node* temp);//Override Function
public:
BT();//Constructor
bool isEmpty();
Node* newNode(itemtype d);
Node* getroot();
void insert(itemtype d);//Function to call in main
int countLeafNodes(Node * temp);
int countAllNodes();//to count all nodes
}
BT::BT()//constructor
{
root = NULL;
}
bool BT::isEmpty()
{
if (root == NULL)
return true;
else
return false;
}
Node* BT::newNode(itemtype d)
{
Node* n = new Node;
n->left = NULL;
n->data = d;
n->right = NULL;
return n;
}
void BT::insert(itemtype d)//Function to call in main
{
if (isEmpty())
{
Node* temp = newNode(d);
root = temp;
}
else
{
Node* temp = root;
insert(d, temp);
}
count++;//to count number of inserted nodes
}
void BT::insert(itemtype d, Node* temp)//Private Function which is overrided
{
if (d <= temp->data)
{
if (temp->left == NULL)
{
Node* n = newNode(d);
temp->left = n;
}
else
{
temp = temp->left;
insert(d, temp);
}
}
else
{
if (temp->right == NULL)
{
temp->right = newNode(d);
}
else
{
temp = temp->right;
insert(d, temp);
}
}
}
int BT::countAllNodes()
{ return count; }
int BT::countLeafNodes(Node* temp)
{
int leaf = 0;
if (temp == NULL)
return leaf;
if (temp->left == NULL && temp->right == NULL)
return ++leaf;
else
{
leaf = countLeafNodes(temp->left) + countLeafNodes(temp->right);
return leaf;
}
}
void main()
{
BT t;
t.insert(7);
t.insert(2);
t.insert(3);
t.insert(15);
t.insert(11);
t.insert(17);
t.insert(18);
cout<<"Total Number Of Nodes:" <<t.countAllNodes() <<endl;
cout << "Leaf Nodes:" << t.countLeafNodes(t.getroot()) << endl;
_getch();
}
Output:
Ouput