linked list deletion algorithm - list

this program is used to delete a node from a linked list.It works fine but the thing is that it prints 0 instead of NOT printing the value of the deleted node.
For ex. If my list is 1-->2-->3-->-999.And I want to delete say 2. Then the final list is printed as 1-->0-->-->3-->-999.Why the 0???
enter code here
#include<stdio.h>
#include<malloc.h>
struct list {
int number;
struct list *next;
};
typedef struct list node;
void create(node *);
void print(node *);
node *delete(node *,int);
main() {
int key;
node *head;
head = (node *)malloc(sizeof(node));
create(head);
printf("Your list as you entered is....................\n");
print(head);
printf("Which element do you want to delete?\n ");
scanf("%d",&key);
head = delete(head,key);
printf("The new list is ..............................\n ");
print(head);
return 0;
}
void create(node *list) {
printf("Enter a number,-999 to stop data entrying\n");
scanf("%d",&list->number);
if(list->number == -999) {
list->next = NULL;
}
else {
list->next = (node *)malloc(sizeof(node));
create(list->next);
}
}
void print(node *list) {
if(list->number != -999) {
printf("%d-->",list->number);
print(list->next); }
else {
printf("%d",list->number);
}
}
node *delete(node *list,int key) {
node *prev_ptr = NULL;
node *curr_ptr;
for(curr_ptr=list;curr_ptr!=NULL;prev_ptr=curr_ptr,curr_ptr=curr_ptr->next) {
if(curr_ptr->number == key) {
break;
}
}
if(prev_ptr == NULL) {
list = curr_ptr->next;
}
else {
prev_ptr = curr_ptr->next;
}
free(curr_ptr);
return(list);
}

You have a mistake in rearranging the pointers in delete routine.
Instead of
...
else {
prev_ptr = curr_ptr->next;
}
...
You should have
...
else {
prev_ptr->next = curr_ptr->next;
}
...
The 0 is being shown because you free curr_ptr (thus it points to nowhere). But the real issue is you shouldn't have it in the list.

Related

Add integer to each item of unordered linked list

I want to write a function that adds an integer (passed as an argument to the function) to each item in the unordered linked list. Here is the complete program.
#include <iostream>
using namespace std;
//creates a node class
class Node {
//defines data, and next as a pointer.
private:
int data; //data in the beginning node
Node *next; //pointer to the next node
public:
Node(int initdata) {
data = initdata; //the initialized data is set as the head
next = NULL; //the next node is set as NULL, as there is no next node yet.
}
int getData() { //function that return data of a given node.
return data;
}
Node *getNext() { // pointer that gets the next node
return next;
}
void setData(int newData) { // sets data in node
data = newData;
}
void setNext(Node *newnext) {
next = newnext;
}
};
// creates unorderedlist that points to the head of the linked list
class UnorderedList {
public:
Node *head;
UnorderedList() { // makes the head node equal to null
head = NULL;
}
bool isEmpty() { // the head node is empty if it is null
return head == NULL;
}
void add(int item) { //cerates a "temp" pointer that adds the new node to the head of the list
Node *temp = new Node(item);
temp->setNext(head);
head = temp;
}
int size() { //cereates a "current" pointer that iterates through the list until it reaches null
Node *current = head;
int count = 0;
while (current != NULL) {
count++;
current = current->getNext();
}
return count;
}
// creates "current" pointer that iterates through the list
// untli it finds the item being searched for, and returns a boolean value
bool search(int item) {
Node *current = head;
while (current != NULL) {
if (current->getData() == item) {
return true;
} else {
current = current->getNext();
}
}
return false;
}
void addInteger(int item){
Node *current = head;
while (current != NULL) {
current->getData() = current->getData() + item;
}
}
// uses current and previous pointer to iterate through the lists
// finds the items that is searched for, and removes it
void remove(int item) {
Node *current = head;
Node *previous = NULL;
bool found = false;
while (!found) {
if (current->getData() == item) {
found = true;
} else {
previous = current;
current = current->getNext();
}
}
if (previous == NULL) {
head = current->getNext();
} else {
previous->setNext(current->getNext());
}
}
friend ostream& operator<<(ostream& os, const UnorderedList& ol);
};
ostream& operator<<(ostream& os, const UnorderedList& ol) {
Node *current = ol.head;
while (current != NULL) {
os<<current->getData()<<endl;
current = current->getNext();
}
return os;
}
int main() {
UnorderedList mylist;
mylist.add(1);
mylist.add(2);
mylist.add(3);
mylist.add(4);
mylist.add(5);
mylist.add(6);
cout<<"MY LIST: "<<endl<<mylist;
mylist.addInteger(5);
cout<<"=========================================================\n";
cout<<"After adding 5 to each element, the list now is\n";
cout<<"MY LIST: "<<endl<<mylist;
return 0;
}
Now the program shows an error in the following function from the program above regarding the assignment operation.
void addInteger(int item){
Node *current = head;
while (current != NULL) {
current->getData() = current->getData() + item;
}
}
How can I add a number to each element of the linked list?
Any help is appreciated.
You probably want something like the following:
current->setData(current->getData() + item);
Note that now you are retrieving a return value in the left-hand side, then trying to assign to it. This is what your compiler is telling you, presumably.

