题目描述
对链表进行插入排序
解题策略
插入排序一般用于数组中,而在链表中,不可以方便的使用标号来确定一个“绝对位置”。仅仅能使用指针来标记一个“相对位置”。
因此,我们要采取不一样的策略。
按照插入排序的思路,首先,我们将链表分为已排序区、待排序区。然后迭代待排序区,一次次将其中的首位元素插入到已排序区的正确位置上。
在链表中,交换元素并不方便,为此,我采取一个策略:即在遍历的时候,当前指针指向待比较节点的父节点,使用父节点来得到下一节点的值,进行比较,这样一来,交换节点的时候就非常方便。
在遍历方式上,可以进一步优化,使用一个指针i
指向已排序区的最后一个节点,如果i->next->val
的值比i->val
小,则表示i->next
节点需要进行插入操作才能进入已排序区,那么就接着遍历已排序区,寻找合适的插入点;否则就将i
往后移动,表示下一个节点可以直接并入已排序区并作为其最后一个节点。
代码
class Solution
{
public:
ListNode *insertionSortList(ListNode *head)
{
ListNode thead(0);
thead.next = head;
for (auto i = head; i->next != nullptr;)
{
int flag = 1;
for (auto j = &thead; j->next != nullptr&&j!=i; j = j->next)
{
if (i->next->val < j->next->val)
{
auto src = i->next;
i->next = src->next;
src->next = j->next;
j->next = src;
flag = 0;
break;
}
}
if (flag)
{
i = i->next;
}
}
return thead.next;
}
};