【双向链表练习】 - 对链表进行插入排序

题目描述

描述
对链表进行插入排序。

示例1

输入:3 -> 1 -> 4 -> 2 -> NULL
输出:1 -> 2 -> 3 -> 4 -> NULL

解题分析:

思路:
插入排序思路算法:
1、插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表
2、每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入
3、重复直到所有输入数据插入完为止。
假设第一个元素为有序,从第二个元素开始,依次取出元素插入,如果比前面的元素小,移动元素,直到找到比它大的元素,插入其后 - 数组的插入排序
取头结点作为一个结点的新的链表,从剩余的节点中不断取值插入到新的链表中。
如何选择最合适的位置插入?每次插入一个数时,都需要从前往后遍历新数组,直到找到一个合适的地方插入(头插、尾插、中间插入)
请添加图片描述

代码实现:

struct ListNode
{
	int val;
	struct ListNode* next;
};
struct ListNode* insertionSortList(struct ListNode* head)
{
	//当为空链表或者只有一个结点的链表时,直接返回
	if (head == NULL || head->next == NULL)
		return head;
	//取原链表头结点作为一个新的链表头结点,
	struct ListNode* sortHead = head;

	//cur是需要取下的剩余链表当前的结点,
	struct ListNode* cur = head->next;

	sortHead->next = NULL;//这一行不能放在struct ListNode* sortHead = head;后面,否则cur为NULL,无法取下一个结点

	//取结点插入
	while (cur)//当cur为NULL,则结点取完了
	{
		struct ListNode* next = cur->next;//next保存下一个结点,防止找不到下一个需要取下的结点

		//把cur插入到sortHead链表中,并保持有序
		if (cur->val <= sortHead->val)//即头插
		{
			cur->next = sortHead;
			sortHead = cur;//变成新的头
		}
		else//中间插入或者尾插
		{
            //sortprev、sortcur指针用于遍历新链表,
			//sortcur用于和cur的比较
            //sortprev用于保存前一个结点,防止链接cur的时候,无法链接
			struct ListNode* sortprev = sortHead;//struct ListNode* sortcur = sortHead;这里赋值,cur不可能插入在sortcur的前面
			struct ListNode* sortcur = sortprev->next;

			//遍历sortcur和cur比较,找到合适的地方插入
			while (sortcur)
			{
				if (cur->val <= sortcur->val)//中间插入 - 插入在sortcur前面
				{
					//sortprev cur sortcur
					sortprev->next = cur;
					cur->next = sortcur;
					break;
                }
				else
				{
					//新链表的sortprev、sortcur迭代
					sortprev = sortcur;
					sortcur = sortcur->next;
				}
			}
			//来到这里可能是break,也可能是sortcur为NULL循环结束
			//尾插
			if (sortcur == NULL)
			{
				sortprev->next = cur;
				cur->next = NULL;//需要置空,否则会形成环
			}
		}
		//原链表的迭代,取下一个结点插入
		cur = next;
    }
	return sortHead;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值