【上机代码】链表插入排序(直接插入)

思路

对数组插入排序时,是两重循环,第一重是从第二个元素开始遍历整个数组,第二个就是反向循环,从当前元素开始向前寻找第一个小于当前数的值,并插到它后面。

但单链表无法反向,所以第二重循环就可以进行正向遍历,找到第一个大于当前结点值的结点,并插到它前面。

借助两个指针sort和unsort,分别指向待排序的第一个元素,和未排序的最后一个元素,且unsort->next==sort。
1,当前元素大于链表第一个元素就直接头插法
2,当前元素不大于第一个元素,就从第二个元素开始遍历已排序的元素(利用p和q两个指针),要么已排序都小于当前元素,则插入尾部。要么找到大于当前元素的节点,插在该节点前即可。

错误点

1,unsort与sort对比是从第二个元素开始遍历,L->next->next开始

2,遍历要遍历完sort中最后一个元素,因为之前只和第一个元素对比过了。

代码

#include<stdio.h>
#include "malloc.h"
#include<stdlib.h>
#include<time.h>
//定义链表结构体
typedef struct LinkList
{
	int data;
	int id;//唯一标识每个节点
	struct LinkList* next;
}LinkList;

//交换链表中两个数据
void swap(LinkList* p, LinkList* min)
{
	int temp = p->data;
	p->data = min->data;
	min->data = temp;
};

void Insertsort(LinkList* L)
{
	LinkList* sort, * unsort, * p, * q;
	if (L != NULL) { //保证链表不为空
		sort = L->next;//指向排序好部分的最后一个元素
		while (sort->next != NULL)//遍历未排序的第一个元素
		{
			unsort = sort->next;//每次循环都指向未排序的第一个元素
			if (unsort->data < L->next->data) { //未排序的元素小于链表第一个元素
				sort->next = unsort->next;//头插法,把第一个未排序的插入表头
				unsort->next = L->next;
				L->next = unsort;
			}
			else
			{
				q = L->next;
				p = q->next;//从第二个元素开始遍历,第一个在上面头插法对比过了
				while (unsort->data >= p->data) {//直到找到p>unsort
					if (p->id == unsort->id)//遍历到unsort就停止,若遍历到unsort前一个就会少对比sort的最后一个元素
						break;
					q = p;
					p = p->next;
				}
				if (p->id == unsort->id) {//遍历到unsort前。说明未排序元素均大于已排序元素,插入队尾
					sort = unsort;
				}
				else//未遍历到unsort前,找到了大于未排序元素的p,插入p前
				{
					sort->next = unsort->next;
					unsort->next = p;
					q->next = unsort;
				}
			}
		}
	}
}

//输出链表节点
void print(LinkList* L)
{
	LinkList* p = L;
	for (int i = 0; i < L->data; ++i)//L为头结点不能动 否则每次遍历就会改变条件
	{
		printf("%d-%d ", p->next->id, p->next->data);

		p = p->next;
	}
}

void test()
{
	//建立链表
	LinkList* L = (LinkList*)malloc(sizeof(LinkList));
	if (L == NULL) {
		printf("内存分配不成功!\n");
	}
	else
	{
		L->data = 10;
		LinkList* p = L;
		srand(time(0));
		for (int i = 0; i < L->data; ++i)
		{
			p->next = (LinkList*)malloc(sizeof(LinkList));
			if (p->next) {
				p = p->next;
				p->data = rand() % 100;//取0-99的随机数  0-99,都为原值,100-199为0-99,以此类推
				p->id = i;
			}
		}
		p->next = NULL;
		printf("原始序列为:\n");
		print(L);
		Insertsort(L);
		printf("\n排序后为:\n");
		print(L);
	}
}

int main()
{
	test();
}

参考:
#数据结构 将带头结点的单链表实现直接插入排序.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

燕南路GISer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值