How to implement complete binary in c++?

I want to try make insertion of complete binary tree using recursion . I make a piece of code and I cannot catch problem why value not inserted. I make height function and count nodes function with help of these function and recursive call I want to insert new node in Complete binary tree. In main get root by using get root function then send to insert function
#include<iostream>
#include<math.h>
using namespace std;
struct node{
int data;
node *left,*right;
};
class cbt{
node *root;
public:
cbt()
{
root=NULL;
}
node* get_node()
{
return root;
}
node* newNode(int key)
{
node* temp1 = new node;
temp1->data = key;
temp1->left = temp1->right = NULL;
return temp1;
}
void CBT_inseration(node* temp,int data)
{
node *ptr;
ptr=newNode(data);
if(root==NULL)
{
root=ptr;
return;
}
else
{
height = f_height(temp->left);
int excepted_node = pow(2,height)-1;
int left_tree_node_count = countNumNodes(temp->left);
int right_tree_node_count = countNumNodes(temp->right);
if(left_tree_node_count==right_tree_node_count)
{
CBT_inseration(temp->left,data);
}
else if(excepted_node != left_tree_node_count)
{
if(temp->left == NULL)
{
temp->left = ptr;
return;
}else
{
CBT_inseration(temp->left,data);
}
}
else if(temp->right == NULL)
{
temp->right=ptr;
return;
}
else if(excepted_node != left_tree_node_count)
{
if(temp->left == NULL)
{
temp->left=ptr;
return;
}
else
{
CBT_inseration(temp->right,data);
}
}
}
}
void print(node *root) {
if (root == NULL)
return;
print(root->left);
cout << root->data << " ";
print(root->right);
}
};
int main()
{
cbt obj;
node *r=NULL;
obj.CBT_inseration(obj.get_node(),4);
obj.CBT_inseration(obj.get_node(),3);
obj.CBT_inseration(obj.get_node(),5);
obj.CBT_inseration(obj.get_node(),8);
obj.print(obj.get_node());
return 0;
}
You would need to go through a debugger to see what is wrong with your code. I will tell you how I would do this:
First, you need a function to check if the tree is full. We will reuse your functions to do this:
bool isTreeFull(node* head) {
return head != NULL && countNumNodes(head) == (1 << find_height(head)) - 1;
}
Then for inserting I have to check if the number of nodes on each side are the same. This tells me that I am allowed to move one level deeper on the left side. If the number of nodes aren't the same, then I only move on to insert on the right subtree if the left subtree is full:
void CBT_inseration(int data) {
root = insert(root, data);
}
node* insert(node* head, int data) {
if (head == NULL) {
head = newNode(data);
} else {
int leftCount = countNumNodes(head->left);
int rightCount = countNumNodes(head->right);
if (leftCount == rightCount) {
head->left = insert(head->left, data);
} else {
if (isTreeFull(head->left)) {
head->right = insert(head->right, data);
} else {
head->left = insert(head->left, data);
}
}
}
return head;
}
Then you would call it like:
cbt obj;
obj.CBT_inseration(4);
obj.CBT_inseration(3);
obj.CBT_inseration(5);
obj.CBT_inseration(6);
obj.CBT_inseration(8);
obj.print(obj.get_node()); // 6 3 8 4 5

