使用插入排序对链表进行排序。
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * } */ public class Solution { /** * 需要使用插入排序, 1.创建头节点为虚节点,将虚节点指针指向原头节点 2.循环 从原头节点第二个node开始 往前 判断,是否存在比该节点大得数据,存在则交换指针, 3.每循环一次,都需要将记录下次需要遍历node得引用, * @param head ListNode类 * @return ListNode类 */ public ListNode insertionSortList (ListNode head) { if(head==null||head.next==null)return head; //创建头节点 ListNode tempNode =new ListNode(0); //连接指针 tempNode.next=head; //从第二个节点开始遍历是否需要插入 ListNode current =head.next; //设置引用对象,交换指针得时候需要有 3个节点得指针变动, //pre节点得next指向currentNode, //currentNode得上一节点得next需要指向currentNode得next //currentNode得next指向pre节点得next //如果需要指针变动,则会把当前节点插入到前面,所以currentLast指针不用变动, //如果不需要指针变动,则下次循环得时候currentLast指针为currentLast得next节点 ListNode next,pre,currentLast=head; while (true){ pre=tempNode; if(current==null)break; next=current.next; while (pre.next.val<current.val){ pre=pre.next; } if(pre.next!=current){ //交换 1,2,3,4, currentLast.next = next; current.next =pre.next; pre.next = current; }else{ currentLast = current; } current=next; } return tempNode.next; } }
import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * } */ public class Solution { /** * 找到小的节点,然后从开头遍历插入改节点 * @param head ListNode类 * @return ListNode类 */ public ListNode insertionSortList (ListNode head) { if (head == null || head.next == null){ return head; } //记录从头部节点开始进行插入后面一个较小的值,插入完成后重置执行head ListNode p = head; //设置哨兵节点,用于记录头部 ListNode preHead = new ListNode(0); preHead.next = head; //记录前一个节点 ListNode pre = head; //比较的当前节点,从第二个开始比较 ListNode cur = head.next; while (cur != null){ //找到小的节点 if (cur.val < pre.val){ //切分当前节点 ListNode temp = cur; pre.next = cur.next; cur.next = null; cur = pre.next; //循环从前往后插入该节点 ListNode pr = preHead; while (p != cur){ if (temp.val < p.val){ pr.next = temp; temp.next = p; break; } p = p.next; pr = pr.next; } //重置 p = preHead.next; }else { cur = cur.next; pre = pre.next; } } return preHead.next; } }
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode insertionSortList(ListNode head) { if(head == null || head.next == null){ return head; } ListNode newHead = new ListNode(0);//新建一个链表表头 ListNode cur = head.next;//原链表上的指针 //将原链表的表头即第一个节点从原链表上断开,并接到新链表上 head.next = null; newHead.next = head; ListNode newCur = newHead.next;//新链表上的指针 //依次取出原链表中的节点,从原链表上断开之后按顺序插入新链表上对应的位置 while(cur != null){ ListNode node = cur;//取出cur所指向的原链表中的当前节点node cur = cur.next;//cur指针后移一位 node.next = null;//将node从原链表上断下来 if(node.val >= newCur.val){ //如果node的值比新链表尾节点(即newCur所指节点)的值大或相等,则直接插在新链表末尾即可 newCur.next = node; newCur = newCur.next;//注意别忘了将新链表指针newCur后移一位 }else{ //如果node的值比新链表尾节点(即newCur所指节点)的值小,则从新链表首节点的下一节点开始查找第一个next节点的值比node值大的节点 ListNode p = newHead; //依次向后遍历,直到p的值比node值小,但p.next的值比node值大时为止,这时node应该插在p节点后面 while(p.next.val<node.val){ p = p.next; } //把node插在p节点后面即可 node.next = p.next; p.next = node; } } //注意返回的是newHead的下一个节点才是真正的首节点 return newHead.next; } }
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode insertionSortList(ListNode head) { if(head==null||head.next==null) return head; ListNode tail,nex,i,t; tail=head; nex=head.next; tail.next=null; out: while(nex!=null){ t=nex; nex=nex.next; if(t.val<head.val){ t.next=head; head=t; } else{ i=head; while(i.next!=null){ if(t.val<i.next.val){ t.next=i.next; i.next=t; continue out; } i=i.next; } t.next=i.next; i.next=t; } } return head; } }
public class Solution { public ListNode insertionSortList(ListNode head) { if (head == null || head.next == null) return head; // pre指向有序表的尾部节点 ListNode pre = head; // cur指向待排序表头部的节点 ListNode cur = head.next; // 辅助节点,用于节点插入 ListNode aux = new ListNode(-1); aux.next = head; while (cur != null) { if (cur.val < pre.val) { // 先把cur节点删除,然后再插到合适位置 pre.next = cur.next; // l1,l2双指针,用于cur节点插入 ListNode l1 = aux; ListNode l2 = aux.next; //从表头往后找到l2.val大于cur.val的地方, //把cur插到l1,l2之间 while (cur.val > l2.val) { l1 = l2; l2 = l2.next; } //把cur节点插入到l1和l2之间 l1.next = cur; cur.next = l2; //指向下一个待处理节点 cur = pre.next; } else { pre = cur; cur = cur.next; } } return aux.next; } }
public class Solution { public ListNode insertionSortList(ListNode head) { if(head==null) return head; ListNode node1=head; ListNode node2=head.next; while(node1.next!=null){ while(node2!=null){ if(node1.val>node2.val){ int tem=node1.val; node1.val=node2.val; node2.val=tem; } node2=node2.next; } node1=node1.next; node2=node1.next; } return head; } }
Sort a linked list using insertion sort.
解题思路就是根据插入排序的思想,每次遍历都保证前n个数都是排好序的,那么按照原生的插入排序,是从当前元素前一个元素开始一个一个往前判断,只要比前面元素小,则往前移动,一直移动到有一个元素小于它或者移动到头部了则停止,这个位置就是当前元素在这一趟中应该在的位置。但是链表中不好往前移,只能每次都从头部开始往后判断,一直找到第一个比当前元素大的元素停止,然后调整一下指针,就是让当前元素插入到本趟合适的位置。由于有可能要与第一个元素交换,所以搞一个虚拟头节点处理起来会简单一点。
class Solution {
public ListNode insertionSortList(ListNode head) {
//1.判断一下
if(head == null || head.next == null){
return head;
}
//2.新建一个虚拟节点,后面要用
ListNode dummy = new ListNode(0);
//3.curr指向的节点及其后面所有节点都是未排序的,前面的都是排好序的
ListNode curr = head;
while(curr != null){
//4.每次循环,pre都重新指向dummy,dummy后一个节点到curr前一个节点都是排好序的
ListNode pre = dummy;
//5.保存一下当前节点后面一个节点的引用
ListNode next = curr.next;
//6.每次都从dummy节点下一个开始找,前面都是排好序的,如果小于当前节点则指针后移,一直找到pre.next为空
//或者比当前节点大的时候,停止,表明pre的下一个节点就是当前节点应该放的位置
while(pre.next != null && pre.next.val < curr.val){
pre = pre.next;
}
//7.找到当前节点应该放的位置之后,下面的工作就是移动指针,让curr插到pre和pre.next中间
//然后让curr后移一位,前面都是排好序的
curr.next = pre.next;
pre.next = curr;
curr = next;
}
//8.dummy后面就是我们所需要的用插入排序排好序的链表
return dummy.next;
}
}
import java.util.*; public class Solution { public static ListNode insertionSortList(ListNode head) { ListNode L=head; ListNode SL=head; if(head==null||head.next==null) return head; else{ int i=0; ArrayList al=new ArrayList(); while(head!=null){ al.add(head.val); head=head.next; } int[] a= new int[al.size()]; for(i=0;i<al.size();i++) { a[i]=(int) al.get(i); } getInsertSort(a);//和上一题一样,只不过换了一个排序算法,主方法里面几乎没变。 for(i=0;i<a.length;i++) { L.val=a[i]; L=L.next; } } return SL; } public static void getInsertSort(int[] a) { int n = a.length;//将数组的长度赋给n是为了防止每次for循环中判断时都调用length方法影响性能 int temp;//放于for循环外面是为了防止重复创建变量 int j; for(int i = 1; i < n;i++){//排序的趟数 temp = a[i];//赋给temp是为了防止索引i之前的元素向后移动覆盖了索引i的元素 j = i-1; for(; j>=0&&a[j]>temp; --j) {//将大于i位置元素的元素向后移 a[j+1] = a[j]; } a[j+1]= temp;//找到i应该在的位置,将值放置此处 } } }
public ListNode insertionSortList(ListNode head) { if (head == null || head.next == null) { return head; } // 9->8->12->6->18,sortNode为要比较的 ListNode sortNode = head.next; ListNode tempNode = new ListNode(-1); // 要替换的前一个tempNode ListNode preNode; tempNode.next = head; // 将head的后面设置为null head.next = null; while (sortNode != null) { ListNode tempNodeCopy = tempNode.next; ListNode next = sortNode.next; preNode = tempNode; while (tempNodeCopy != null && tempNodeCopy.val <= sortNode.val) { preNode = preNode.next; tempNodeCopy = tempNodeCopy.next; } preNode.next = sortNode; sortNode.next = tempNodeCopy; sortNode = next; } return tempNode.next; }
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode insertionSortList(ListNode head) { if (head == null || head.next == null) { return head; } ListNode myHead = new ListNode(Integer.MIN_VALUE); ListNode tmpNode = head; while (tmpNode != null) { ListNode indexNode = myHead; for (; indexNode.next != null && indexNode.next.val < tmpNode.val; indexNode = indexNode.next) { } ListNode nextNode = tmpNode.next; tmpNode.next = indexNode.next; indexNode.next = tmpNode; tmpNode = nextNode; } return myHead.next; } }
public ListNode insertionSortList(ListNode head) { if(head==null || head.next==null) return head; ListNode q=head.next ; while(q!=null) { ListNode t=head; while(t!=q) { if(t.val>q.val) { int tmp=t.val; t.val=q.val; q.val=tmp; } t=t.next; } q=q.next; } return head; }
/** 由于不能直接判断两个结点是否相等,因此用两个整数指标来判断每次的迭代是否到达当前有序* 队列的队尾;用结点分别记录有序部分的迭代结点前面的结点和队尾结点,方便插入操作*/public class Solution { public ListNode insertionSortList(ListNode head) { if (head == null || head.next == null) return head; //为了避免处理当前结点最小,需要更换头结点的特殊情况,//添加哑结点,值为最小整数,作为头结点 ListNode dumy = new ListNode(Integer.MIN_VALUE); dumy.next = head; ListNode first;//first表示前面有序部分的迭代结点 ListNode second;//second表示将要向前面有序部分链表插入的结点//分别记录first前面的一个节点和有序部分的尾结点ListNode beforeFirst, tmpTail; beforeFirst = dumy; tmpTail = dumy; int i, j;//用于判断first结点是否到达有序部分队尾 for (second = dumy.next, i = 1; second != null; ++ i) { for (first = dumy, j = 0; j < i; beforeFirst = first, first = first.next, ++ j) { //如果second结点值比某一个first结点值小,//则将second结点值插入beforeFirst和first结点中间,并跳出内循环 if (first.val > second.val) { tmpTail.next = second.next;//将second结点插入beforeFirst与first之间second.next = first;beforeFirst.next = second; break; } }//说明second结点值比当前有序链表中值都大,则直接添加second在有序链 if (i == j)表最后,并更新尾结点 tmpTail = second; second = tmpTail.next;//更新要插入的结点 } return dumy.next; } }
/* 手动模拟插入排序的过程啊,用h节点来遍历,temp1节点寻找插入的位置,找到后用temp2记录要插入的位置, 之后将整个链表后移到当前元素所在位置,后移的时候使用val来记录下一个节点原来的值。 */ public ListNode insertionSortList(ListNode head) { ListNode h = head; while(h!=null){ ListNode temp1 = head; while(temp1 != h && temp1.val <= h.val){ temp1 = temp1.next; } if(temp1!=null && temp1 != h){ ListNode temp2 = temp1; int val = temp1.val; while(temp1 != h){ temp1.next.val ^= val;val ^= temp1.next.val;temp1.next.val ^= val; temp1 = temp1.next; } temp2.val = val; } h = h.next; } return head; }
//使用插入排序,将一个链表进行排序 //思路:插入排序的思路是将一个数字插入到一个已经排序好的序列中,本题目中是链表 //所以我们可以新建一个链表,之后新链表中存放排序好的节点。循环遍历原链表,依次 // 在新链表中进行比较,之后进行插入操作 public class Solution { public ListNode insertionSortList(ListNode head) { if(head == null || head.next==null){ return head; } //创建一个新节点(头结点),保存排序好的节点 ListNode sortNode = new ListNode(0); ListNode pCur = head; //ListNode sortHead = sortNode; while(pCur != null){ //保存当前节点的下一个节点 ListNode nodeNext = pCur.next; //得到排序好的链表的头指针 ListNode sortHead = sortNode; //寻找插入位置 while(sortHead.next != null && sortHead.next.val < pCur.val){ sortHead = sortHead.next; } //找到位置将pCur进行插入到有序链表中 pCur.next = sortHead.next; sortHead.next = pCur; //更新pCur节点 pCur = nodeNext; } return sortNode.next; } }