user-0 提问: 软考的一道直接插入排序题有答案和解析但是看不懂

回复:
user: user-1
content: 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

user: user-0
content: 引用 1 楼 user-2 的回复：#include <stdio.h>  typedef struct node { 	char data; 	struct node* next; } NODE;  void print_list(char c, NODE* list) { 	printf("%c: ", c); 	while (list) { 		printf("[%d]->", list->data); 		list = list->next; 	} 	printf("NULL\n"); }  NODE* insert_sort(NODE* h) { 	NODE *t, *s, *u = NULL, *v; 	s = h->next; 	h->next = NULL; 	print_list('s', s); 	print_list('h', h); 	printf("\n"); 	while (s != NULL) { 		for (t = s, v = h; v != NULL && v->data < t->data; u = v, v = v->next) { 			; 		} 		s = s->next; 		if (v == h) { 			h = t; 		} else { 			u->next = t; 		} 		t->next = v; 		print_list('s', s); 		print_list('h', h); 		print_list('t', t); 		print_list('v', v); 		print_list('u', u); 		printf("\n"); 	} 	return h; }  NODE* insert(NODE* LIST, int n) { 	NODE* node = (NODE*)malloc(sizeof(NODE)); 	node->data = n; 	node->next = NULL; 	if (LIST) { 		node->next = LIST; 	} 	LIST = node; 	return LIST; }  int main() { 	NODE* list; 	list = NULL; 	list = insert(list, 1); 	list = insert(list, 5); 	list = insert(list, 4); 	list = insert(list, 2); 	list = insert(list, 3); 		 	printf("LIST"); 	print_list(' ', list); 	printf("\n\n");  	list = insert_sort(list);  	printf("LIST"); 	print_list(' ', list); 	printf("\n\n");  	return 0; }  输出结果为： LIST : [3]->[2]->[4]->[5]->[1]->NULL   s: [2]->[4]->[5]->[1]->NULL h: [3]->NULL  s: [4]->[5]->[1]->NULL h: [2]->[3]->NULL t: [2]->[3]->NULL v: [3]->NULL u: NULL  s: [5]->[1]->NULL h: [2]->[3]->[4]->NULL t: [4]->NULL v: NULL u: [3]->[4]->NULL  s: [1]->NULL h: [2]->[3]->[4]->[5]->NULL t: [5]->NULL v: NULL u: [4]->[5]->NULL  s: NULL h: [1]->[2]->[3]->[4]->[5]->NULL t: [1]->[2]->[3]->[4]->[5]->NULL v: [2]->[3]->[4]->[5]->NULL u: [4]->[5]->NULL  LIST : [1]->[2]->[3]->[4]->[5]->NULL  这题因为印刷排版和变量短名极不友好，我这里给你详细解析insert_sort函数里的逻辑。  首先传入一个NODE* h，加上临时指针 t s u v，这些指针既是链表的首元素，也可以是整个链表。  程序的19 20行 	s = h->next; 	h->next = NULL; 这两句，实际上把传入的h链表一分为二成为两个链表。 h作为一个有序链表，保留原来的第一个元素。s为无序链表。从第二个元素到最后，此时输出为： s: [2]->[4]->[5]->[1]->NULL h: [3]->NULL  往下走，24行 while (s != NULL) 这个循环的逻辑是遍历s里每一个NODE，比对h找到相应的位置插入。  25行 for (t = s, v = h; v != NULL && v->data < t->data; u = v, v = v->next) 书上有个分号，其实是空的，只执行for里的循环。 t指向s的第一个元素，这个指针不会移动。v指向h，会在比较大小的时候后移。 u在v移动时，会指向移动前的位置。换言之，u和v之间，要插入的位置。 至于插入哪一个，当然是t指向的那一个。  往下走，29行 if (v == h) 如果v指针没移动过，在h的头部插入t。 否则，在u和v之间插入t。  循环处理完s链表，s置空，h完成排序，返回。我靠大神！我慢慢来看

user: user-2
content: #include <stdio.h>  typedef struct node { 	char data; 	struct node* next; } NODE;  void print_list(char c, NODE* list) { 	printf("%c: ", c); 	while (list) { 		printf("[%d]->", list->data); 		list = list->next; 	} 	printf("NULL\n"); }  NODE* insert_sort(NODE* h) { 	NODE *t, *s, *u = NULL, *v; 	s = h->next; 	h->next = NULL; 	print_list('s', s); 	print_list('h', h); 	printf("\n"); 	while (s != NULL) { 		for (t = s, v = h; v != NULL && v->data < t->data; u = v, v = v->next) { 			; 		} 		s = s->next; 		if (v == h) { 			h = t; 		} else { 			u->next = t; 		} 		t->next = v; 		print_list('s', s); 		print_list('h', h); 		print_list('t', t); 		print_list('v', v); 		print_list('u', u); 		printf("\n"); 	} 	return h; }  NODE* insert(NODE* LIST, int n) { 	NODE* node = (NODE*)malloc(sizeof(NODE)); 	node->data = n; 	node->next = NULL; 	if (LIST) { 		node->next = LIST; 	} 	LIST = node; 	return LIST; }  int main() { 	NODE* list; 	list = NULL; 	list = insert(list, 1); 	list = insert(list, 5); 	list = insert(list, 4); 	list = insert(list, 2); 	list = insert(list, 3); 		 	printf("LIST"); 	print_list(' ', list); 	printf("\n\n");  	list = insert_sort(list);  	printf("LIST"); 	print_list(' ', list); 	printf("\n\n");  	return 0; }  输出结果为： LIST : [3]->[2]->[4]->[5]->[1]->NULL   s: [2]->[4]->[5]->[1]->NULL h: [3]->NULL  s: [4]->[5]->[1]->NULL h: [2]->[3]->NULL t: [2]->[3]->NULL v: [3]->NULL u: NULL  s: [5]->[1]->NULL h: [2]->[3]->[4]->NULL t: [4]->NULL v: NULL u: [3]->[4]->NULL  s: [1]->NULL h: [2]->[3]->[4]->[5]->NULL t: [5]->NULL v: NULL u: [4]->[5]->NULL  s: NULL h: [1]->[2]->[3]->[4]->[5]->NULL t: [1]->[2]->[3]->[4]->[5]->NULL v: [2]->[3]->[4]->[5]->NULL u: [4]->[5]->NULL  LIST : [1]->[2]->[3]->[4]->[5]->NULL  这题因为印刷排版和变量短名极不友好，我这里给你详细解析insert_sort函数里的逻辑。  首先传入一个NODE* h，加上临时指针 t s u v，这些指针既是链表的首元素，也可以是整个链表。  程序的19 20行 	s = h->next; 	h->next = NULL; 这两句，实际上把传入的h链表一分为二成为两个链表。 h作为一个有序链表，保留原来的第一个元素。s为无序链表。从第二个元素到最后，此时输出为： s: [2]->[4]->[5]->[1]->NULL h: [3]->NULL  往下走，24行 while (s != NULL) 这个循环的逻辑是遍历s里每一个NODE，比对h找到相应的位置插入。  25行 for (t = s, v = h; v != NULL && v->data < t->data; u = v, v = v->next) 书上有个分号，其实是空的，只执行for里的循环。 t指向s的第一个元素，这个指针不会移动。v指向h，会在比较大小的时候后移。 u在v移动时，会指向移动前的位置。换言之，u和v之间，要插入的位置。 至于插入哪一个，当然是t指向的那一个。  往下走，29行 if (v == h) 如果v指针没移动过，在h的头部插入t。 否则，在u和v之间插入t。  循环处理完s链表，s置空，h完成排序，返回。