Traversal pointer in tree while insertion

#include<iostream>
using namespace std;
struct node
{
int data;
node *right;
node *left;
} ;
node *root = NULL;
node *right = NULL;
node *left = NULL;
node insert(int data)
{
node *ptr = new node;
ptr->data = data;
ptr->left = NULL;
ptr->right = NULL;
if(root==NULL)
{
root = ptr;
cout<<"Inserted "<<root->data<<" at root\n";
}
else
{
node *pos = root;
while(pos)
{
cout<<pos->data<<" pos->data\n";
if(pos->data > data)
{
cout<<pos->data<<": data\n";
pos = pos->left;
}
else if(pos->data < data)
{
cout<<pos->data<<": data\n";
pos = pos->right;
}
if(!pos)
cout<<"NULL\n";
}
pos = ptr;
cout<<"Inserted\n";
}
return *root;
}
void preorder(node *root)
{
if(root)
{
cout<<root->data;
preorder(root->left);
preorder(root->right);
}
}
int main()
{
insert(2);
insert(1);
insert(3);
insert(4);
insert(5);
preorder(root);
return 0;
}
Here, while inserting the new element, I am pointing root to new variable pos so that root is unaltered so that it becomes parameter to the function preorder() properly as it is the actual root
But, pos isn't inserting all the elements and also not displaying the required results. In short I have to use root instead of pos to insert, but using root directly is altering the 'actual' root (which in this case is 2).
But, pos isn't inserting all the elements and also not displaying the required results.
I think there are mainly two bugs.
root is never updated in the current insert function because ptr is just only assigned to a temporal variable pos after while loop finished.
We should consider the case that the value of the passed argument data is already saved in the binary tree.
In addition, preorder is displaying the root again and again is confusing.
An example of fixing the insert and preorder is following one.
DEMO is here.
node insert(int data)
{
node *ptr = new node;
ptr->data = data;
ptr->left = nullptr;
ptr->right = nullptr;
if(!root)
{
root = ptr;
}
else
{
node *pos = root;
while(true)
{
if(pos->data > data)
{
if(!pos->left){
pos->left = ptr;
break;
}
pos = pos->left;
}
else if(pos->data < data)
{
if(!pos->right){
pos->right = ptr;
break;
}
pos = pos->right;
}
else{
break;
}
}
}
return *root;
}
void preorder(node *next)
{
if(next)
{
cout << next->data << std::endl;
preorder(next->left);
preorder(next->right);
}
}

Binary Search Tree Using Classes

