======================================
Function: Select sorting (from small to large)
Return: pointer to the table header of the linked list.
======================================
*/
/*
The basic idea of sorting is to repeat the nodes that are not sorted,
Select the node with the smallest key value (that is, the field sorted by the student number num,
Re-combine them into a linked list.
I think the key to writing a linked list is to understand:
Head stores the address of the first node, and head-> next stores the address of the second node;
The P address of any node can only be obtained through the next of the previous node.
The following figure shows how to select and sort a one-way linked list:
----> [1] ----> [3] ----> [2]... ----> [N] ----> [null] (original linked list)
Head 1-> next 3-> next 2-> next N-> next
----> [Null] (empty linked list)
First
Tail
----> [1] ----> [2] ----> [3]... ----> [N] ----> [null] (sorted linked list)
First 1-> next 2-> next 3-> next tail-> next
Figure 10: Sorting by the linked list with N nodes
1. First, find the smallest one in the original linked list and put it in another empty linked list;
2. Place the first incoming node in the empty linked list to generate an ordered linked list, and separate it from the original linked list (Note whether the first node or other intermediate nodes are in the original linked list );
3. Continue to find the next smallest value in the original linked list. After finding the value, place it to the next value of the tail pointer of the ordered linked list, and then change it to its tail pointer;
*/
Struct student * selectsort (struct student * head)
{
Struct student * First;/* Header pointer of the sorted chain */
Struct student * tail;/* Table tail pointer of the sorted chain */
Struct student * p_min;/* reserve the pointer of the front node of a node with a smaller key value */
Struct student * min;/* minimum storage node */
Struct student * P;/* nodes currently compared */
First = NULL;
While (Head! = NULL)/* Find the node with the smallest key value in the linked list. */
{
/* Note: here the for statement is the place where the sorting idea is selected */
For (P = head, min = head; P-> next! = NULL; P = p-> next)/* find the smallest node in the recurrence chain table. */
{
If (p-> next-> num <min-> num)/* finds a node smaller than the current Min. */
{
P_min = P;/* Save and find the frontend node of the node: Obviously, the frontend node of p-> next is P. */
Min = p-> next;/* save nodes with smaller key values. */
}
}
/* After the preceding for statement is complete, two things are required. One is to put it in an ordered linked list; the other is to determine based on the corresponding conditions and arrange it to leave the original linked list. */
/* First thing */
If (first = NULL)/* If the ordered linked list is still an empty linked list */
{
First = min;/* Find the node with the smallest key value for the first time. */
Tail = min;/* Note: The tail Pointer Points to the last node. */
}
Else/* ordered linked list with nodes */
{
Tail-> next = min;/* put the minimum node you just found at the end, that is, let the next of the tail pointer point to it. */
Tail = min;/* the tail pointer also points to it. */
}
/* Second thing */
If (min = head)/* If the minimum node found is the first node */
{
Head = head-> next;/* clearly let the head point to the original head-> next, that is, the second node, then OK */
}
Else/* if it is not the first node */
{
P_min-> next = min-> next;/* Next Of the last min node points to next of the current min, so that Min leaves the original linked list. */
}
}
If (first! = NULL)/* Get the sorted linked list first after the loop ends */
{
Tail-> next = NULL;/* Next Of the last node of the one-way linked list should point to null */
}
Head = first;
Return head;
}
/*
======================================
Function: sort by insert directly (from small to large)
Return: pointer to the table header of the linked list.
======================================
*/
/*
The basic idea of directly inserting sorting is to assume that n-1-1 nodes in the linked list are already key values.
(That is, the field sorted with it, we take the student number num as the key value) sort the order, for node N in
Find the insert position in the sequence so that the new sequence is still ordered after N is inserted. According to this idea
You can execute the chain table from start to end to change the unordered chain table to an ordered chain table.
The following figure shows the direct insertion and sorting of a one-way linked list:
----> [1] ----> [3] ----> [2]... ----> [N] ----> [null] (original linked list)
Head 1-> next 3-> next 2-> next N-> next
----> [1] ----> [null] (retrieve 1st nodes from the original linked list as an ordered linked list with only one node)
Head
Figure 11
----> [3] ----> [2]... ----> [N] ----> [null] (the original linked list contains the nodes used for direct insertion and sorting)
First 3-> next 2-> next N-> next
Figure 12
----> [1] ----> [2] ----> [3]... ----> [N] ----> [null] (sorted linked list)
Head 1-> next 2-> next 3-> next N-> next
Figure 13: Direct insertion and sorting of linked lists with N nodes
1. First, use the first node as an ordered linked list in the original linked list, and the remaining nodes as undetermined nodes.
2. Fetch nodes from the linked list in Figure 12 and locate the insertion in the linked list in Figure 11.
3. Although two linked lists are drawn in the figure above, there is actually only one linked list. In sorting, only one header pointer first is added to point to the remaining nodes.
Please be sure to clarify this point, or you may think it is the same as the preceding sorting method.
*/
Struct student * insertsort (struct student * head)
{
Struct student * First;/* left the node header pointer for direct insertion of sorting in the original linked list */
Struct student * t;/* Temporary pointer variable: insert node */
Struct student * P;/* Temporary pointer variable */
Struct student * q;/* Temporary pointer variable */
First = head-> next;/* The original linked list is left with the node linked list for direct insertion and sorting: it can be understood according to Figure 12. */
Head-> next = NULL;/* ordered linked list containing only one node: see Figure 11. */
While (first! = NULL)/* traverse the unordered linked list */
{
/* Note: here the for statement is the place where the sort idea is inserted directly */
For (t = first, q = head; (Q! = NULL) & (Q-> num <t-> num); P = Q, q = Q-> next ); /* unordered nodes are inserted in the ordered linked list */
/* Exit the for loop, that is, locate the insert position */
/* Note: In principle, this sentence can be placed in the position annotated below, but it cannot. Cause: If you understand the above 3rd items, you will know. */
First = first-> next;/* the node in the unordered linked list leaves, so that it is inserted into the ordered linked list. */
If (q = head)/* inserted before the first node */
{
Head = T;
}
Else/* P is the precursor of Q */
{
P-> next = T;
}
T-> next = Q;/* insert operation completed */
/* First = first-> next ;*/
}
Return head;
}
/*
======================================
Function: bubble sort (from small to large)
Return: pointer to the table header of the linked list.
======================================
*/
/*
The basic idea of directly inserting sorting is to directly insert all nodes in the range not sorted yet,
Compares and adjusts two adjacent nodes from top to bottom to enable the key value (that is
For the ordinal field, we take the student number num as the key value) The larger node is sunk, and the smaller key value is
. That is, when two adjacent nodes compare and find that they have different sorting requirements,
They are exchanged.
The Bubble Sorting icon of the one-way linked list:
----> [1] ----> [3] ----> [2]... ----> [N] ----> [null] (original linked list)
Head 1-> next 3-> next 2-> next N-> next
----> [1] ----> [2] ----> [3]... ----> [N] ----> [null] (sorted linked list)
Head 1-> next 2-> next 3-> next N-> next
Figure 14: Bubble Sorting of linked lists with N nodes
The positions of p and q on any two adjacent nodes are displayed as follows:
If P1-> next points to P, it is clear that P1-> next points to Q,
P1-> next point to the next node of Q. We use p2 to save
P1-> next pointer. That is, P2 = p1-> next, there are:
[] ----> [P] ----------> [Q] ----> [] (Before sorting)
P1-> next P1-> next P2-> next
Figure 15
[] ----> [Q] ----------> [p] ----> [] (after sorting)
Figure 16
1. After sorting, the Q node points to the P node. before adjusting the direction, we need to save the point to the node address of the original P, that is, P2 = p1-> next;
2. Follow this step to push down. After sorting, in Figure 16, P1-> next refers to P2-> next, so P1-> next = P2-> next;
3. In Figure 15, P2-> next is the original direction of Q. After sorting, the point of Q in Figure 16 changes to P, the original P1-> next points to P, so P2-> next = p1-> next;
4. In Figure 15, P1-> next is originally directed to P. After sorting, P1-> next is directed to Q in Figure 16. The original P1-> next (P2) is directed to Q, so P1-> next = P2;
5. At this point, we have completed the sequential exchange of adjacent two nodes.
6. The following program description improves the record of the position of the last sinking node, so that we do not have to scan from start to end each time, but only need to scan to the record point.
Because the subsequent steps are sorted.
*/
Struct student * bubblesort (struct student * head)
{
Struct student * endpt;/* control loop comparison */
Struct student * P;/* Temporary pointer variable */
Struct student * P1;
Struct student * P2;
P1 = (struct student *) malloc (LEN );
P1-> next = head;/* Note: we add a node before the first node to facilitate comparison. Because the first node does not have a precursor, we cannot exchange addresses. */
Head = p1;/* point the head to the P1 node. After sorting, release the P1 node */
For (endpt = NULL; endpt! = Head; endpt = P)/* understanding with 6th points */
{
For (P = p1 = head; P1-> next! = Endpt; P1 = p1-> next)
{
If (P1-> next-> num> P1-> next-> num)/* If the key value of the previous node is greater than that of the subsequent node, switch */
{
P2 = p1-> next;/* understanding with 1st points */
P1-> next = P2-> next;/* understanding with 2nd points */
P2-> next = p1-> next;/* understanding with 3rd points */
P1-> next = P2;/* understanding based on the 4th points */
P = p1-> next;/* understanding with 6th points */
}
}
}
P1 = head;/* remove P1 information */
Head = head-> next;/* point the head to the first node after sorting */
Free (P1);/* release P1 */
P1 = NULL;/* If P1 is set to null, no "wild pointer" is generated, that is, pointer variables with uncertain addresses */
Return head;
}
/*
======================================
Function: Insert a node behind an ordered linked list (from small to large)
Return: pointer to the table header of the linked list.
======================================
*/
/*
Insert nodes to an ordered linked list:
----> [Null] (empty ordered linked list)
Head
Figure 18: Empty ordered linked list (empty ordered linked list is a good solution, so you can direct the head to it .)
The following describes an ordered linked list that is not empty.
----> [1] ----> [2] ----> [3]... ----> [N] ----> [null] (ordered linked list)
Head 1-> next 2-> next 3-> next N-> next
Figure 18: ordered linked list with N nodes
There are two scenarios for inserting a node: first, before the first node, and second, before or after another node.
----> [Node] ----> [1] ----> [2] ----> [3]... ----> [N] ----> [null]
Head node-> next 1-> next 2-> next 3-> next N-> next
Figure 19: Insert a node before the first node
----> [1] ----> [2] ----> [3]... ----> [node]... ----> [N] ----> [null]
Head 1-> next 2-> next 3-> next node-> next N-> next
Figure 20: After a node is inserted into another node
*/
Struct student * sortinsert (struct student * head, struct student * node)
{
Struct student * P;/* P stores the address of the node to be checked */
Struct student * t;/* Temporary pointer variable */
If (Head = NULL)/* process an empty ordered linked list */
{
Head = node;
Node-> next = NULL;
N + = 1;/* after insertion, add 1 to the total number of nodes */
Return head;
}
P = head;/* The ordered linked list is not empty */
While (p-> num <node-> num & P! = NULL)/* the student ID of the node pointed to by P is smaller than the student ID of the inserted node, and it is not equal to null */
{
T = P;/* Save the current node's precursor for later judgment */
P = p-> next;/* move a node behind */
}
If (P = head)/* just before inserting the first node */
{
Node-> next = P;
Head = node;
}
Else/* after other nodes are inserted */
{
T-> next = node;/* Add a node */
Node-> next = P;
}
N + = 1;/* after insertion, add 1 to the total number of nodes */
Return head;
}
/*
The test code is as follows:
*/
/* Test selectsort (): remove the comment block during compilation */
/*
Head = selectsort (head );
Print (head );
*/
/* Test insertsort (): remove the comment block during compilation */
/*
Head = insertsort (head );
Print (head );
*/
/* Test bubblesort (): remove the comment block during compilation */
/*
Head = bubblesort (head );
Print (head );
*/
/* Test sortinsert (): Create a linked list above. When entering a node, pay attention to the order in which the student ID num is ascending. Remove the comment block during compilation */
/*
Stu = (struct student *) malloc (LEN );
Printf ("/nplease input insert node -- num, score :");
Scanf ("% lD, % F", & stu-> num, & stu-> score );
Head = sortinsert (Head, Stu );
Free (Stu );
Stu = NULL;
Print (head );
*/