插入排序需要从后往前遍历寻找可以插入的位置,所以会使用到双向链表
typedef struct Node//定义的结构体
{
int data;
struct Node* per; //记录前驱
struct Node* next;
}*List;
创建带头节点的双链表
List create_list()
{
List head = (List)malloc(Size);//#define Size sizeof(struct Node)
List p, q = head;
if (head)
{
head->next = NULL;
}
printf("请输入数据(输入-1结束):");
for (int i = 0;; i++)
{
p = (List)malloc(Size);
if (p)
{
scanf_s("%d", &p->data);
p->per = q;
p->next = NULL;
if (p->data == -1)
{
break;
}
}
if (head && i == 0)
{
head->next = p;
q = p;
}
else if (q)
{
q->next = p;
q = p;
}
}
return head;
}
重点来了,排序函数如下:
void insert_sort(List head)//插入排序,传入头节点
{
List p = head->next, q, temp;
if (p)
{
for (p = p->next; p; p = p->next)//从第二个数开始,第一个数默认有序
{
temp = p;
for (q = p->per; q != head; q = q->per)//q从p的前一节点开始往前遍历
{
if (q->data <= temp->data)//升序
{
break;
}
}
if (q->next != p)//如果q有前移,插入temp
{
if (temp->next)//temp不为最后一个节点
{
//temp前后互指,分离temp
temp->per->next = temp->next;
temp->next->per = temp->per;
//插入temp
temp->next = q->next;
q->next->per = temp;
temp->per = q;
q->next = temp;
}
else //temp是最后一个节点
{
temp->per->next = NULL;//temp前一节点的next指为NULL
//插入temp
temp->next = q->next;
q->next->per = temp;
temp->per = q;
q->next = temp;
}
}
}
printf("已排序\n");
}
else
{
printf("链表为空\n");
}
}
怕你们懒,打印链表的函数也写一下吧
void print_list(List head)
{
List p = head->next;
if (p)
{
printf("链表中的数据:");
for (; p; p = p->next)
{
printf("%d ", p->data);
}
putchar('\n');
}
else
{
printf("链表为空\n");
}
}
程序结束前可不要忘了销毁链表
void destory_list(List head)
{
List p = head, q;
while (p)
{
q = p->next;
free(p);
p = q;
}
}
头文件,函数声明,main函数也贴一下
#include<stdio.h>
#include<stdlib.h>
#define Size sizeof(struct Node)
List create_list();
void print_list(List head);
void insert_sort(List head);
void destory_list(List head);
int main(void)
{
List head = create_list();
print_list(head);
insert_sort(head);
print_list(head);
destory_list(head);
return 0;
}
可以先复制粘贴运行一下,试试写的对不对,有问题还请指出,谢谢。