1. 各种排序的主要操作
与数组相比,链表随机访问特性较差,直接交换两个节点比较困难,但是插入和删除节点比较方便,因而链表排序中多使用到节点的插入和删除操作。
冒泡排序:时间复杂度O(n^2) 主要操作时链表中相邻的两个节点交换
插入排序:时间复杂度O(n^2) 主要操作时将链表中的某个节点插入到链表中指定的节点的前面
归并排序:时间复杂度O(nlgn) 空间复杂度O(lgn)主要操作是合并两个有序的链表
快速排序:平均时间复杂度O(nlgn),最坏时间复杂度O(n^2) 平均空间复杂度O(lgn) 最坏空间复杂度O(n) (最坏时间和空间复杂度均为链表有序的情况) 链表快排主要操作是将划分操作,每次划分操作都是遍历某段链表然后将关键字小于划分值的链表节点删除并插入到划分值所在的节点之前。
2.Java实现
import java.util.Random;
class ListNode
{
int val=0;
ListNode next=null;
ListNode(){}
ListNode(int val){this.val = val;}
}
public class LinkedList
{
public ListNode head=null;
public LinkedList(ListNode x){ head=x; }
public void addNode(ListNode x)
{
if(head==null)
{
head=x;
return;
}
else
{
ListNode p=head;
while(p.next!=null)
{
p=p.next;
}
p.next=x;
}
}
public void print()
{
ListNode p=head;
while(p!=null)
{
System.out.print(p.val+" ");
p=p.next;
}
System.out.println();
}
public void bubbleSort()
{
if(head.next==null) return;
int len=0;
ListNode p=head,pre=null;
while(p!=null)
{
len++;
p=p.next;
}
for(int i=len;i>1;i--)
{
pre=null;
p=head;
for(int j=1;j<i;j++)
{
if(p.val>p.next.val)
{
if(pre==null)
{
ListNode next=p.next;
head=next;
p.next=next.next;
next.next=p;
pre=head;
continue;
}
else
{
ListNode next=p.next;
pre.next=next;
p.next=next.next;
next.next=p;
pre=pre.next;
continue;
}
}
pre=p;
p=p.next;
}
}
}
public void insertSort()
{
ListNode p=head;
while(p!=null&&p.next!=null)
{
ListNode cur=p.next,pre_cur=p,q=head,pre_q=null;
while(q!=cur)
{
if(q.val>cur.val)
{
pre_cur.next=cur.next;
if(pre_q==null)
{
head=cur;
}
else
{
pre_q.next=cur;
}
cur.next=q;
p=q;//attention
break;
}
pre_q=q;
q=q.next;
}
p=p.next;
}
}
private static ListNode merge(ListNode l,ListNode r)
{
ListNode newHead=null;
if(l==null){return r;}
if(r==null){return l;}
if(l.val<=r.val)
{
newHead=l;
l=l.next;
}
else
{
newHead=r;
r=r.next;
}
ListNode tail=newHead;
while(l!=null||r!=null)
{
if(l==null)
{
tail.next=r;
break;
}
else if(r==null)
{
tail.next=l;
break;
}
else
{
if(l.val<=r.val)
{
tail.next=l;
tail=l;
l=l.next;
tail.next=null;
}
else
{
tail.next=r;
tail=r;
r=r.next;
tail.next=null;
}
}
}
return newHead;
}
public static ListNode mergeHelp(ListNode x)
{
if(x!=null&&x.next!=null)
{
ListNode q=x;
int len=0;
while(q!=null)
{
q=q.next;
len++;
}
int halflen=0,cnt=0;
halflen=len>>1;
q=x;
while(q!=null)
{
cnt++;
if(cnt==halflen)
{
break;
}
q=q.next;
}
ListNode lin=x,rin=q.next;
q.next=null;
ListNode l=mergeHelp(lin);
ListNode r=mergeHelp(rin);
ListNode newHead=merge(l,r);
return newHead;
}
return x;
}
public void mergeSort()
{
head=mergeHelp(head);
}
public static void print(ListNode x)
{
while(x!=null)
{
System.out.print(x.val+" ");
x=x.next;
}
System.out.println();
}
public static ListNode quickSort(ListNode pre_x,ListNode x,ListNode y)
{
if(x!=null&&x.next!=null&&x!=y&&x.next!=y)
{
ListNode key=x;
ListNode p=key.next,pre=key;
while(p!=y)
{
if(p.val<key.val)
{
pre.next=p.next;
p.next=x;
x=p;
if(pre_x!=null)
{
pre_x.next=x;
}
p=pre.next;
}
else
{
pre=p;
p=p.next;
}
}
ListNode newHead=quickSort(pre_x,x,key);
quickSort(key,key.next,y);
return newHead;
}
return x;
}
public static void main(String[] args)
{
Random random=new Random();
ListNode head=new ListNode(random.nextInt(50));
LinkedList mlist=new LinkedList(head);
for(int i=0;i<15;i++)
{
mlist.addNode(new ListNode(random.nextInt(50)));
}
mlist.print();
mlist.head=quickSort(null,mlist.head,null);
System.out.println("After Sort:");
mlist.print();
}
}