思路:我们只需要两个指针p和q,这两个指针均往next方向移动,移动的过程中保持p之前的key都小于选定的key,p和q之间的key都大于选定的key,那么当q走到末尾的时候便完成了一次支点的寻找。既然两个指针都是从前往后遍历,那么链表值进行交换就简单了。找到支点后,支点左边和支点右边进行子问题递归,就回到快排原来的思路上去了
C++代码实现:
#include<iostream>
#include<cstdio>
using namespace std;
struct node
{
int key;
node* next;
};
node* GetPartion(node* pBegin,node* pEnd)
{
int key=pBegin->key;
node *p=pBegin;
node *q=p->next;
while(q!=pEnd) //注意是否搜完了整个单链表
{
if(q->key<key)
{
p=p->next;
swap(p->key,q->key);
}
q=q->next;
}
swap(p->key,pBegin->key);
return p;
}
void QuickSort(node* Begin,node* End)
{
if(Begin!=End)
{
node *p=GetPartion(Begin,End);
QuickSort(Begin,p);
QuickSort(p->next,End);
}
}
int main()
{
node *a=new node[5];
a[0].key=1; a[0].next=&a[1];
a[1].key=2; a[1].next=&a[2];
a[2].key=9; a[2].next=&a[3];
a[3].key=4; a[3].next=&a[4];
a[4].key=3; a[4].next=NULL;
QuickSort(&a[0],NULL);
for(int i=0;i<5;i++)
cout<<a[i].key<<" ";
cout<<endl;
delete []a;
return 0;
}
Java代码实现要复杂许多:
1.由于java基本类型"传参”是传的值得拷贝,java对象传参是传的地址引用,所以基本类型数据互换值不能通过参数。
2.基本类型值互换可以通过x=x^y,y=x^y,x=x^y,x=x+y,y=x-y,x=x-y等方式互换值,但是值得注意的是基本数据类型是类的参数,通过对象取值互换时,必须保证两个对象的地址不相等,这在排序中经常用到。
java代码实现:
public class QuickSortTest {
static node GetPartion(node pBegin,node pEnd)
{
int key=pBegin.key;
node p=pBegin;
node q=p.next;
System.out.println(p.hashCode()+" "+q.hashCode());
while(q!=pEnd)
{
if(q.key<key)
{
p=p.next;
if(p!=q)
{
p.key=p.key+q.key;
q.key=p.key-q.key;
p.key=p.key-q.key;
}
}
q=q.next;
}
if(p!=pBegin)
{
p.key=p.key+pBegin.key;
pBegin.key=p.key-pBegin.key;
p.key=p.key-pBegin.key;
}
return p;
}
static void QuickSort(node Begin,node End)
{
if(Begin!=End)
{
node p=GetPartion(Begin,End);
QuickSort(Begin,p);
QuickSort(p.next,End);
}
}
public static void main(String[] args) {
node[] a=new node[5];
for(int i=0;i<5;i++)
a[i]=new node();
a[4].key=3; a[4].next=null;
a[3].key=4; a[3].next=a[4];
a[2].key=9; a[2].next=a[3];
a[1].key=2; a[1].next=a[2];
a[0].key=1; a[0].next=a[1];
QuickSort(a[0],null);
for(int i=0;i<5;i++)
System.out.print(a[i].key+" ");
System.out.println();
}
}
class node{
int key;
node next;
}