Sorting a linked list in c++ - c++

I'm getting mad with infinite loop, what do you think is suitable solution?
void sorting () {
node * temphead = head;
node * tempnode = NULL;
for (int i=0; i<count; i++) {
for (int j=0; j<count-i; j++) {
if (temphead->data > temphead->next->data) {
tempnode = temphead;
temphead = temphead->next;
temphead->next = tempnode;
}
temphead=temphead->next;
count++;
}
}
}
I tried to increment count and use many conditions with while- before and after the for loop with no result

An easier way to slide through a linked list is like this:
for (node *current = head; current != nullptr; current = current->next) {
// This will run through all of the nodes until we reach the end.
}
And to slide to the second to last item (ensuring that node->next exists) looks like this:
for (node *current = head; current->next != nullptr; current = current->next) {
// Go through all of the nodes that have a 'next' node.
}
If you want to count how many items are in a linked list, you do something like this:
int count = 0;
for (node *current = head; current != nullptr; current = current->next) {
count = count + 1;
}
So a selection type sort like you have above would look like this:
for (node *index = head; index->next != nullptr; index = index->next) {
for (node *selection = index->next; selection != nullptr; selection = selection->next) {
if (index->data > selection->data) {
swap(index->data, selection->data);
}
}
}
Although sorting linked lists is generally not the best way to go (unless you're performing a merge).

the problem is you are looping till count and you are incrementing count in every run of the loop//remove line count++ to avoid remove infinite loop

Related

singly linked list insertion issue

I was trying to insert element at end of a linked list, but if I comment the break in my while loop, it goes to a continuous loop, I'm unable to figure out why
code:
head=NULL;
node *temp=head;
for(int i=0;i<5;i++)
{
//temp=head;
node* t1=new node;
if(head==NULL)
{
t1->a=i;
t1->next=NULL;
head=t1;
}
else
{
temp=head;
while(temp!=NULL)
{
if(temp->next==NULL)
{
t1->a=i;
t1->next=NULL;
temp->next=t1;
//break;
}
temp=temp->next;
}
}
}
temp=head;
while(temp!=NULL)
{
cout<<temp->a<<endl;
temp=temp->next;
}
Your while loop is trying to traverse the new node you have just added again and again. Breaking the loop after the insert operation is correct here, otherwise the while loop may loop indefinitely.
Your while loop runs forever without the break because temp is never set to NULL to stop the loop. When the while loop reaches the last node in the list, it appends the new node to the end, then sets temp to that node. So the next loop iteration sees that node, appends again, and again, and again, endlessly.
So, you need to break the while loop when the last node has been reached:
for(int i = 0; i < 5; i++)
{
node* t1 = new node;
t1->a = i;
t1->next = NULL;
if (head == NULL)
{
head = t1;
}
else
{
node *temp = head;
while (temp != NULL)
{
if (temp->next == NULL)
{
temp->next = t1;
break;
}
temp = temp->next;
}
}
}
In which case, the while loop can be simplified to not need break at all:
for(int i = 0; i < 5; i++)
{
node* t1 = new node;
t1->a = i;
t1->next = NULL;
if (head == NULL)
{
head = t1;
}
else
{
node *temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = t1;
}
}
That being said, this whole code can be greatly simplified further, to not reiterate the entire list on each iteration of the outer for loop, and to not use an if.. else to decide whether or not to set the head:
node **temp = &head;
while (*temp != NULL)
{
temp = &((*temp)->next);
}
for(int i = 0; i < 5; i++)
{
node* t1 = new node;
t1->a = i;
t1->next = NULL;
*temp = t1;
temp = &(t1->next);
}

Create a function to insert element into List at given position

Not sure if there is a simple and better way to implement this function?
void insert(Node* &head, int element, int position) {
Node* current = new Node;
current->data = element;
current->next = NULL;
if (position == 1) {
current->next = head;
head = current;
return;
}
else {
Node * current2 = head;
for (int i = 0; i < position - 2; i++) {
current2 = current2->next;
}
current2->next = current2->next;
current2->next = current;
}
}
A better way would be to make this function without null pointer access. You are missing all the necessary error checking.
But if you have to use this function you are already doing something wrong. The operation takes O(n) time. And if you build your list using only this function then you already have O(n^2) time. Using a balanced tree or heap would give you O(n * log n) time which makes a huge difference even for relatively small n. So think again why you need to insert at a given position and think about more suitable data structures.
A simpler implementation, and actually used in real code a lot, is to implement insert_before(before, data) or insert_after(after, data) with a doubly linked list. Both of which would get an item in the list and a new item to insert and place the new item before or after the old one on O(1) time.
Some boundary check is needed (please find the comments inline):
int listLen(Node *head)
{
int len = 0;
while (head != nullptr)
{
len++;
head = head->next;
}
return len;
}
void insert(Node* &head, int element, int position)
{
if (head == nullptr) // do nothing if head is nullptr
return;
if (position < 0) // insert to the begin if position is negative
position = 0;
else
{
int len = listLen(head);
if (len < position) // position is out of range, insert to the end
{
position = len;
}
}
if (position == 0)
{
Node *next = head;
head = new Node(element);
head->next = next;
}
else
{
int curPos = 0;
Node *curNode = head;
while (curPos < position - 1) // move to position
{
curNode = curNode->next;
curPos++;
}
Node *next = curNode->next; // do insertion
curNode->next = new Node(element);
curNode->next->next = next;
}
}

calling a function within another function

I am making a simple linked list with an insert function that has 4 conditions:
add in the middle of the list
add to the head if the list is not empty
add to an empty list
add to the end of a list
I have made an addNode function that takes care of the last two conditions and im trying to implement it inside of the insertNode but it keeps crashing? is there any specific reason or am I just missing something simple?
addNode:
void linkList::addNode(int dataAdd) // this only adds a node to the end
{
nodePtr n = new node; // what this does is make the node pointer 'n' point to this new node
n->next = NULL;
n->data = dataAdd;
if (head != NULL)
{
follow = head;
while (follow->next != NULL)
{
follow = follow->next;
}
follow->next = n;
}
else
{
head = n;
}
}
insertNode:
void linkList::insertNode(int dataInsert)
{
nodePtr n = new node;
n->next = NULL;
n->data = dataInsert;
follow = head;
while (follow != NULL)
{
trail = follow;
follow = follow->next;
if (head->data < dataInsert){
n->next = head; //n's next will become the current head (n is now the first item in the linkList)
head = n; //n the head structure will now be n (n is the new head)
}
else if (follow->data < dataInsert)
{
trail->next = n;
n->next = follow;
break;
}
else
{
addNode(dataInsert);
}
}
}
I want to call addNode in the else statement in insertNode

Doubly Linked List Bubblesort, Reverse method now broken

So I've recently updated my Bubblesort (sorts alphabetically) to work with a linked list.
Although now my previously working reverse method breaks the list. (Previously worked if I didn't do the single list bubble sort first)
Bubble sort and Swap.
void bubbleSort() {
City *temp = NULL;
City *current = head;
while (current != NULL) { //for the rest in list
if (current->getName().compare(current->next->getName()) > 0) { //compare distance
if (current == head) {
head = current->next;
}
swap(current, current->next);
}
current = current->next;
}
}
Swap
void swap(City* i, City* j) {
if (i->previous) i->previous->next = j;
if (j->previous) j->previous->next = i;
if (i->next) i->next->previous = j;
if (j->next) j->next->previous = i;
City* temp;
temp = i->previous;
i->previous = j->previous;
j->previous = temp;
temp = i->next;
i->next = j->next;
j->next = temp;
}
This is the now broken reverse list.
void reverseList() {
City *temp = NULL;
City *current = head;
while (current != NULL) {
temp = current->previous;
current->previous = current->next;
current->next = temp;
current = current->previous;
}
if (temp != NULL) {
head = temp->previous;
}
}
Question What have I missed out of my bubble sort that breaks the list?
One error is your bubble sort implementation. It should be making multiple passes through the data, since bubble sort has O(n*n) complexity, where n is the number of items to be sorted.
In other words, you need to execute the while loop in bubbleSort until you've detected that the data is sorted. That can be done either by using a boolean flag that is only set when a swap occurs and then testing that flag, or just make n passes through the data.

Bubble sorting for linked list

I am trying to sort a singly linked list using bubble sort. If there is a simple mistake then please pardon. Please tell me where I am going wrong. Program stops unexpectedly when I try to do this.
void sortBubble()
{
Node *i=start,*j=start;Node *temp;Node* prev=start;Node* agla;
while(i->next!=NULL)
{
cout<<"\nhello 1";
j=i;
agla=j->next;
while(agla!=NULL)
{
temp=NULL;temp->next=NULL;
cout<<"\nhello2";
if(*(j) > *(agla))
{
temp=agla->next;
agla->next=j;
prev->next=agla;
prev=agla;
agla=j->next;
j->next=temp;
}
else{
prev=j;
j=agla;
agla=j->next;}
}
prev=i;
i=i->next;
}
}
}
Your first obvious mistake that absolutely leads to program crash is:
while(agla!=NULL)
{
temp=NULL;temp->next=NULL;
You are setting a variable to NULL, then setting its fields. A null pointer points to nowhere, so you cannot edit its contents.
Remove temp->next=NULL;
Edit:
Your program logic is not correct. You ruin the list after a few iterations of the loop and the program sticks in an infinite loop with mixed up pointers.
In bubble sort, we iterate through the items several times. In each iteration, the largest item is bubbled up to the end of the list. After first iteration, we are sure that the largest element is at the end of the list. After second iteration, we are sure that the second largest element is before the last element of the list, and so on.
You repeat this process until all the items are on their places:
int getListSize(Node* start)
{
int count = 0;
while(start != NULL)
{
count++;
start = start->next;
}
return count;
}
void bubbleSort(Node *&start) // <-- Pass a reference to pointer, because we may need to modify the start pointer.
{
int size = getListSize(start);
int i = 0;
while(size--)
{
Node
*current = start,
*prev = NULL; // We are at the beginnig, so there is no previous node.
while(current->next != NULL) // We have at least one node (size > 0) so `current` itself is not NULL.
{
Node *after = current->next;
if((*current) > (*after))
{
//swap the items
current->next = after->next;
after->next = current;
if (prev == NULL) // we are at the beginning
start = after;
else
prev->next = after;
prev = after;
}
else
{
prev = current;
current = current->next;
}
}
}
}
We repeat the "bubbling up" process size times. This is not the most efficient way, since we even compare the items that are already sorted. A more efficient way is to sort until no new swapping occurs:
void bubbleSort(Node *&start) // <-- Pass a reference to pointer, because we may need to modify the start pointer.
{
int size = getListSize(start);
int i = 0;
Node *lastSwapped = NULL;
while(size--)
{
Node
*current = start,
*prev = NULL, // We are at the beginnig, so there is no previous node.
*currentSwapped = NULL;
while(current->next != lastSwapped) // We have at least one node (size > 0) so `current` itself is not NULL.
{
Node *after = current->next;
if((*current) > (*after))
{
//swap the items
current->next = after->next;
after->next = current;
if (prev == NULL) // we are at the beginning
start = after;
else
prev->next = after;
prev = after;
currentSwapped = current;
}
else
{
prev = current;
current = current->next;
}
}
if (currentSwapped == NULL)
break; // No swapping occured. The items are sorted.
else
lastSwapped = currentSwapped;
}
}
This is the complete working program
You are comparing the elements by simply doing *(j) > *(agla), I'm not sure how that builds since both j and agla are pointers to structures. Structures cannot be compared directly.