![]() |
Active Topics Memberlist Calendar Search |
|
|
| C Programming FAQs Part-II | |
| How do you sort a linked list? Write a C program to sort a linked list. | ||
| Author | Message |
|
Faqs
Admin Group
Admin Joined: 13 Apr 2006 Location: India Online Status: Offline Posts: 14411 |
|
|
This is a very popular interview question, which most people go wrong. The ideal solution to this problem is to keep the linked list sorted as you build it. Another question on this website teaches you how to insert elements into a linked list in the sorted order. This really saves a lot of time which would have been required to sort it.
However, you need to Get That Job.... Method1 (Usual method) The general idea is to decide upon a sorting algorithm (say bubble sort). Then, one needs to come up with different scenarios to swap two nodes in the linked list when they are not in the required order. The different scenarios would be something like 1. When the nodes being compared are not adjacent and one of them is the first node. 2. When the nodes being compared are not adjacent and none of them is the first node 3. When the nodes being compared are adjacent and one of them is the first node. 4. When the nodes being compared are adjacent and none of them is the first node. One example bubble sort for a linked list goes like this (working C code!).... #include<stdio.h> #include<ctype.h> typedef struct node { int value; struct node *next; struct node *prev; }mynode ; void add_node(struct node **head, int *count, int value); void print_list(char *listName, struct node *head); mynode *bubbleSort(mynode *head, int count); int main() { mynode *head; int count = 0; head = (struct node *)NULL; add_node(&head, &count, 100); add_node(&head, &count, 3); add_node(&head, &count, 90); add_node(&head, &count, 7); add_node(&head, &count, 9); print_list("myList(BEFORE)", head); head = bubbleSort(head, count); print_list("myList(AFTER) ", head); getch(); return(0); } mynode *bubbleSort(mynode *head, int count) { int i, j; mynode *p0, *p1, *p2, *p3; for(i = 1; i < count; i++) { p0 = (struct node *)NULL; p1 = head; p2 = head->next; p3 = p2->next; for(j = 1; j <= (count - i); j++) { if(p1->value > p2->value) { // Adjust the pointers... p1->next = p3; p2->next = p1; if(p0)p0->next=p2; // Set the head pointer if it was changed... if(head == p1)head=p2; // Progress the pointers p0 = p2; p2 = p1->next; p3 = p3->next!=(struct node *)NULL?p3->next: (struct node *)NULL; } else { // Nothing to swap, just progress the pointers... p0 = p1; p1 = p2; p2 = p3; p3 = p3->next!=(struct node *)NULL?p3->next: (struct node *)NULL; } } } return(head); } void add_node(struct node **head, int *count, int value) { mynode *temp, *cur; temp = (mynode *)malloc(sizeof(mynode)); temp->next=NULL; temp->prev=NULL; if(*head == NULL) { *head=temp; temp->value=value; } else { for(cur=*head;cur->next!=NULL;cur=cur->next); cur->next=temp; temp->prev=cur; temp->value=value; } *count = *count + 1; } void print_list(char *listName, struct node *head) { mynode *temp; printf("\n[%s] -> ", listName); for(temp=head;temp!=NULL;temp=temp->next) { printf("[%d]->",temp->value); } printf("NULL\n"); } As you can see, the code becomes quite messy because of the pointer logic. Thats why I have not elaborated too much on the code, nor on variations such as sorting a doubly linked list. You have to do it yourself once to understand it. Method2 (Divide and Conquer using Merge Sort) Here is some cool working C code... #include<stdio.h> #include<ctype.h> typedef struct node { int value; struct node *next; struct node *prev; }mynode ; void add_node(struct node **head, int value); void print_list(char *listName, struct node *head); void mergeSort(struct node** headRef); struct node *merge2SortedLLs(struct node *head1, struct node *head2); void splitLLInto2(struct node* source, struct node** frontRef, struct node** backRef); // The main function.. int main() { mynode *head; head = (struct node *)NULL; add_node(&head, 1); add_node(&head, 10); add_node(&head, 5); add_node(&head, 70); add_node(&head, 9); add_node(&head, -99); add_node(&head, 0); print_list("myList", head); mergeSort(&head); print_list("myList", head); getch(); return(0); } // This is a recursive mergeSort function... void mergeSort(struct node** headRef) { struct node* head = *headRef; struct node* a; struct node* b; // Base case -- length 0 or 1 if ((head == NULL) || (head->next == NULL)) { return; } // Split head into 'a' and 'b' sublists splitLLInto2(head, &a, &b); // Recursively sort the sublists mergeSort(&a); mergeSort(&b); // Merge the two sorted lists together *headRef = merge2SortedLLs(a, b); } // This is an iterative function that joins two already sorted // Linked lists... struct node *merge2SortedLLs(struct node *head1, struct node *head2) { struct node *a, *b, *c, *newHead, *temp; a = head1; b = head2; c = (struct node *)NULL; newHead = (struct node*)NULL; if(a==NULL)return(b); else if(b==NULL)return(a); while(a!=NULL && b!=NULL) { if(a->value < b->value) { //printf("\na->value < b->value\n"); if(c==NULL) { c = a; } else { c->next = a; c = c->next; } a = a->next; } else if(a->value > b->value) { //printf("\na->value > b->value\n"); if(c==NULL) { c = b; } else { c->next = b; c = c->next; } b = b->next; } else { // Both are equal. // Arbitraritly chose to add one of them and make // sure you skip both! if(c == NULL) { c = a; } else { c->next = a; c = c->next; } a = a->next; b = b->next; } // Make sure the new head is set... if(newHead == NULL) newHead = c; } if(a==NULL && b==NULL) return(newHead); if(a==NULL) c->next = b; else if(b==NULL) c->next = a; return(newHead); } // Uses the fast/slow pointer strategy // // This efficient code splits a linked list into two using // the same technique as the one used to find the // middle of a linked list! void splitLLInto2(struct node* source, struct node** frontRef, struct node** backRef) { struct node* fast; struct node* slow; if (source==NULL || source->next==NULL) { // length < 2 cases *frontRef = source; *backRef = NULL; } else { slow = source; fast = source->next; // Advance 'fast' two nodes, and advance 'slow' one node while (fast != NULL) { fast = fast->next; if (fast != NULL) { slow = slow->next; fast = fast->next; } } // 'slow' is before the midpoint in the list, so split it in two // at that point. *frontRef = source; *backRef = slow->next; slow->next = NULL; } } void add_node(struct node **head, int value) { mynode *temp, *cur; temp = (mynode *)malloc(sizeof(mynode)); temp->next=NULL; temp->prev=NULL; if(*head == NULL) { *head=temp; temp->value=value; } else { for(cur=*head;cur->next!=NULL;cur=cur->next); cur->next=temp; temp->prev=cur; temp->value=value; } } void print_list(char *listName, struct node *head) { mynode *temp; printf("\n[%s] -> ", listName); for(temp=head;temp!=NULL;temp=temp->next) { printf("[%d]->",temp->value); } printf("NULL\n"); } The code to merge two already sorted sub-linked lists into a sorted linked list could be either iterative or recursive. You already saw the iterative version above. Here is a recursive version of the same... Recursive solution to merge two already sorted linked lists into a single linked list struct node* sortedMergeRecursive(struct node* a, struct node* b) { struct node* result = NULL; if (a==NULL) return(b); else if (b==NULL) return(a); // Pick either a or b, and recur if (a->data <= b->data) { result = a; result->next = sortedMergeRecursive(a->next, b); } else { result = b; result->next = sortedMergeRecursive(a, b->next); } return(result); } Also, see how the splitLLInto2() function uses the same technique used to find the middle of a linked list to split a linked list into two without having to keep a count of the number of nodes in the linkes list! Here is another solution (not that great, though) to split a linked list into two. It used the count of the number of nodes to decide where to split void splitLLInto2(struct node* source,struct node** frontRef, struct node** backRef) { int len = Length(source); //Get the length of the original LL.. int i; struct node* current = source; if (len < 2) { *frontRef = source; *backRef = NULL; } else { int hopCount = (len-1)/2; for (i = 0; i<hopCount; i++) { current = current->next; } // Now cut at current *frontRef = source; *backRef = current->next; current->next = NULL; } } Using recursive stack space proportional to the length of a list is not recommended. However, the recursion in this case is ok ? it uses stack space which is proportional to the log of the length of the list. For a 1000 node list, the recursion will only go about 10 deep. For a 2000 node list, it will go 11 deep. If you think about it, you can see that doubling the size of the list only increases the depth by 1 ![]() Posted: 31 Dec 2007 at 11:25pm
|
|
IP Logged |
|
|
Ramya
Newbie
Joined: 21 Nov 2009 Online Status: Offline Posts: 5 |
|
|
The Remembrance of Lilacs The family had just moved to Rhode Island, and the young woman was feeling a little melancholy on that Sunday in May. After all, it was Mother's Day -- and 800 miles separated her from her parents in Ohio.(maple story mesos) She had called her mother that morning to wish her a happy Mother's Day, and her mother had mentioned how colorful the yard was now that spring had arrived. As they talked, the younger woman could almost smell the tantalizing aroma of purple lilacs hanging on the big bush outside her parents'back door. Later, when she mentioned to her husband how she missed those lilacs, he popped up from his chair. "I know where we can find you all you want, "he said. "Get the kids and c'mon. " So off they went, driving the country roads of northern Rhode Island on the kind of day only mid-May can produce:sparkling sunshine, unclouded azure skies and vibrant newness of the green growing all around. They went past small villages and burgeoning housing developments, past abandoned apple orchards, back to where trees and brush have devoured old homesteads. wow gold "Come with me , "the man said. "Over that hill is an old cellar hole, from somebody's farm of years ago, and there are lilacs all round it. The man who owns this land said I could poke around here anytime. I'm sure he won't mind if we pick a few lilacs. " Before they got halfway up the hill, the fragrance of the lilacs drifted down to them, and the kids started running. Soon, the mother began running, too, until she reached the top. world of warcraft power leveling There, far from view of passing motorists and hidden from encroaching civilization, were the towering lilacs bushes, so laden with the huge, cone-shaped flower clusters that they almost bent double. With a smile, the young woman rushed up to the nearest bush and buried her face in the flowers, drinking in the fragrance and the memories it recalled. Finally, though, they returned to their car for the trip home. While the kids chattered and the man drove, the woman sat smiling, surrounded by her flowers, a faraway look in her eyes. When they were within three miles of home, she suddenly shouted to her husband, "Stop the car. Stop right here!" The man slammed on the brakes. Before he could ask her why she wanted to stop, the woman was out of the car and hurrying up a nearby grassy slope with the lilacs still in her arms. At the top of the hill was a nursing home and, because it was such a beautiful spring day, the patients were outdoors strolling with relatives or sitting on the porch. world of warcraft gold The young woman went to the end of the porch, where an elderly patient was sitting in her wheelchair, alone, head bowed, her back to most of the others. Across the porch railing went the flowers, in to the lap of the old woman. She lifted her head, and smiled. For a few moments, the two women chatted, both aglow with happiness, and then the young woman turned and ran back to her family. As the car pulled away, the woman in the wheelchair waved, and clutched the lilacs. "Mom, "the kids asked, "who was that?Why did you give her our flowers?Is she somebody's mother?"The mother said she didn't know the old woman. But it was Mother's Day, and she seemed so alone, and who wouldn't be cheered by flowers?"Besides, "she added, "I have all of you, and I still have my mother, even if she is far away. That woman needed those flowers more than I did. " ![]() Posted: 21 Nov 2009 at 3:16am
|
|
IP Logged |
|
|
qiuqiu320
Newbie
Joined: 13 May 2010 Online Status: Offline Posts: 6 |
|
|
Blacksmithing is a Cheap wow gold buy wow power leveling aion wedding dresses wow power leveling great profession, and for some classes it would be a very wise decision to make blacksmithing their profession. Mining should definitely be taken as your second profession if you wow gold decide to be a blacksmith because it will save you a lot of gold. Leveling blacksmithing is quite expensive even if you are a miner and doing it without it will costs you thousands of additional gold. wow power leveling Blacksmithing would be a perfect choice, especially for the plate users and melee DPS classes since most of the goodies that can be made only have a purpose for these classes.It must also be sad that the best craftable and usable items come in the end. Even though you might find some armors, items and weaponry that you are able to craft while you level worth equipping to boost your character a bit. wedding dresses Most of you probably know you need a Blacksmith Hammer to craft items and that most items can only be crafted at a forge. Forges can be found in all the major cities though, as well as in many smaller villages.We made this guide especially for the people that would like to minimize their costs and effort while leveling their blacksmithing aion power leveling profession.You will also notice that at one point you will be able cxyojhllkjhd to choose between becoming a weaponsmith, and then be able to choose from Axe, Mace and Sword smith, and an Armor smith. You will be able to redo your choice but this will be at a cost of 25G-100G, so choose wisely. cxy
![]() Posted: 13 May 2010 at 2:34am
|
|
IP Logged |
|
|
||
Select Category |
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot delete your posts in this forum You cannot edit your posts in this forum You cannot create polls in this forum You cannot vote in polls in this forum |
|