Linked list
Question 1: What is the difference between an array and a linked list?
The difference between an array and a linked list is manifested in the following ways:
1) Logical structure. Arrays must be defined in advance to define a fixed length that cannot be adapted to dynamically increase or decrease data. When you insert or delete data items in an array, you need to move other data items. The chain list is implemented in the form of dynamically allocated memory, which can be adapted to the situation of dynamic change of data, can allocate memory space with New/malloc when needed, do not need to use Delete/free to release allocated space, insert and delete elements do not need to move data items.
2) Memory structure. The array allocates space from the stack, and the linked list allocates space from the heap.
3) The data in the array is stored sequentially in memory, and the linked list is stored randomly. The random access of the array is very efficient and can be directly positioned, but the efficiency of the INSERT and delete operations is lower. The INSERT, delete operation of the linked list does not require moving elements.
4) There is no cross-border problem with the list, and the array has a cross-border problem.
Task Form 2: Sorting a single linked list
Method 1: Use bubble sort
Method 2: Use direct insert sorting
Method 3: Use merge sort
When we need to sort the list, because it can not be random access to its elements, it is more appropriate to use the merge sort, the famous fast sort used on the linked list, the efficiency is very low, because the list of elements can not be random access, similarly, the use of heap sorting is more impossible.
The implementation of the algorithm requires a pointer to the head node (the first node of the list, the list does not contain an additional node to make the head node) pointers, because when the algorithm is implemented, it is unlikely that the first node is exactly the smallest of all elements, the list of the head node will change, So we need a pointer to the head node to store the changing head node.
Algorithm idea:
mergesort (headref)
1) If Head is NULL or there are only one element in the Linked list then return.2) Else divide the Linked list into Halves. Frontbacksplit (Head, &a, &b); /* A and B are both halves */3) Sort the and B halves a. MergeSort (a); MergeSort (b); 4) Merge The sorted A and B (using Sortedmerge () discussed here) and update the head pointer using Headre F. *headref = Sortedmerge (A, b);
code example:
#include <stdio.h>#include <stdlib.h>/*Link List Node*/structNode {IntDatastruct node*Next };/*Function prototype*/struct node* sortedmerge (struct node* A,struct node*b);void Frontbacksplit (struct node* source,struct node** frontref,struct node**BACKREF);/*Sorts the linked list by changing next pointers (not data)*/void MergeSort (struct node**HEADREF) {struct node* head = *Headref;struct node*Astruct node*b/*Base case--length 0 or 1*/if ((head = = NULL) | | (Head->next = =NULL)) {Return; }/*Split head into ' a ' and ' B ' sublists*/Frontbacksplit (Head, &a, &b);/*Recursively sort the sublists*/MergeSort (&a); MergeSort (&b);/*Answer = Merge the sorted lists together*/*headref =Sortedmerge (A, b); }struct node* sortedmerge (struct node* A,struct node*b) {struct node* result =NULL;/*Base Cases*/if (A = =NULL)Return(b);Elseif (b = =NULL)Return(a);/*Pick either A or B recur*/if (A->data <= b->data) {result =A Result->next = Sortedmerge (a->Next, B); }Else{result =b Result->next = Sortedmerge (A, b->Next); }Return(result); }/*UTILITY FUNCTIONS*//*Split the nodes of the given list into front and back halves, and return the both lists using the references parameters. If the length is odd, the extra node shold go in the front list. Uses the Fast/slow pointer strategy.*/void Frontbacksplit (struct node* source,struct node** frontref,struct node**BACKREF) {struct node*Faststruct node*Slowif (Source = = NULL | | source->next = =NULL) {*frontref =Source *backref =NULL; }Else{slow =Source Fast = Source->Next/*Advance ' fast ', ' nodes ', and Advance ' slow ' one node*/while (fast! =NULL) {fast = Fast->Nextif (fast! =NULL) {slow = slow->Next Fast = Fast->Next }} *frontref =Source *backref = slow->Next Slow->next =NULL; } }/*Function to print nodes in a given linked list*/void Printlist (struct node*node) {while (node! =NULL) {printf ("%d", node->data); node = node->Next } }/*Function to insert a node at the begining of the linked list*/void Push (struct node** head_ref,IntNew_data) {/*Allocate node*/struct node* New_node = (struct node*) malloc (sizeofstructnode));/*Put in the data*/New_node->data =New_data;/*Link the old list off the new node*/New_node->next = (*HEAD_REF);/*Move the head to point to the new node*/(*head_ref) =New_node; }/*Drier program to test above functions*/IntMain () {/*Start with the empty list*/struct node* res =NULL;struct node* a =NULL;/*Let us create a unsorted linked lists to test the functions Created lists shall be a:2->3->20->5->10->15*/push (&A), push ( &a), push (&a, 5), push (&a, ),push ( &a, 3); push (&a, 2); /* Sort The above created Linked list */mergesort (&a); printf ("\ n Sorted Linked list is: \ n"); Printli St (a); return 0; }
The time complexity is O (NLOGN).
Seemingly mergesort time complexity is O (NLOGN), split time complexity is O (NLOGN)? Of course, the total time complexity is still O (Nlogn), but certainly not the array to merge sort fast.
Data structure and algorithms-linked list