单链表直接插入排序

点击查看代码
#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

posted @ 2022-09-26 22:58  zhaoo_o  阅读(34)  评论(0编辑  收藏  举报