How to check for common values between two Linked Lists? - singly-linked-list

public void setIntersection(LinkList list1, LinkList list2) {
LinkList list4 = new LinkList();
Node a = list1.head;
Node b = list2.head;
while (a != null && b != null) {
if (a.value < b.value) {
a = a.next;
} else if (a.value > b.value) {
b = b.next;
} else if (a.value == b.value){
list4.insert(a.value);
a = a.next;
b = b.next;
}
}
list4.printList();
}
I want to find out the common values appearing in List 1 and List 2 and save the entries in List4. Although this seems straight forward, I still feel my code is too long and wondering if there is a more efficient way to solve this problem ?

struct LinkList
{
int data;
struct LinkList *next;
}*list1,*list2,*list4;
public void setIntersection(LinkList *list1, LinkList *list2)
{
LinkList *temp, *temp1, *temp2, *node;
for(temp1 = list1;temp1!=null;temp1=temp1->next)
{
enter code here for(temp2 = list2;temp2!=null;temp2=temp2->next)
{
if(temp1->data == temp2->data)
{
node = (struct LinkList *)malloc(sizeof(struct LinkList));
node->next = null;
if(list4==null)
{
list4 = node;
}
else
{
for(temp = list4;temp->next!=NULL;temp=temp->next);
temp->next = node;
}
}
}
}
}

Related

