Insertion Sort List对链表进行插入排序

对链表进行插入排序。


插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。

 

插入排序算法:

  1. 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
  2. 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
  3. 重复直到所有输入数据插入完为止。

 

示例 1:

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

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

思路

这道题要求用插入排序的思想对单向链表进行排序,则我们可以构建一个新链表,每次从新链表头结点向后判断应该插入哪个节点,新链表的每个节点插入后都保证有序,如图所示:


红色表示带插入节点,我们首先初始化静态头结点pre_new_head,并且new_head_tmp=pre_new_head,然后比较:

while (new_head_tmp->next && new_head_tmp->next->val <= cur->val)

不断更新new_head_tmp,则最后带插入节点便在new_head_tmp和new_head_tmp->next之间。

这里有个小技巧:不用每次判断都把new_head_tmp=pre_new_head,因为每次节点插入,new_head_tmp总是指向最后一个元素,如下图所示:

若此时带插入的节点是6,则直接插在new_head_tmp后面即可,即我们只有在new_head_tmp->next->val>cur->val时才把new_head_tmp赋值为pre_new_head

if (new_head_tmp->next && new_head_tmp->next->val > cur->val) {
	new_head_tmp = pre_new_head;
}

代码如下:

    ListNode* insertionSortList(ListNode* head) {
	  ListNode* pre_new_head = new ListNode(-1);
	  ListNode* new_head_tmp = pre_new_head;

	  ListNode* cur = head;
	  ListNode* pre_cur = cur;
	  while (cur) {
		  pre_cur = cur->next;
		  if (new_head_tmp->next && new_head_tmp->next->val > cur->val) {
			  new_head_tmp = pre_new_head;
		  }
		  while (new_head_tmp->next && new_head_tmp->next->val <= cur->val) {
			  new_head_tmp = new_head_tmp->next;
		  }
		  cur->next = new_head_tmp->next;
		  new_head_tmp->next = cur;
		  //new_head_tmp = pre_new_head;
		  cur = pre_cur;
	  }
	  return pre_new_head->next;     
    }






猜你喜欢

转载自blog.csdn.net/qq_26410101/article/details/80441737