点击查看代码
#include<iostream>
using namespace std;
//结点定义
struct LNode {
int data;
struct LNode* next;
};
/*
函数功能:创建单链表
函数列表:
head:指向创建的单链表头结点的指针
a[]:待排序序列,将该序列转换为单链表
n:待排序元素个数
main函数只定义了head指针,此时要用引用型head指针,确保malloc分配的内存地址能传给main函数的head
*/
void CreateLink(LNode*& head, int a[], int n) {
head = (LNode*)malloc(sizeof(LNode)); //为单链表头结点分配内存
head->next = NULL; //头结点的next先人为置空
LNode* p, * node; //p指向单链表末尾结点,node指向新建结点
p = head; //单链表初始只有一个头结点,所以p指向头结点
//单链表尾插法,将a[]转变为单链表
for (int i = 0; i < n; i++) {
node = (LNode*)malloc(sizeof(LNode)); //新建一个结点
node->data = a[i]; //存储数组元素值
node->next = p->next; //将node插在p后面
p->next = node; //p指向node
p = node; //node尾插完成后将p移至末尾结点node上,为下一轮尾插做准备
}
}
//输出单链表
void Print(LNode* head) {
LNode* p;
p = head->next;//头结点没有内容不用输出,从头结点的next结点开始输出
//只要p非空就输出
while (p) {
cout << p->data << " ";
p = p->next;//当前结点输出后,p指向下一个结点准备下轮输出
}
cout << endl;
}
/*
函数功能:单链表直接插入排序(升序排序)
函数列表:
head:指向待排序序列头结点的下一个结点
本例单链表第1个结点不是指头结点,而是指头结点的next结点(head->next),
首先将单链表分为有序区和无序区,每轮将无序区的第1个结点插入到有序区中,
注意:单链表插入排序的有序区扫描要从前往后比较,与数组从后往前不同
*/
void InsertSort(LNode* head) {
LNode* pre;//有序区扫描指针
LNode* p;//无序区第1个结点
LNode* q;//无序区第2个结点
p = head->next->next;//p指向无序区第1个结点,即待插入结点
head->next->next = NULL;//在有序区第1个结点后面人为断开,将序列分为有序区和无序区
//只要无序区的待插入结点p非空就进行插入排序
while (p) {
q = p->next;//先用q记录下一个待插结点,防止将p插进有序区后无法找回无序区
pre = head;//单链表插入排序在有序区中要从前往后比较,pre初始指向头结点
//逐个比较有序区的结点,当到达有序区末尾或遇到大于p的结点时,找到插入位置
while (pre->next != NULL && pre->next->data < p->data) {
pre = pre->next;
}
p->next = pre->next;//先将p插在pre后面
pre->next = p;//再将pre指向p,完成有序区排序
p = q;//最后将p指向下一个待插入结点q
}
}
int main() {
int a[] = { 156,212,365,9589,15232,74 };//待排序列
int n = sizeof(a) / sizeof(a[0]);
LNode* head;//定义单链表头结点指针head
CreateLink(head,a, n);//将数组a[]转变为单链表
cout << "序列个数:" << n << endl;
cout << "单链表排序前:";
Print(head);
InsertSort(head); //单链表直接插入排序
cout << "单链表排序后:";
Print(head);
return 0;
}
单链表直接插入排序过程如下图所示
![image](https://img2022.cnblogs.com/blog/2134653/202209/2134653-20220926225932986-632186060.png)