几种链表排序算法的JAVA实现
插入排序
首先解释一下一个概念叫做:前继节点,即我们要的节点的前一个节点。我当时写这个算法的时候一直在犹豫的一点在于我怎么保存下个节点的状态,因为在单向链表中的必须要保存下个节点的状态才能对当前节点进行操作,而另外一点是我应该怎么样利用当前的值和前一个值比较。这是我在做这个题的时候最大的麻烦。参考别人的思路。
插入排序的主要的思想在于:
- 利用一个前继节点的概念去寻找当前值比前一个值大的节点
- 对前面插入的内容进行排序,然后我们每次从第一个节点开始遍历这个链表进行比较然后插入。
插入算法的时间复杂度是O(n^2),空间复杂度是常数项。
public static ListNode insertSortList(ListNode head){
if(head == null || head.next == null) return head;
ListNode root = new ListNode(0);//来记录头结点
root.next = head;
ListNode prevNode = head;//这个是用来作为我们遍历无序链表的前继节点
ListNode orderPrev ;//这个用来存储排序完成的链表的前继节点
ListNode cur;
while(prevNode != null && prevNode.next != null){
if(prevNode.val < prevNode.next.val){//这样的比较就是为了要找到比前继节点大的当前的节点
prevNode = prevNode.next;
}else{
cur = prevNode.next;//如果找到的话,我们需要保存当前节点
prevNode.next = cur.next;//用来保存当前的值的下一个节点,是为了使得下次循环可以实现
/*
下面开始进行插入元素
*/
orderPrev = root;
while(orderPrev.next.val < cur.val){
orderPrev = orderPrev.next;
}
/**
当找到前继节点以后,注意在链表中怎么才能原地插入元素。
*/
cur.next = orderPrev.next;
orderPrev.next = cur;
}
}
return root.next;
}
public static void main(String[] args){
ListNode l1 = new ListNode(-1);
ListNode l2 = new ListNode(5);
ListNode l3 = new ListNode(3);
ListNode l4 = new ListNode(4);
ListNode l5 = new ListNode(0);
l1.next = l2;
l2.next = l3;
l3.next = l4;
l4.next = l5;
l5.next = null;
ListNode head = insertSortList(l1);
while(head != null){
System.out.printf(head.val+" ");
head = head.next;
}
}
归并排序
归并排序的时间复杂度是O(nlogn)空间复杂度是常数项
归并排序的主要思想在于:
- 利用快慢指针的方法,找到中间的节点
- 然后进行归并排序,归并排序的具体内容在上面的博客有介绍。(归并排序的重点在于:我们要确定递归切分的退出的条件在这里是(head == null || head.next != null)还有就是归并时候:要注意退出的条件)
public ListNode sortList(ListNode head){
if(head == null || head.next == null) return head;
ListNode slow = head;
ListNode fast = head;
while(fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
ListNode right = slow.next;
slow.next = null;
ListNode left = sortList(head);
right = sortList(right);
head = mergeList(left,right);
return head;
}
public ListNode mergeList(ListNode left,ListNode right){
if(left == null){
return right;
}
if(right == null){
return left;
}
ListNode result = null;
if(left.val < right.val){
result = left;
left.next = mergeList(left.next,right);
}else{
result = right;
right.next = mergeList(left,right.next);
}
return result;
}
public static void main(String[] args){
ListNode l1 = new ListNode(-1);
ListNode l2 = new ListNode(5);
ListNode l3 = new ListNode(3);
ListNode l4 = new ListNode(4);
ListNode l5 = new ListNode(0);
l1.next = l2;
l2.next = l3;
l3.next = l4;
l4.next = l5;
l5.next = null;
ListNode head = sortList(l1);
while(head != null){
System.out.printf(head.val+" ");
head = head.next;
}
}