What could cause a Cyclical Linked List [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed yesterday.
Improve this question
I am trying to make a quicksort algorithm for singly-linked lists. I, however, must be somehow creating a cyclical list in the process. In the concatenate function, the while loop gets stuck printing out 2 and 22 continuously. So, I assume that I must somehow be creating a list where Node 2 points to Node 22 and vice versa. Unfortunately, I have no idea how, since I feel like I have added nullptr to the end of every list where it would matter. I have reviewed my partition function so many times I add more bugs than I fix. Is there something I am missing with how linked lists work?
I have been stuck on this for a while so any help would be greatly appreciated.
Here is my quicksort code.
// quick.cpp
#include "volsort.h"
#include <iostream>
#include <string>
using namespace std;
// Prototypes
Node *qsort(Node *head, bool numeric);
void partition(Node *head, Node *pivot, Node *&left, Node *&right, bool numeric);
Node *concatenate(Node *left, Node *right);
// Implementations
void quick_sort(List &l, bool numeric) {
l.head = qsort(l.head, numeric);
}
Node *qsort(Node *head, bool numeric) {
if (head == nullptr || head->next == nullptr) {
return head;
}
Node *l = nullptr;
Node *r = nullptr;
partition(head, head, l, r, numeric);
l = qsort(l, numeric);
r = qsort(r, numeric);
head = concatenate(l, head);
head = concatenate(head, r);
return head;
}
void partition(Node *head, Node *pivot, Node *&left, Node *&right, bool numeric) {
Node *cur = pivot->next;
bool c;
Node *tl=nullptr, *tr=nullptr;
while (cur != pivot && cur != nullptr) {
if (numeric) {
c = node_number_compare(cur, pivot);//compare numeric elements of the Nodes
}
else {
c = node_string_compare(cur, pivot);//compare string elements of the code
}
if (c) {
if (left == nullptr) {
left = cur;
cur = cur->next;
tl = left;
}
else {
tl->next = cur;
cur = cur->next;
tl = tl->next;
tl->next = nullptr;
}
}
else {
if (right == nullptr) {
right = cur;
cur = cur->next;
tr = right;
}
else {
tr->next = cur;
cur = cur->next;
tr = tr->next;
tr->next = nullptr;
}
}
}
}
Node *concatenate(Node *left, Node *right) {
if (right == nullptr && left == nullptr) {
return nullptr;
}
else if (left == nullptr) {
right->next = nullptr;
return right;
}
else if (right == nullptr) {
left->next = nullptr;
return left;
}
Node *t = left;
while (t->next != nullptr) {
cout << t->number << endl;
t = t->next;
}
t->next = right;
while (t->next != nullptr) {
cout << t->number << endl;
t = t->next;
}
t->next = nullptr;
return left;
}
Input:
45
4
9
22
2
Here's the list class functions if it helps.
#include "volsort.h"
#include <string>
#include <iostream>
List::List() {
head = NULL;
size = 0;
}
List::~List() {
if (head != NULL) { // follow the links, destroying as we go
Node *p = head;
while (p != NULL) {
Node *next = p->next; // retrieve this node's "next" before destroy it
delete p;
p = next;
}
}
}
bool node_number_compare(const Node *a, const Node *b) {
if (a->number <= b-> number) {
return true;
}
else {
return false;
}
}
bool node_string_compare(const Node *a, const Node *b) {
return a->string <= b->string;
}
void List::push_front(const std::string &s) {
Node *node = new Node();
node->next = NULL;
node->string = s;
node->number = std::stoi(s);
if (head == NULL) {
head = node;
size = 1;
}
else {
Node *p = head;
while (p->next != NULL) {p = p->next;} // go to end of list
p->next = node;
size++;
}
}
void List::dump_node(Node *n) {
while (n->next != NULL) {
std::cout << n->number << " " << n->string << std::endl;
}
}

Merge sort a Linked list (segementation fault)

The below code is for merge sorting a linked list. Its giving out a segmentation fault. I really dont know how to deal with the above. All I could find was that I was trying to access a restricted part of the memory, the only place I think i could've gone wrong is re combining the two linked lists after splitting and sorting them under the split function body. I'd appreciate if I could get some guidance on how to deal with segmentation faults from here on & how to rectify them.
//Segmentation fault
#include <iostream>
using namespace std;
class Node
{
public:
int data;
Node *next;
Node(int data)
{
this->data = data;
next = NULL;
}
};
void print(Node *head)
{
Node *temp = head;
while (temp != NULL)
{
cout << temp->data << " ";
temp = temp->next;
}
}
Node *insert()
{
int data;
cin >> data;
Node *head = NULL;
Node *tail = NULL;
while (data != -1)
{
Node *n = new Node(data);
if (head == NULL)
{
head = n;
tail = n;
}
else
{
tail->next = n;
tail = tail->next;
}
cin >> data;
}
return head;
}
Node *sortedMerge(Node *h1, Node *h2)
{
// Node *fHead = NULL;
// Node *fTail = NULL;
if (!h1)
{
return h2;
}
if (!h2)
{
return h1;
}
if (h1->data < h2->data)
{
h1->next = sortedMerge(h1->next, h2);
return h1;
}
else
{
h2->next = sortedMerge(h1, h2->next);
return h2;
}
}
void split(Node *head, Node *h1, Node *h2)
{
Node *slow = head;
Node *fast = head->next;
while (fast != NULL)
{
fast = fast->next;
if (fast != NULL)
{
slow = slow->next;
fast = fast->next;
}
}
h1 = head;
h2 = slow->next;
slow->next = NULL;
}
void mergeSort_LL(Node *head)
{
Node *temp = head;
Node *h1;
Node *h2;
if ((temp == NULL) || (temp->next == NULL))
{
return;
}
split(temp, h1, h2);
mergeSort_LL(h1);
mergeSort_LL(h2);
head = sortedMerge(h1, h2);
}
int main()
{
Node *head = insert();
print(head);
cout << endl;
mergeSort_LL(head);
cout << "Sorted List is : " << endl;
print(head);
return 0;
}
Your call to split will not make h1 or h2 get a value. Arguments are passed by value. Since you evidently need h1 and h2 to get a different value from that split call, you should pass their addresses:
split(temp, &h1, &h2)
The function itself should therefore accept these addresses instead of the node pointers themselves:
void split(Node *head, Node **h1, Node **h2) {
// ...
*h1 = head;
*h2 = slow->next;
// ...
}

Why am I getting a segmentation fault when I try to run mergesort on my C++ linked list? (SEGFAULT)

I am implementing a linked list with a merge sort function for a class project. My program compiles, but when I try to run it I get segmentation fault(core dumped). I debugged my program using GDB, and found that the segfault happens with the pointer frontRef and backRef in my listSplit() function (line 98 in the code below).
Can someone please help me? For the life of me I can't figure out why I am getting a segfault. I would greatly appreciate help with this.
#include "orderedList.h"
orderedList::orderedList() {
listLength = 0;
traversalCount = 0;
head = nullptr;
tail = nullptr;
}
void orderedList::add(int n) {
listLength++;
struct node* point = new node;
point->value = n;
point->next = nullptr;
if (head == nullptr) {
head = point;
tail = point;
}
else {
point->next = head;
head = point;
}
}
void orderedList::merge(struct node** headRef) {
struct node *listHead = *headRef;
struct node *a;
struct node *b;
if ((listHead == nullptr) || (listHead->next == nullptr)) {
return;
}
listSplit(listHead, &a, &b);
merge(&a);
merge(&b);
*headRef = sortedMerge(a, b);
}
orderedList::node* orderedList::sortedMerge(struct node* a, struct node *b)
{
struct node* result = nullptr;
if (a == nullptr) {
return (b);
}
if (b == nullptr) {
return (a);
}
if (a->value <= b->value) {
result = a;
result->next = sortedMerge(a->next, b);
}
else {
result = b;
result->next = sortedMerge(a, b->next);
}
return (result);
}
void orderedList::print() {
struct node* temp = head;
while (temp != nullptr) {
std::cout << temp->value << " ";
temp = temp->next;
}
delete(temp);
}
int orderedList::search(int key) {
int traversals = 1;
struct node* current = head;
struct node* previous = nullptr;
while (current != nullptr) {
if (current->value == key) {
if (previous != nullptr) {
previous->next = current->next;
current->next = head;
head = current;
return traversals;
}
}
previous = current;
current = current->next;
traversals ++;
}
return 1;
}
void orderedList::listSplit(struct node* source, struct node** frontRef, struct node** backRef) { // <--- Line 98
struct node* current = source;
int hopCount = ((listLength - 1) / 2);
for (int i = 0; i < hopCount; i++) {
current = current->next;
}
*frontRef = source;
*backRef = current->next;
current->next = nullptr;
}
You made *backRef point to current->next and then you let current->next = nullptr. This makes *backRef pointing to a nullptr. Did you later try to do something with the returned backRef, aka a node variable in your caller code?

can I sort a linked-list by an inherited class in c++?

I implemented a linked list in a class with addToHead, addToTail, deleteFromHead, deleteFromTail, isEmpty, and display functions, and I want to sort the linked list in ascending order in an inherited class, so I made a class TSortedList with two functions; the sortList function that compares the elements of the linked list with each other, and the display() function that display the linked list after sorting it. But when I run the code nothing appear to me, however when I sort it through a function in the parent class, not the inherited class it works, so I do not know where is the problem
#include <iostream>
using namespace std;
class Node {
public:
Node() {
next = 0;
//write your modification here
}
Node(int el, Node *ptr = 0) { //write your modification for the constructor arguments here
info = el;
next = ptr;
}
int info;
Node *next;
//write your modification here
};
class LList {
protected:
Node *head, *tail;
public:
LList() {
head = tail = 0;
}
~LList(){
for (Node *p; !isEmpty(); ) {
p = head->next;
delete head;
head = p;
}
}
int isEmpty() {
return head == 0;
}
virtual void addToHead(int el){
head = new Node(el,head);
if (tail == 0)
tail = head;
}
virtual void addToTail(int el){
if (tail != 0) { // if list not empty;
tail->next = new Node(el);
}
else head = tail = new Node(el);
}
int deleteFromHead(){ // delete the head and return its info;
int el = head->info;
Node *tmp = head;
if (head == tail) // if only one node in the list;
head = tail = 0;
else head = head->next;
delete tmp;
return el;
}
int deleteFromTail(){ // delete the tail and return its info;
int el = tail->info;
if (head == tail) { // if only one node in the list;
delete head;
head = tail = 0;
}
else { // if more than one node in the list,
Node *tmp; // find the predecessor of tail;
for (tmp = head; tmp->next != tail; tmp = tmp->next);
delete tail;
tail = tmp; // the predecessor of tail becomes tail;
tail->next = 0;
}
return el;
}
bool isInList(int el) const{
Node *tmp;
for (tmp = head; tmp != 0 && !(tmp->info == el); tmp = tmp->next);
return tmp != 0;
}
virtual void displayList(){
if (head == 0) // if empty list;
return;
Node *tmp = head;
for (tmp = head; tmp != 0; tmp = tmp->next){
cout<<tmp->info<<endl;
}
}
};
class TSortedList: public LList, public Node
{
protected:
Node *current = head, *index = 0;
int temp;
public:
void sortList() {
if(head == 0) {
return;
}
else {
while(current != 0) {
//Node index will point to node next to current
index = current->next;
while(index != 0) {
//If current node's data is greater than index's node data, swap the data betweenthem
if(current->info > index->info) {
temp = current->info;
current->info = index->info;
index->info = temp;
}
index = index->next;
}
current = current->next;
}
}
}
void display() {
//Node current will point to head
Node *current = head;
if(head == 0) {
return;
}
while(current != 0) {
//Prints each node by incrementing pointer
cout<<current->info<<endl;
current = current->next;
}
cout<<"\n"<<endl;
}
};
int main()
{
//Adds data to the list
LList myList;
myList.addToHead(1);
myList.addToHead(7);
myList.addToHead(3);
TSortedList sortt;
sortt.sortList();
sortt.display();
return 0;
}
Your TSortedList sortt; is empty; you never add anything to it.
What do you expect it to display?
This should work as you expected:
int main()
{
//Adds data to the list
TSortedList myList;
myList.addToHead(1);
myList.addToHead(7);
myList.addToHead(3);
myList.display(); // this should be in original order
myList.sortList();
myList.display(); // this should be sorted
return 0;
}
Also, why are you deriving your TSortedList from Node?
class TSortedList: public LList, public Node

Logic Correct but Program Crashes

NOTE: This question is not about reversing a linked list using recursion but about why it crashes. It's more about dynamic memory really.
I'm implementing a linked list and want to have a function in it that recursively reverses it.
struct sNode {
int data;
sNode* next;
sNode(int x) {
data = x;
next = 0;
}
sNode(int x, sNode* n) {
data = x;
next = n;
}
};
class SLL {
public:
SLL() : head(0) {}
sNode* getHead() { return head;}
void reverseRec(sNode*); // Reverse the list using recursion;
private:
sNode* head;
};
void SLL::reverseRec(sNode* node) {
// Reverse the list using recursion
if (node == 0) {
head = node;
return;
}
reverseRec(node->next);
sNode* temp = node->next;
temp->next = node;
node->next = 0;
}
int main() {
SLL l1;
l1.addAtEnd(1);
l1.addAtBeg(2);
l1.addAtPos(3, 2);
l1.reverseRec(l1.getHead());
return 0;
}
The program just crashes. Please help me figure out the reason. I think it's got to do with the arguments of the function.
This is a problem.
if (node == 0) {
head = node;
return;
}
You just made the list an empty list. That should be (prefer to use nullptr or NULL instead of 0 for pointers):
if (node == nullptr || node->next == nullptr ) {
head = node;
return;
}