I have been trying to implement binary search tree using classes. Every time I try to compile and run the program, the program ends. I have tried many things like making the *root public to access it in main so I can update the root, but somehow it becomes null every time.
Help will be appreciated.
This is for my university project.
#include <iostream>
using namespace std;
class tree;
class Node {
friend class tree;
private:
Node *lchild,*rchild;
int data;
public:
Node (int x) {
data = x;
lchild = rchild = NULL;
}
};
class tree {
protected:
Node* root;
void inorder(const Node* root)const;
public:
tree () {
root = NULL;
}
bool insert(int item);
void inorder() const {inorder(root);};
Node* getroot() {
return root;
}
};
bool tree :: insert(int item) {
if (root == NULL) {
Node *temp = new Node(item);
root = temp;
return (bool) root;
}
if (item < root -> data) {
insert(item);
}
if (item > root -> data) {
insert(item);
}
else if (item == root -> data) {
cout<<"Duplicate";
exit (0);
}
return (bool) root;
}
void tree :: inorder(const Node *root)const {
if (root != NULL) {
inorder(root -> lchild);
cout<<root -> data;
inorder(root -> rchild);
}
}
int main()
{
tree obj1;
obj1.insert(3);
//obj1.insert(4);
obj1.insert(1);
//obj1.insert(5);
obj1.inorder();
}
/* Program to implement Binary Search Tree in c++ using classes and objects */
#include<iostream>
#include<stdlib.h>
#include<cstdlib>
using namespace std;
struct Node {
int data;
Node* left;
Node* right;
};
class BinaryTree {
private:
struct Node* root;
public:
BinaryTree() {
root = NULL;
}
Node* createNode(int);
Node* insertNode(Node*, int);
Node* deleteNode(Node*, int);
void inOrder(Node*);
void preOrder(Node*);
void postOrder(Node*);
Node* findMinimum(Node*);
/* accessor function helps to
get the root node in main function
because root is private data member direct access is not possible */
Node* getRoot() {
return root;
}
/* mutator method helps to update root ptr after insertion
root is not directly updatable in the main because its private data member */
void setRoot(Node* ptr) {
root = ptr;
}
};
/* Helper function to create a new node in each function call of insertNode */
Node* BinaryTree :: createNode(int n) {
Node* newNode = new struct Node();
newNode->data = n;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
/* Helps to get inorder predessor to delete the node from tree */
Node* BinaryTree :: findMinimum(Node* rootPtr) {
while(rootPtr->left != NULL) {
rootPtr = rootPtr->left;
}
return rootPtr;
}
/* insertion of the Node */
Node* BinaryTree :: insertNode(Node* rootPtr, int n) {
if(rootPtr == NULL) {
return createNode(n);
}
if(n < rootPtr->data) {
rootPtr->left = insertNode(rootPtr->left, n);
}
if(n > rootPtr->data) {
rootPtr->right = insertNode(rootPtr->right, n);
}
return rootPtr;
}
/* function to delete the Node */
Node* BinaryTree :: deleteNode(Node* rootPtr, int n) {
if(rootPtr == NULL) {
cout<<"Node to be deleted is not present.!"<<endl;
return rootPtr;
}
else if(n < rootPtr->data) {
rootPtr->left = deleteNode(rootPtr->left, n);
} else if(n > rootPtr->data) {
rootPtr->right = deleteNode(rootPtr->right, n);
} else {
if(rootPtr->left == NULL && rootPtr->right == NULL) {
delete rootPtr;
rootPtr = NULL;
}
else if(root->left == NULL) {
struct Node* temp = rootPtr;
rootPtr = rootPtr->right;
delete temp;
}
else if(rootPtr->right == NULL) {
struct Node* temp = rootPtr;
rootPtr = rootPtr->left;
delete temp;
} else {
Node* temp = findMinimum(rootPtr->right);
rootPtr->data = temp->data;
rootPtr->left = deleteNode(rootPtr->right, temp->data);
}
}
return rootPtr;
}
/* all traversal technique */
void BinaryTree :: inOrder(Node* root) {
if(root == NULL) {
return;
}
inOrder(root->left);
cout<<root->data<<"\t";
inOrder(root->right);
}
void BinaryTree :: preOrder(Node* root) {
if(root == NULL) return;
cout<<root->data<<"\t";
preOrder(root->left);
preOrder(root->right);
}
void BinaryTree :: postOrder(Node* root) {
if(root == NULL) return;
postOrder(root->left);
postOrder(root->right);
cout<<root->data<<"\t";
}
int main() {
BinaryTree l1;
int ch, ele, res;
Node* ptr;
do {
cout<<"1 - Insert Node\n";
cout<<"2 - IN-ORDER Traversal\n";
cout<<"3 - PRE-ORDER Traversal\n";
cout<<"4 - POST-ORDER Traversal\n";
cout<<"Enter choice\n";
cin>>ch;
switch(ch) {
case 1:
cout<<"Entre element to insert to the List\n";
cin>>ele;
/* calling insertNode function by passing root ptr to the function,
root ptr can be obtained by accessor function getRoot() */
ptr = l1.insertNode(l1.getRoot(), ele);
/* updating the root ptr*/
l1.setRoot(ptr);
break;
case 2:
cout<<"---IN-ORDER TRAVERSAL---"<<endl;
l1.inOrder(l1.getRoot());
cout<<endl;
break;
case 3:
cout<<"---PRE-ORDER TRAVERSAL---"<<endl;
l1.preOrder(l1.getRoot());
cout<<endl;
break;
case 4:
cout<<"---POST-ORDER TRAVERSAL---"<<endl;
l1.postOrder(l1.getRoot());
cout<<endl;
break;
case 5:
cout<<"Enter node to be deleted."<<endl;
cin>>ele;
ptr = l1.deleteNode(l1.getRoot(), ele);
l1.setRoot(ptr);
default: cout<<"Invalid choice"<<endl;
}
} while(ch >=1 && ch <= 5);
return 0;
}
The reason why root gets NULL again and again is that it actually never changes its value to something else than NULL.
Maybe you have introduced this behaviour in your code in the course of fixing some other issues; yet you assign root=NULL in the constructor; afterwards, you assign only obj.root1 = ..., while you return root in getroot() { return root; }. Further, you pass Node *root as parameter in you insert function; Note that this local variable named root hides data member root, such that root->... in these functions will always address the local variable and not the data member.
Before diving around in code that's interface needs a redesign, I'd suggest to adapt the design and then adapt the code; I'm pretty sure the errors will simply go away. I'd suggest to adapt the interface of class tree as follows and write the code around it.
Member function inorder() should be const to indicate that it does not alter the object's state. Note that const-member functions can - in contrast to other non-static member functions - be called on const-objects.
class Node {
friend class tree;
private:
Node *lchild,*rchild;
int data;
public:
Node (int x) {
data = x;
lchild = rchild = NULL;
}
};
class tree {
public:
tree () { root = NULL; }
bool insert(int item) { return insert(item,root); };
void inorder() const { inorder(root);};
protected:
Node* root;
void inorder(const Node* curr) const;
bool insert(int item, Node* curr);
};
bool tree :: insert(int item, Node *currNode) {
if (root == NULL) {
root = new Node(item);
return true;
}
else if (item < currNode->data) {
if (currNode->lchild == NULL) {
currNode->lchild = new Node(item);
return true;
}
else {
return insert(item, currNode->lchild);
}
}
else if (item > currNode->data) {
if (currNode->rchild == NULL) {
currNode->rchild = new Node(item);
return true;
}
else {
return insert(item, currNode->rchild);
}
}
else // item == currNode->data
return false; // duplicate; do not insert
}
The biggest problem with your code are the following lines:
if (item < root -> data) {
insert(item);
}
if (item > root -> data) {
insert(item);
}
Basically you are saying that if the item is larger or smaller than the root data you will call the function again with the same item, you never changed the item and you will basically do this an infinity amount of times.....

I'm having trouble with cpp code to insert elements in a binary tree

I've tried this way to insert elements in a binary tree in code blocks. The program got compiled but got a run time error and the program stopped running. Could some one please help me out in this issue.
Thanks in advance.
#include <iostream>
#include <cstdlib>
using namespace std;
class bst;
class node
{
public:
int data;
node *lc;
node *rc;
};
class bst
{
public:
node *root;
bst()
{
root = NULL;
}
void search(int, node **, node **);
void insert(int);
void display(node *, int);
};
void bst::search(int item, node **par, node **loc)
{
node *current;
node *ptr;
if(root == NULL)
{
*par = NULL;
*loc = NULL;
return;
}
if(item == root->data)
{
*par = NULL;
*loc = root;
return;
}
if(item < root->data)
current = root->lc;
else
current = root->rc;
ptr = root;
while(current != NULL)
{
if(item == current->data)
{
*par = ptr;
*loc = current;
return;
}
ptr = current;
if(item < current->data)
current = current->lc;
else
current = current->rc;
}
*par = current;
*loc = NULL;
}
void bst::insert(int item)
{
node *parent;
node *location;
node *temp;
search(item, &parent, &location);
temp = new node;
temp->data = item;
temp->lc = NULL;
temp->rc = NULL;
if(item < parent->data)
parent->lc = temp;
else
parent->rc = temp;
}
void bst::display(node *ptr, int level)
{
if(ptr != NULL)
{
display(ptr->rc, level+1);
cout<<"\n";
for(int i=0;i<level;i++)
cout<<" ";
cout<<ptr->data;
display(ptr->lc, level+1);
}
}
int main()
{
int ch, num;
bst b;
while(1)
{
cout<<"1. INSERT ; 2. DISPLAY ; 3. EXIT "<<endl;
cout<<"Enter your choice"<<endl;
cin>>ch;
switch(ch)
{
case 1: cout<<"Enter the number to insert"<<endl;
cin>>num;
b.insert(num);
break;
case 2: b.display(b.root, 1);
break;
case 3: exit(0);
}
}
return 0;
}
In this line search(item, &parent, &location); you are calling the function search with arguments of types int, node** and node**. It in fact expects int, node* and node*. You should change the function declaration to search(int, node**, node**).