C++ insert and delete characters in a linked list - c++

My problem is that I'm trying to insert a letter into a linked list based on users input at a specific position given by the int h...However every time I run the program only the second character in the list changes regardless of the number the user puts into the program.
Example:
./h
Name: koala
a<-l<-a<-o<-k
Change the position: 2
To the character: 3
a<-l<-3<-o<-k
Insert the Character: F
To the Postion: 3
a<-F<-l<-3<-o<-k
I want it to look like.
./h
Name: koala
a<-l<-a<-o<-k
Change the position: 2
To the character: 3
a<-l<-3<-o<-k
Insert the Character: F
To the Postion: 3
a<-l<-3<-F<-o<-k
I know my problem is in the insert_char() function in my lists.cpp but just can't figure out what i'm doing wrong...
List.h
#include <iostream>
using namespace std;
struct Node;
Node* new_list();
void insert_front(Node** plist,char x);
void insert_char(Node* plist, char x, int p);
void change_char(Node* plist, char x, int p);
void print_list(Node* list);
void delete_front(Node** plist);
void delete_list(Node** plist);
//void delete_char(Node* plist,int p);
struct Node {
char x;
Node *next;
};
main.cpp
struct Node {
char x;
Node *next;
};
int main(){
Node *list;
list = new_list(); //new empty list
cout<<"Name: ";
string name;
cin>> name;
for (int i =0; i < name.length(); i++)
insert_front(&list, name[i]);
//---------print list-------------------------
print_list(list);
cout <<"Change the position: ";
int z;
cin>> z;
cout<< "To the character: " ;
char x;
cin>> x;
change_char(list, x, z);
print_list(list);
cout <<"Insert the Character: ";
char y;
cin>> y;
cout<< "To the Postion: ";
int h;
cin>> h;
insert_char(list, y, h);
print_list(list);
return 0;
}
lists.cpp
Node* new_list()
{
Node* list = 0; //in C++ it is better to use 0 than NULL
return list;
}
void insert_front(Node** plist,char x){
Node* t;
t = new Node;
t->x = x;
t->next = *plist;
*plist = t;
return;
}
void change_char(Node* plist, char x, int p)
{
Node* s = plist;
for (int i=1; i<p && 0!=s;i++)
s = s->next;
if (0 != s)
s->x = x;
return;
}
void insert_char(Node* plist, char x, int p){
Node* s = plist;
Node* a = new Node();
for (int i=1; i<p && s; i++)
a->next=s->next;
s->next=a;
if (0 !=s)
a->x=x;
return;
}
//void delete_char(Node* plist,int p)
void print_list(Node* list){
Node* p;
p = list;
if(p == 0)
cout << "--- empty list ---" << endl;
while(p !=0){
cout << p->x<<"<-";
p = p->next;
}
cout << endl;
}
void delete_front(Node** plist){
Node* t;
if( *plist != 0){ // list is not empty
t = (*plist);
*plist = (*plist)->next;
delete t;
}
}
void delete_list(Node** plist){
while(*plist != 0) //while list not empty
delete_front(plist);
}
bool is_empty(Node* list){
return (list == 0);
}

The for loop in insert_char is just "inserting" the character over and over. I think you meant to advance s to the starting point of the insertion (as determined by h).
Update:
This part is wrong for a few reasons:
for (int i=1; i<p && s; i++)
a->next=s->next;
s->next=a;
Note that the indentation is misleading. Since you don't have braces, only the middle line is part of the loop. Effectively, you've written:
for (int i=1; i<p && s; i++) {
a->next=s->next;
}
s->next=a;
Personally, I always use braces on blocks, even if they consist of only one statement.
So you set a->next a bunch of times instead of advancing to the point in the list you want to go.
You need to advance to the position you want the new element in the loop, and then do the actual insertion.
// Advance s to index p.
for (int i = 1; i < p && s->next; i++) {
s = s->next;
}
// Insert a at s.
a->next = s->next;
s->next = a;

Related

dynamically allocated struct array for open hash table

