y
1、冒泡排序法
难度主要在于如何确定内循环和外循环的结束条件。定义 p,q指针用于遍历链表元素和交换。定义一个tail指针,指向最新一轮冒泡排序的结果。内循环结束的条件是q指针指向tail。外循环结束的条件是head.next==tail,此时只有head一个元素,不需要排序。
时间复杂度:O(n²) 如果有n个元素需要进行n-1,n-2,....1 总共次比较,所以时间复杂度为O(n²) 由于这个原因,在链表或者数组特别大的时候,尽管对冒泡排序进行优化,这种排序算法也是不理想的。一般来讲,我们不能忍受平方级的时间复杂度。
空间复杂度:O(1) 只需要常量级的辅助单位
class Solution {
public ListNode sortList(ListNode head) {
if(head==null||head.next==null) return head;
ListNode tail=null;
int temp=0;
boolean flag=true;//当一轮之后都没有元素交换,这种情况下就结束排序。算是对冒泡的优化
while(flag){
flag=false;
while(tail!=head.next){//外循环:这里的tail定位在冒泡排序最新生成的那个位置,当冒泡到head后一个位置的时候,表示未确定的链表元素就只剩下head,结束冒泡排序。
ListNode p=head;
ListNode q=head.next;
while(q!=tail){//内循环:要对从head到tail的所有元素进行冒泡排序,结束条件是q==tail
if(p.val>q.val){
temp=p.val;
p.val=q.val;
q.val=temp;
flag=true;
}
p=q;
q=q.next;
}
tail=p;//因为一轮冒泡完成,tail指向这一轮的冒泡的结果。
}
}
return head;
}
}
缺点:在跑用例的时候,28/29。当链表很长超过一定长度时候,就会超过时间限制。
-