#include
#include
#include
typedef struct data{ /*链表节点*/
int id;
struct data *next;
}DATA;
void list_init(DATA *data) /*链表初始化*/
{
data->id = 0;
data->next = NULL;
}
void list_insert(DATA *head, DATA *node) /*malloc一个节点, 并拷贝数据插入到链表中*/
{
DATA *e = (DATA *)malloc(sizeof(DATA));
if (!e){
perror("malloc");
return ;
}
e->id = node->id; //拷贝数据
while (head->next)
head = head->next; //插入链表末尾
head->next = e;
e->next = NULL;
}
void list_reverse(DATA *head) //链表逆序, 本例子中头节点不存数据, 故只逆序头节点以外的节点
{
DATA *list1, *list2, *list3;
list1 = head->next;
list2 = list1->next;
while (list2)
{
list3 = list2->next;
list2->next= list1;
list1 = list2;
list2 = list3;
}
head->next->next = NULL; //head的下一个及为遍历时的第一节点也即逆序后的最后一个数据节点,链表的尾巴, 故这个数据节点的next要为空。
head->next = list1; //此时, list2为空,list2的上一个节点为list1, 故list1为遍历时的最后一个数据节点也即逆序后的第一个节点,故设置head的下一个为list1
}
void list_sort(DATA *head) //链表排序, 排序头结点以外的数据节点
{
DATA *phead = head; //遍历单链表, 并将遍历的每个节点插入到新链表中, 新链表头和原链表头是同一个节点
DATA *list = head->next;
DATA *tmp; //暂存遍历原链表的数据节点的下一个节点
phead->next = NULL; //新链表头的下一节点初始化为空
while (list){
tmp = list->next; //保存原链表数据节点的下一节点
while (phead->next){ //遍历新链表找到插入的位置
if (phead->next->id > list->id)
break;
phead = phead->next;
}
list->next = phead->next; //将原链表数据节点插入到新链表中
phead->next = list;
list = tmp; //将下一个原链表数据节点取出来
phead = head; //赋值新链表头位置, 便于下一次遍历新链表查找位置
}
}
void list_display(DATA *head)
{
DATA *plist = head->next;
while (plist)
{
printf("%-3d ", plist->id);
plist = plist->next;
}
printf("\n");
}
void list_free(DATA *head)
{
DATA *e;
head = head->next;
while (head){
e = head;
head = head->next;
free(e);
}
}
#ifdef TEST
DATA g_head;
int main(int c, char **v)
{
DATA node;
int i;
list_init(&g_head);
srand(10);
for (i = 0; i < 10; i++){
node.id = rand()%100;
list_insert(&g_head, &node);
}
list_display(&g_head);
list_reverse(&g_head);
list_display(&g_head);
list_sort(&g_head);
list_display(&g_head);
list_free(&g_head);
return 0;
}
#endif