I am trying to implement a simple open hash in c++ for the sake of learning. I am getting very confused about the interaction of functions with array pointers, and I am at the end of my wits.
The code:
struct node{
int data;
node* next;
node* prev;
bool state;
node(){
prev = next = NULL;
state = true;
}
};
//state true means empty, state false means full.
void insert(node *array,int value){
node *current = array;
if(array->state == true){
array->data = value;
array->state = false;
} else {
node* add = new node();
add->data = value;
add->state = false;
while(current->next != NULL){
current = current->next;
}
current->next = add;
add->prev = current;
}
}
void display(node *array, int size){
node *show = new node();
for(int i = 0; i< size; i++){
if(array->state == false){
cout<<array->data;
show = array;
while(show->next != NULL){
show = show->next;
cout<<" --> "<<show->data;
}
} else {
cout<<"Empty.";
}
cout<<"\n\n";
}
}
int main(){
int size;
cout<<"Enter size of the hash table: ";
cin>>size;
node *array = new node[size];
int value;
cout<<"Enter Value: ";
cin>>value;
int index = value%size;
//inserting single value
insert(&array[index],value);
//Hash table output.
display(array,size);
return 0;
}
When I run this code, instead of showing "empty" in places where the array's state is empty, it seems as if the entire array has the same value. The problem lies in the insert function, but I cannot figure it out.
You can simplify this by making the Hashtable an array of pointers to Node. A nullptr then means the slot is empty and you don't have empty and full nodes. Also Nodes only need a next pointer and usually new entries are added to the beginning of the buckets instead of the end (allows duplicate entries to "replace" older ones). Inserting at the beginning of a list becomes real easy with Node **.
#include <cstddef>
#include <iostream>
struct Table {
struct Node {
Node * next;
int data;
Node(Node **prev, int data_) : next{*prev}, data{data_} {
*prev = this;
}
};
std::size_t size;
Node **tbl;
Table(std::size_t size_) : size{size_}, tbl{new Node*[size]} { }
~Table() {
for (std::size_t i = 0; i < size; ++i) {
Node *p = tbl[i];
while(p) {
Node *t = p->next;
delete p;
p = t;
}
}
delete[] tbl;
}
void insert(int value) {
Node **slot = &tbl[value % size];
new Node(slot, value);
}
void display() const {
for(std::size_t i = 0; i < size; i++) {
std::cout << "Slot " << i << ":";
for (const Node *node = tbl[i]; node; node = node->next) {
std::cout << " " << node->data;
}
std::cout << std::endl;
}
}
};
int main(){
std::size_t size;
std::cout << "Enter size of the hash table: ";
std::cin >> size;
Table table{size};
int value;
std::cout << "Enter Value: ";
std::cin >> value;
//inserting single value
table.insert(value);
//Hash table output.
table.display();
return 0;
}

How to pass values within functions in linked lists C++

I created this code to calculate the sum of the values in a linked list entered by the user, and the expected output is to print the sum but it gives the last value and prints the wrong number of records in linked list
Enter a number : 5
Enter [Y] to add another number : Y
Enter a number : 1
Enter [Y] to add another number : N
List of existing record : 5
1
My code is as below, however it does not print my expected output :
#include <iostream>
using namespace std;
class Node {
public:
int no;
Node* next; //missing code
};
Node* createNode(int num) {
Node* n = new Node();
n->no = num;
n->next = NULL;
return n;
}
void addValue(int no, Node** h) {
//insert first node into linked list
Node* y = createNode(no), * p = *h;
if (*h == NULL)
*h = y;
//insert second node onwards into linked list
else {
while (p->next != NULL) //while not the end
p = p->next; // go next
p->next = y;
}
}
void display(Node* x) {
while (x != NULL) {
cout << x->no << " " << endl;
x = x->next;
}
}
double sumNodes(Node** h) {
double* sum = 0;
Node* x = *h;
while (x != NULL) {
*sum += x->no;
x = x->next;
}
return *sum;
}
int main() {
int num = 0; char choice;
Node* head = NULL;
double s;
do {
cout << "Enter a number : ";
cin >> num;
addValue(num, &head);
cout << "Enter [Y] to add another number : ";
cin >> choice;
} while (choice == 'Y');
cout << "List of existing record : ";
display(head);
cout << endl << endl;
s = sumNodes(&head);
cout << "Sum = " << s << endl;
return 0;
}
In sumNodes(), you are declaring sum as a null pointer and then dereferencing it, which invokes undefined behavior.
double sumNodes(Node** h) {
double* sum = 0; // <-- null pointer
Node* x = *h;
while (x != NULL) {
*sum += x->no; // <-- dereference
x = x->next;
}
return *sum; // <-- dereference
}
There is no need to use a pointer at all. Instead, write:
double sumNodes( const Node** h) {
double sum = 0;
const Node* x = *h;
while (x != NULL) {
sum += x->no;
x = x->next;
}
return sum;
}
change double *sum to double sum, or better to int sum.

Reversing a specific part of singly Linked List i.e from m to n

How to make this code work for all values of m i.e m=any value from (1-10)
*
This code for reversing a specific part of linked list..This code is working but only for m<5.When we give value of m as 5 or greater than 5,it will goes into an infinite loop.I didn't get where this code goes wrong.
One extra help :-),Is it required to delete the complete linked list using delete() as like as i had done in destructor::as i didn't see anyone to do like this but i think its required to free heap memory.
*
#include<iostream>
using namespace std;
struct Node
{
int data;
Node *next=NULL;
};
class LinkedList
{
Node *first=NULL,*last=NULL;
int no_of_nodes=10;
public:
LinkedList(int[],int);
~LinkedList();
void display(void);
void reverse(int m,int n);
};
LinkedList::~LinkedList()
{
Node *p=NULL;
for(int i=0;i<no_of_nodes;i++)
{
p=first;
for(int j=0;j<no_of_nodes-i-1;j++)
{
if(p->next==last)
{
delete(p->next);
p->next=NULL;
last=p;
}
else
{
p=p->next;
}
}
}
delete(first);
}
void LinkedList::reverse(int m,int n)
{
Node *prev=NULL,*pointer_m=first,*pointer_n=first;
//Making pointer_m to point on m-th node
for(int i=1;i<m;i++)
{
prev=pointer_m;
pointer_m=pointer_m->next;
}
//Making pointer_n to point on n-th node
pointer_n=first;
for(int i=1;i<n;i++)
{
pointer_n=pointer_n->next;
}
// reversing the list part between m and n
Node *p=first->next,*q=first,*r=prev; // q and r are tailing pointers
while(q!= pointer_n && p)
{
r=q;
q=p;
p=p->next;
q->next=r;
}
//fixing pointers
prev->next=pointer_n;
pointer_m->next=p;
}
LinkedList::LinkedList(int arr[],int n)
{
first=new Node;
first->data=arr[0];
last=first;
for(int i=1;i<n;i++)
{
Node *temp=new Node;
temp->data=arr[i];
last->next=temp;
last=temp;
}
}
void LinkedList::display(void)
{
Node *p=first;
// cout<<"No.of nodes:: "<<no_of_nodes<<"\t\t";
cout<<"List is:: ";
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
int main(void)
{
int arr[]={2,4,6,8,10,12,14,16,18,20};
int n=sizeof(arr)/sizeof(arr[0]);
LinkedList list(arr,n);
list.display();
list.reverse(5,8);
list.display();
return 0;
}
The major error arised from the wrongly setting of the initial values for the three reversion variables `p, q, r`. The 3 node is runing through the reverse segment `(m -> n)`to set backward the linkage of nodes. The three should be start from `m` instead of the beginning.
// Reversing a specific part of singly Linked List i.e from m=3 to n=7
#include<iostream>
using namespace std;
struct Node
{
int data;
Node *next=NULL;
};
class LinkedList
{
Node *first=NULL,*last=NULL;
int no_of_nodes=10;
public:
LinkedList(int[],int);
~LinkedList();
void display(void);
void reverse(int m,int n);
};
LinkedList::~LinkedList()
{
Node *p=NULL;
for(int i=0;i<no_of_nodes;i++)
{
p=first;
for(int j=0;j<no_of_nodes-i-1;j++)
{
if(p->next==last)
{
delete &(p->next->data);
p->next=NULL;
last=p;
break;
}
else
{
p = p->next;
}
}
}
delete &(first->data);
first = NULL;
}
void LinkedList::reverse(int m,int n)
{
Node *prev_m, *pointer_m, *pointer_n;
if (n >= no_of_nodes) n = no_of_nodes - 1;
//Making pointer_m to point on m-th node
prev_m = first;
for(int i=1;i<m;i++) prev_m = prev_m->next;
pointer_m = prev_m->next;
//Making pointer_n to point on n-th node
pointer_n=first;
for(int i=0;i<n;i++) pointer_n = pointer_n->next;
// reversing the list part between m and n
Node *p, *q, *r;
r = pointer_m;
q = r->next;
p = q->next; // q and r are tailing pointers
q->next = r;
while(q!= pointer_n && p != last)
{
r = q;
q = p;
p = p->next;
q->next = r;
}
//fixing pointers
if(m!=1)
{
prev->next=pointer_n;
pointer_m->next=p;
}
else
{
first=pointer_n;
pointer_m->next=p;
}
}
LinkedList::LinkedList(int arr[],int n)
{
Node *temp;
first = new Node;
first->data = arr[0];
last = first;
for(int i=1 ;i<n; i++)
{
temp = new Node;
temp->data = arr[i];
last->next = temp;
last = temp;
}
no_of_nodes = n;
}
void LinkedList::display(void)
{
Node *p; p = first;
cout<<"List is:: ";
while(p != last)
{
cout<< (p->data) <<" ";
p = p->next;
}
cout<< last->data << endl;
}
int main(void)
{
int arr[]={2,4,6,8,10,12,14,16,18,20};
int n=sizeof(arr)/sizeof(arr[0]);
LinkedList list(arr,n);
list.display();
list.reverse(3,7);
list.display();
return 0;
}
A test run reverses the nodes from 3 to 7.
$ ./a.exe
List is:: 2 4 6 8 10 12 14 16 18 20
List is:: 2 4 6 16 14 12 10 8 18 20

Single Link List delete function in the middle issue

I look around for some help for single link list around the web but couldn't find the information I needed. What im trying to do is Design and Implement a single linked list with the following operations
a- Create "n" nodes
b- Delete from the middle (where im not deleting the middle, but anything else but the start and end node)
c- Insert in the middle
I did my "insert" part with a ADD function
but when I get to the delete function, im stuck in how to use a single link list & not a double, because Im trying to break that habit. Anyway here my code, it my delete function that im trying to fix. thanks
PS: tell me if my add function is also correct, :)
#include <iostream>
#include <vector>
using namespace std;
class node
{
public:
node(int user_input);
int info;
node * next_node;
};
node::node(int user_input)
{
info = user_input;
next_node = NULL;
}
class link_list
{
public:
node * start;
node * end;
int size;//seperated the attritibute from the method
link_list(); //default constuctor
link_list(int value); //value constuctor
link_list(int value, int num_of_Nodes); //n-ary
void Add(int store_node);
void Print(); //non midify
void insert_at_begining(int value); //while these guys are modify
void insert_at_end(int value); //
void insert_at_middle(int delete_node);
void delete_at_begining();
void delete_at_end(); //
void delete_at_middle(int Nodes_store);
private:
int Number_of_nodeV2;
};
link_list::link_list(int value, int num_of_Nodes) //this
{
//if val = 0 & num = 5 we get 5 new nodes
Number_of_nodeV2 = 0;
if (num_of_Nodes < 1)
{
cout << "error, please enter correct numbers" << endl;
}
else
{
start = new node(value); //this is pointing to node that has value in it.
//start == NULL;
node* tracker = start;
for (int i = 0; i < num_of_Nodes - 1; i++)
{
tracker->next_node = new node(value); //this track each node //-> de-renecen
tracker = tracker->next_node;
}
}
}
void link_list::Add(int store_node)
{
node* tracker = start;
node* newVal = new node(store_node);
while (tracker->next_node != NULL)
{
tracker = tracker->next_node;
}
tracker->next_node = newVal;
}
void link_list::Print()
{
node* tracker = start;
while (tracker != NULL)
{
cout << tracker->info << endl;
tracker = tracker->next_node;
cout << size;
}
}
void link_list::delete_at_middle(int delete_node)
{
//int center = 0;
node* tracker = start;
node* tracker2 = end;
node* temp;
node* temp1;
temp1 = temp = start;
if (start == NULL)
{
cout << "the list is empy" << endl;
}
else //this is where I cant seem to answer, thanks
{
while (temp != end)
{
temp = temp1->next_node;
if (temp->info = delete_node)
{
delete temp;
temp1->next_node = NULL; //ffffffffffff
}
}
tracker = tracker->next_node;
for (size_t i = 0; i < length; i++)
{
pre = start;
pre
}
//iltertae with tracker until the tracker has hit the center
}
}
int main() {
int Nodes_store = 0;
int delete_node = 0;
cout << "please enter the number of nodes" << endl;
cin >> Nodes_store;
cout << "please enter the number of to delete nodes" << endl;
cin >> delete_node;
link_list list = link_list(0, Nodes_store);
list.Print();
//list.delete_at_middle();
//list.Print();
//
//list.insert_at_middle(7);
//list.Print();
}AS'
;'

C++ - Inserting Linked list (A) into another Linked list (B) at position n

Example:
Linked List A: 1->2->3
Linked List B: 4->5->6
My task is to make a function, that passes List B into List A at any given position (n).
For instance: After "2" = 1->4->5->6->2->3 (output).
I wasn't really sure, how to do this, so I used:
// Function that finds a number in a list and gets an address of that node.
Node* List::find(int i)
{
for (start();!end();next())
if(current->num==i) return current;
return NULL;
};
// Function, that puts freely desired number at position n in the list;
Example cin >> i; // i = 6;
1->2->6->desired number->...
Node* List::addAfter(int pos, int num)
{
Node* p = NULL; i
current = find(pos);
if (current != NULL)
{
p = new Node(num);
p->next = current->next;
current->next = p;
}
if (last == current) last = p;
current = p;
return p;
}
Both things works, but only as:
cout << "After which number?" << endl;
cin >> i; // **2**
l.addAfter(i, 1); // Before: 2->3->4 After: 2->1->3->4
l.print();
This works perfectly! But if I have two lists - l1 (2->3->4 and l2 6->7)
how can I put both together using this function?
Node* List::addAfter(int pos, I HAVE TO PASS L2 VALUES HERE)
How can I give this function l2 values as parameter?
Is there maybe a better way, to do this? I'd appreciate any help.
WHOLE CODE:
#include <iostream>
using namespace std;
class Node
{
public:
int num;
Node *next;
Node (int n) { num = n; next = NULL; };
};
class List
{
protected:
Node *first, *last;
public:
Node *current;
public:
List () { first = last = current = NULL; };
void add_element (int n);
void delete_element ();
void print(); // Izdrukā sarakstu
bool is_empty () { return (first == NULL); };
void start () { current = first; };
bool end () { return (current == NULL); };
void next(){if (!end())current = current -> next;};
Node* find(int i);
Node* addAfter(int i, List * l2);
~List();
};
int main()
{
List l, l2;
int k, i;
cout << "Type number: (0,to stop):\n";
cin >> k;
while (k!=0)
{
l.add_element (k);
cout << "Type number: (0, to stop):\n";
cin >> k;
};
cout << endl;
cout << "Type 2nd list numbers: (0,to stop):\n";
cin >> k;
while (k!=0)
{
l2.add_element (k);
cout << "Type 2nd list numbers: (0,to stop):\n";
cin >> k;
};
cout << endl;
l.print();
l2.print();
cout << "After which element do you want to insert second list?" << endl;
cin >> i;
l.addAfter(i, l2); // GETTING ERROR HERE.
l.print();
return 0;
}
simplest and easiest form is to pour out both stacks into an array
const int size = stackA.size() + stackB.size();
const stackASize = stackA.size();
const stackBSize = stackB.size();
int arrayOfStackA [size];
int arrayOfStackB [stackBSize];
//Pop StackA into ArrayA
for(int i=stackASize-1; i>0; i++)
{
arrayOfStackA[i] = stackA.pop();
}
//Pop StackB into ArrayB
for(int i=stackBSize-1; i>=0; i++)
{
arrayOfStackB[i] = stackB.pop();
}
Now find the index where you want to insert the data in array A.
In your case you want to enter stack b after 1 which in case of array is the index:1
int count = 0
for(int i=0;i<size;i++){
if(i<requiredIndexNumber){
//do nothing
}
else if(i>=requiredIndexNumber && count!=stackBSize){
int temp = arrayOfStackA[i];
arrayOfStackA[i] = arrayOfStackB[count++];
arrayOfStackA[stackASize+i] = temp;
}
}
This is the most easiest from of popping one stack into an other at any index