算法概述:
快速排序与归并排序一样,它们的思想都是一种分而治之的思想。快速排序顾名思义它的速度非常快,同时它没有归并排序那么稳定。原因就在于快速排序实现的基础是递归,递归在处理时要开辟很多堆栈以外的内存,所以在处理小数量的数据时,快速排序可能未必有简单排序快。
实现
第一步:选主元,主元如何选择对快速排序来说十分重要,主元选的不好十分影响他的速度。选主元的方法有很多种,最直接了当的就是以数组中第一个元素为主元。但这样也最复杂,因为我们需要不断遍历后面n-1个元素。所以最好的情况每次选的主元都在这个数组中间 即中分元素。这样可以保证我们分出来的左右两部分都是原来的1/2。选主元的方法。取头,中,尾三个数的中位数。
第二步:集合的划分:集合划分。先将找到的主元放在最右边利用两个指针。一个从头开始遍历(i),一个从主元的前一个元素开始向前遍历(j)。向后遍历的索引遇到比主元大的要停住,向前遍历的遇到比主元小的要停住。两索引同时停住时,交换对应元素,遍历继续。最后当i-j>0时结束。此时交换主元和i索引的对应元素。当数组中有元素与主元相同时选择交换,这样虽然做了许多无用的交换,但保证了主元在中间每次都将序列分成2个长度为n/2的序列。
代码
对数字:
package edu.xalead;
/**
* 1.选主元
* 2.根据主元集合划分
* 3.合并。
*/
public class 快速排序 {
public static int zhaozhuyaun(int []a,int left,int right){
int mid=(left+right)/2;
int temp=0;
if(a[left]>a[mid]){
temp=a[left];
a[left]=a[mid];
a[mid]=temp;
}
if(a[left]>a[right]){
temp=a[left];
a[left]=a[right];
a[right]=temp;
}
if(a[mid]>a[right]){
temp=a[mid];
a[mid]=a[right];
a[right]=temp;
}
temp=a[mid];
a[mid]=a[right-1];
a[right-1]=temp;
return a[right-1];
}
public static void Quitsort(int a[],int left,int right){
int provit=zhaozhuyaun(a,left,right);
int i=left;
int j=right-1;
int temp=0;
for (;;){
while (a[++i]<provit){ }
while (a[--j]>provit){ };
if(i<j){
temp=a[i];
a[i]=a[j];
a[j]=temp;
}else{
break;
}
}
temp=a[i];
a[i]=a[right-1];
a[right-1]=temp;
if(i==1){
return;
}
Quitsort(a,left,i-1);
Quitsort(a,i-1,right);
}
public static void main(String[] args) {
int a[]={20,89,96,75,12};
Quitsort(a,0,a.length-1);
for(int k=0;k<a.length;k++){
System.out.print(a[k]+" ");
}
}
}
运行结果:
对对象进行排序:需要实现Comparable接口:Student类
package edu.xalead;
public class Student implements Comparable{
public Student(String name, int id, char sex) {
this.name = name;
this.id = id;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
", sex=" + sex +
'}';
}
private String name;
private int id;
private char sex;
@Override
public int compareTo(Object o) {
if(o instanceof Student){
Student s=(Student)o;
if(this.id>s.id) return 1;
if(this.id<s.id) return -1;
return 0;
}
throw new RuntimeException("类型不匹配无法比较");
}
}
排序算法:
package edu.xalead;
import java.util.ArrayList;
public class 快速排序2 {
public static void swap(ArrayList a,int index1,int index2){
Student s= (Student) a.get(index1);
a.set(index1,a.get(index2));
a.set(index2,s);
}
public static Student zhaozhuyaun(ArrayList a, int left, int right){
int mid =(left+right)/2;
Comparable o1=(Comparable)a.get(left);
Comparable o2=(Comparable)a.get(mid);
if(o1.compareTo(o2)==1){
swap(a,left,mid);
}
Comparable o3=(Comparable)a.get(left);
Comparable o4=(Comparable)a.get(right);
if(o3.compareTo(o4)==1){
swap(a,left,right);
}
Comparable o5=(Comparable)a.get(mid);
Comparable o6=(Comparable)a.get(right);
if(o5.compareTo(o6)==1){
swap(a,mid,right);
}
swap(a,mid,right-1);
Student aa= (Student) a.get(right-1);
return aa;
}
public static void QuickSort(ArrayList a,int left,int right){
Student provit=zhaozhuyaun(a,left,right);
int i=left;
int j=right-1;
for (;;) {
while (((Comparable)a.get(++i)).compareTo(provit) == -1) {}
while (((Comparable)a.get(--j)).compareTo(provit) == 1) {}
if (i < j) {
swap(a, i, j);
} else {
break;
}
}
swap(a,i,right-1);
if(i==1) return;
QuickSort(a,left,i-1);
QuickSort(a,i-1,right);
}
public static void main(String[] args) {
ArrayList a=new ArrayList();
a.add(new Student("zhangsan",105,'M'));
a.add(new Student("lisi",102,'F'));
a.add(new Student("wangmazi",103,'M'));
QuickSort(a,0,a.size()-1);
System.out.println(a);
}
}
运行结果: