I'm working on a doubly linked list and want to implement an insert() function at a given index. Right now I am able to traverse through the linked list with a for loop. However, I want execute the traversing with a while loop but I cant figure it out.
The for loop I am running is
for (int i = 0; i < index - 1; i++) {
//move the temp pointer down the list
temp = temp->next;
}
The full insert() function:
template<typename Data>
void Link<Data>::insert(int index, Data value) {
if (head == nullptr) {
Link<Data>::push2Front(value);
}
else if (index >= size) {
Link<Data>::add2Rear(value);
}
else {
Node* temp = head;
for (int i = 0; i < index - 1; i++) {
temp = temp->next;
}
Node* nn = new Node;
nn->value = value;
nn->next = temp->next;
nn->prev = temp->prev;
temp->next->prev = nn;
temp->next = nn;
size++;
}
}
Suggestions are much appreciated.
You can do it like this
int i=0;
while(i<index-1){
temp=temp->next;
++i;
}
Using a while loop instead is very easy, just decrement index until it reaches 0, eg:
template<typename Data>
void Link<Data>::insert(int index, Data value) {
if (index <= 0) {
Link<Data>::push2Front(value);
}
else if (index >= count) {
Link<Data>::add2Rear(value);
}
else {
Node* temp = head;
while (--index > 0) {
temp = temp->next;
}
Node* nn = new Node;
nn->value = value;
nn->next = temp->next;
nn->prev = temp;
if (temp->next) temp->next->prev = nn;
temp->next = nn;
++size;
}
}
That being said, the insert() code can be simplified a bit further:
template<typename Data>
void Link<Data>::insert(int index, Data value) {
if (index < 0 || index > size) {
throw std::out_of_range("");
}
Node** temp = &head;
Node* prev = nullptr;
while (index-- > 0) {
prev = *temp;
temp = &(prev->next);
}
Node* nn = new Node;
nn->value = value;
nn->next = *temp;
nn->prev = prev;
if (*temp) (*temp)->prev = nn;
*temp = nn;
++size;
}
Related
I want to use subscript operator overloading in linklist but everytime it give me Segmentation fault (core dumped) ERROR! MY TASK IS : (Overload [] operator. Use for loop in main to display it.) I ALSO PROVIDING THE TASK LINK BELOW
//task link
[LINK OF TASK] https://anonymfile.com/r1XKK/dsa-a3.pdf
//MY CODE IS :
#include <iostream>
using namespace std;
class LinkedList
{
private:
class Node
{
public:
int data;
Node * next;
Node(int data)
{
this->data = data;
this->next = NULL;
}
};
public:
Node *head;
LinkedList(){
head = NULL;
}
//Write a copy constructor. Also copy must be deep.
LinkedList(LinkedList& S)
{
head = S.head;
}
//Overload [] operator. Use for loop in main to display it.
void operator[](int i) {
head->data = i;
}
void InsertAtEnd(int data){
if (head == NULL)
{
head = new Node(data);
return;
}
Node * temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = new Node(data);
}
void Insert(int d1, int d2)//Add the node of data d2 after the node with data d1. If d2 is not available add it to the end.
{
if (head == NULL)
{
Node * n = new Node(d2);
n->next = head;
head = n;
return;
}
Node * temp = head;
while (temp != NULL)
{
if (temp->data == d1)
{
Node * temp1 = temp->next;
temp->next = new Node(d2);
temp->next->next = temp1;
}
temp = temp->next;
}
}
void Delete(int data){
Node * todelete;
if(head->data == data){
todelete = head;
head = head->next;
free(todelete);
return;
}
Node *temp = head;
while(temp->next != NULL){
if(temp->next->data == data){
todelete = temp->next;
temp->next = temp->next->next;
free(todelete);
break;
}
temp = temp->next;
}
} // Deletes a node with data.
int getSize(){
Node * temp = head;
int size = 0;
while(temp != NULL){
temp = temp->next;
size++;
}
return size;
} //returns the count of elements in the list
bool IsEmpty(){
if(head == NULL){
return true;
}
else{
return false;
}
} //Returns true if empty.
void Merge(Node * list){
//merge
Node * temp = head;
while(temp != NULL){
if(temp->next == NULL and list != NULL){
temp->next = list;
break;
}
temp = temp->next;
}
//DISPLAY
while(head!=NULL){
cout<<head->data<<"->";
head=head->next;
}
cout<<"NULL"<<endl;
} //Merges the to the calling class.
void Erase(){
Node * erase;
while(head!= NULL){
erase = head;
head = head->next;
head = NULL;
}
free(erase);
} //Deletes every node in an array.
void SelectiveErase(int num) //Find num and delete everything after num.
{
Node * temp = head;
Node * todelete;
while(temp != NULL){
if(temp->data == num){
Node * erase = temp->next;
while(temp->next != NULL){
erase = temp->next;
temp->next = temp->next->next;
temp->next = NULL;
}
free(erase);
break;
}
temp = temp->next;
}
}
int FindNCount(int find)//Find and return count of all occurrence.
{
int counter = 0;
bool flag = false;
Node * temp = head;
while(temp->data!= find){
temp = temp->next;
counter++;
}
return counter;
}
int RemoveDuplicate(int find)//Find and remove every duplicate element in the list. Make //elements unique.
{
Node * temp = head;
Node *temp1;
while(temp != NULL){
temp1 = temp;
while(temp1->next != NULL){
if(temp->data == temp1->next->data and temp->data == find and temp1->next->data == find){
Node *todelete = temp1->next;
temp1->next = temp1->next->next;
free(todelete);
}
else{
temp1 = temp1->next;
}
}
temp = temp->next;
}
return find;
}
void FindNReplace(int find, int data)//Find and replace all occurrence recursively.
{
Node * temp = head;
while(temp != NULL){
if(temp->data == find){
temp->data = data;
break;
}
temp = temp->next;
}
}
void Display(){
static Node * temp= head;
if(temp == NULL){ cout << "NULL" << endl; return;}
cout << temp->data<<"->";
temp = temp->next;
Display();
}
};
void Swap() // swap the contents of one list with another list of same type and size. Also write parameter
{
LinkedList L,L1;
cout<<"AFTER SWAPING THE VALUE OF FIRST LIST \n";
while(L.head != NULL && L1.head != NULL){
int temp = L.head->data;
L.head->data = L1.head->data;
L1.head->data = temp;
cout<<L.head->data<<"\n";
L.head = L.head->next;
L1.head = L1.head->next;
}
cout<<endl;
}
int main()
{
// You must call Display function after every function.
LinkedList L{};
L[23];
// LinkedList L1;
// L1.InsertAtEnd(5);
// L1.InsertAtEnd(6);
//L.Erase();
// cout<<L.FindNCount(1)<<endl;
//L.SelectiveErase(2);
//L.Display();
//L.Merge(L1.head);
//L.RemoveDuplicate(2);
//L.Display();
//Swap();
return 0;
}
Overloading the subscript operator should return something. The assignment looks a bit vague, but I hope this will fix it:
//Overload [] operator. Use for loop in main to display it.
Node* operator[](int i) {
Node* nodePtr = head;
int counter = 0;
while (nodePtr != NULL && counter != i) {
nodePtr = nodePtr->next;
counter++;
}
return nodePtr;
}
i have 2 doubly linked list within nodes, i compare data of nodes and if data of node of second list is bigger than data of node of first list, i will chande nodes. How can i do that.
this deletes old nodes and adds that given nodes.
void DoubleLinkedList::SwitchNodesFromList(Node* changeNode, int index)
{
RemoveAt(index);
if (index < 0 || index > size)
throw "Error";
if (index == 0)
{
head = changeNode;
if (head->next != NULL)
head->next->prev = head;
}
else
{
Node* prv = findPreviousByPosition(index);
prv->next = changeNode;
if (prv->next->next != NULL)
prv->next->next->prev = prv->next;
}
}
that keeps nodes these will change
void ListController::SwitchNodes(Node* firstNodeOfList, Node* secondNodeOfList, int index)
{
Node* first = firstNodeOfList;
Node* second = secondNodeOfList;
Node* temp = first;
first->next = second->next;
first->prev = second->prev;
second->next = temp->next;
second->prev = temp->prev;
firstList->SwitchNodesFromList(second, index);
secondList->SwitchNodesFromList(first, index);
delete temp;
}
i compare item but i cant switch nodes
void ListController::CompareItemsOfNodes()
{
for (int i = 0; i < firstList->Count(); i++)
{
if (firstList->ElementAt(i) > secondList->ElementAt(i))
{
ReverseList(firstList);
}
else if (firstList->ElementAt(i) == secondList->ElementAt(i))
{
ReverseList(secondList);
}
else if (firstList->ElementAt(i) < secondList->ElementAt(i))
{
SwitchNodes(firstList->GetNode(i), secondList->GetNode(i), i);
}
}
}
I am writing a program that modifies a linked list. The problem I am having is when inserting nodes into the linked list. The first few nodes are inserted and moved properly, but when reaching the end of the linked list some nodes are either removed or not displayed.
Function for inserting
void LinkedList::insert(int num, int pos)
{
Node *temp1 = new Node;
temp1->data = num;
temp1->next = NULL;
if(pos == 0)
{
temp1->next = head;
head = temp1;
return;
}
Node *temp2 = head;
for(int i = 0; i < pos-1; i++)
{
temp2 = temp2->next;
}
temp1->next = temp2->next;
temp2->next = temp1;
}
Node structure
struct Node
{
int data;
Node *next;
};
int size;
Node *head, *tail;
Driver code
nums.insert(1, 0); // 1 in location 0
nums.insert(5, 4); // 5 in location 4
nums.insert(3, 7); // 3 in location 7
List before insert
8 6 7 8 0 9
List after insert
1 8 6 7 5 8
Expected after insert
1 8 6 7 5 8 0 9 3
Would the values excluded from being display needed to be stored and inserted afterwards? Or is the inserting itself not being coded properly/missing elements?
Thanks for your help.
Full code
#include "linkedlist.h"
LinkedList::LinkedList()
{
head = nullptr;
tail = nullptr;
size = 0;
}
LinkedList::~LinkedList()
{
if(head != nullptr)
{
Node *temp;
while(head != nullptr)
{
temp = head->next;
// deletes head
delete head;
// goes to next element
head = temp;
}
}
}
void LinkedList::display()
{
Node *temp = head;
for(int i = 0; i < size; i++)
{
cout << temp->data << "\t";
temp = temp->next;
}
cout << endl;
}
void LinkedList::append(int num)
{
// list is empty
if(head == nullptr)
{
head = new Node;
head->data = num;
head->next = nullptr;
// sets tail to head
tail = head;
}
else
{
// creates new node
Node *temp = new Node;
// sets new node data
temp->data = num;
temp->next = nullptr;
// sets previous tail link to new node
tail->next = temp;
// sets this node to new tail
tail = temp;
}
// increments size
size++;
}
void LinkedList::pop()
{
if(size > 1)
{
Node *temp = head;
// loops to node before tail
while(temp->next->next != nullptr)
{
temp = temp->next;
}
// deletes tail
delete tail;
// sets new tail
tail = temp;
tail->next = nullptr;
}
// if there's only one item
else if(size == 1)
{
Node *temp = tail;
// head and tail are now null
head = nullptr;
tail = nullptr;
// deletes node
delete temp;
}
size--;
}
int LinkedList::min()
{
int min = head->data;
struct Node *temp = head;
while(temp != nullptr)
{
if(min > temp->data)
{
min = temp->data;
}
temp = temp->next;
}
return min;
}
int LinkedList::max()
{
int max = head->data;
struct Node *temp = head;
while(temp != nullptr)
{
if(max < temp->data)
{
max = temp->data;
}
temp = temp->next;
}
return max;
}
int LinkedList::mean()
{
int sum = 0;
int average = 0;
struct Node *temp = head;
while(temp != nullptr)
{
sum += temp->data;
temp = temp->next;
}
average = sum / size;
return average;
}
void LinkedList::sort()
{
Node *current1 = head;
Node *current2 = head;
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size - 1; j++)
{
if(current1->data < current2->data)
{
int temp = current1->data;
current1->data = current2->data;
current2->data = temp;
}
current2 = current2->next;
}
current2 = head;
current1 = head->next;
for(int p = 0; p < i; p++)
{
current1 = current1->next;
}
}
}
void LinkedList::reverse()
{
Node *current1 = head;
Node *current2 = head;
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size - 1; j++)
{
if(current1->data > current2->data)
{
int temp = current1->data;
current1->data = current2->data;
current2->data = temp;
}
current2 = current2->next;
}
current2 = head;
current1 = head->next;
for(int p = 0; p < i; p++)
{
current1 = current1->next;
}
}
}
int LinkedList::linearSearch(int key)
{
Node *search = nullptr;
Node *temp = head;
Node *current = head;
int count = 0;
while(current != NULL && current->data != key)
{
count++;
temp = current;
current = current->next;
}
if(current != NULL)
{
search = current;
current = current->next;
}
key = count;
return key;
}
void LinkedList::insert(int num, int pos)
{
Node *temp1 = new Node;
temp1->data = num;
temp1->next = NULL;
if(pos == 0)
{
temp1->next = head;
head = temp1;
return;
}
Node *temp2 = head;
for(int i = 0; i < pos-1; i++)
{
temp2 = temp2->next;
}
temp1->next = temp2->next;
temp2->next = temp1;
}
You have a size member that your display function uses, but you never increment it in insert. So while the element gets added, you don't increase the size of the list.
Reading your whole code and getting to the solution may consume lot of time but if you want i have a code ready which is properly working. If you wanted to use this. Please go for it and also, please feel free to ask my anything though this link
#include <iostream>
using namespace std;
struct node
{
int data;
node *next;
};
class linked_list
{
private:
node *head,*tail;
public:
linked_list()
{
head = NULL;
tail = NULL;
}
void add_node(int n)
{
node *tmp = new node;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
node* gethead()
{
return head;
}
static void display(node *head)
{
if(head == NULL)
{
cout << "NULL" << endl;
}
else
{
cout << head->data << endl;
display(head->next);
}
}
static void concatenate(node *a,node *b)
{
if( a != NULL && b!= NULL )
{
if (a->next == NULL)
a->next = b;
else
concatenate(a->next,b);
}
else
{
cout << "Either a or b is NULL\n";
}
}
};
int main()
{
linked_list a;
a.add_node(1);
a.add_node(2);
linked_list b;
b.add_node(3);
b.add_node(4);
linked_list::concatenate(a.gethead(),b.gethead());
linked_list::display(a.gethead());
return 0;
}
When I run valgrind, I get one error at method insert for operator new;
I know this probably means that I have to delete node n how I tried so many things to try to delete it but it just gives me even more errors. Please hel.
class key_value_sequences {
public:
struct node{
int key;
vector<int> values;
node* next;
node* prev;
};
key_value_sequences() {
}
~key_value_sequences() {
}
key_value_sequences(const key_value_sequences& A) {
n = A.n;
head = A.head;
tail = A.tail;
v = A.v;
}
key_value_sequences& operator=(const key_value_sequences& A) {
if (this == &A) return *this;
n = A.n;
head = A.head;
tail = A.tail;
v = A.v;
return *this;
}
// YOU SHOULD USE C++ CONTAINERS TO AVOID RAW POINTERS
// IF YOU DECIDE TO USE POINTERS, MAKE SURE THAT YOU MANAGE MEMORY PROPERLY
// IMPLEMENT ME: SHOULD RETURN SIZE OF A SEQUENCE FOR GIVEN KEY
// IF NO SEQUENCE EXISTS FOR A GIVEN KEY RETURN -1
int size(int key) const {
if (find(v.begin(), v.end(), key)!=v.end()) {
node* temp = head;
while(temp != NULL) {
if (temp->key == key) {
return temp->values.size();
}
else temp = temp->next;
}
}
else return -1;
}
// IMPLEMENT ME: SHOULD RETURN POINTER TO A SEQUENCE FOR GIVEN KEY
// IF NO SEQUENCE EXISTS FOR A GIVEN KEY RETURN nullptr
const int* data(int key) const {
if (find(v.begin(), v.end(), key)!=v.end()) {
node* temp = head;
while(temp != NULL) {
if (temp->key == key) {
return temp->values.data();
}
else temp = temp->next;
}
}
else return nullptr;
}
// IMPLEMENT ME: INSERT VALUE INTO A SEQUENCE IDENTIFIED BY GIVEN KEY
void insert(int key, int value) {
if(v.size() == 0) { //empty list
v.push_back(key);
n = new node;
n->prev = NULL;
n->key = key;
n->values.push_back(value);
head = n;
tail = n;
}
else if((find(v.begin(), v.end(), key)!=v.end())) { //if key exists already
node* temp = head;
while(temp != NULL) {
if (temp->key == key) {
temp->values.push_back(value);
break;
}
else temp = temp->next;
}
}
else { //if theres no existing key
v.push_back(key);
n = new node;
n->key = key;
n->values.push_back(value);
n->prev = tail;
tail->next = n;
tail = n;
tail->next = NULL;
}
}
private:
vector<int> v;
node* n;
node* head;
node* tail;
}; // class key_value_sequences
#endif // A3_HPP
In insert method:
if(v.size() == 0) { //empty list
v.push_back(key);
n = new node;
n->prev = NULL;
n->key = key;
n->values.push_back(value);
head = n;
tail = n;
}
You are not setting the head->next to NULL. I suspect that could be the problem while inserting second value.
while(temp != NULL) { // <<<<< Is temp uninitialized?
if (temp->key == key) {
temp->values.push_back(value);
break;
}
else temp = temp->next;
Its pretty dangerous to not initialize the pointer to NULL
I have a function and it is suppose to organize a dictionary of stemmed words. I have a function call inserted then suppose to place it in the right alphabetical order. Adding to the front and middle of the list works, but adding to the back doesn't. I've looked at several sources and I can't tell what's wrong.
void dictionary::insert(string s) {
stem* t = new stem;
t->stem = s;
t->count =0;
t->next = NULL;
if (isEmpty()) head = t;
else {
stem* temp = head;
stem* prev = NULL;
while (temp != NULL) {
if (prev == NULL && t->stem < temp ->stem) {
head = t;
head->next = temp;
}
prev = temp;
temp = temp->next;
if(t->stem > prev->stem && t->stem < temp->stem ){
prev->next =t;
t->next=temp;
}
}
if(temp == NULL && t->stem > prev->stem){
prev->next=t;
}
}
}
The statement if(temp->next=NULL) does not result in a boolean but rather an assignment. This is why the insert to the end of the list doesn't appear to work.
if (temp->next=NULL) {
prev->next = t;
}
Note the usage of a single equal. The effect of this is to set the temp->next to NULL and then evaluate if (NULL) witch will be always false. You should use ==.
This will probably do the job: (sorry, I don't have a compiler right now to test it)
#include <string>
struct node;
struct node
{
node* next;
std::string value;
};
node* head = NULL;
void insert(const std::string& word)
{
node* n = new node;
n->value = word;
node* temp = head;
node** tempp = &head;
while (true)
{
if (temp == NULL or temp->value > word)
{
n->next = temp;
*tempp = n;
return;
}
temp = temp->next;
tempp = &temp->next;
}
}