直接插入排序
排序过程
整个排序过程为n-1趟插入,即先将序列中第1个记录看成是一个有序子序列,然后从第2个记录开始,逐个进行插入,直至整个序列有序
算法描述
折半插入排序
排序过程
用折半查找方法确定插入位置的排序叫折半插入排序.
算法描述
算法评价
时间复杂度:T(n)=O(n²)
空间复杂度:S(n)=O(1)
希尔排序(缩小增量法)
排序过程
先取一个正整数d1<n,把所有相隔d1的记录放一组,组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止
算法描述
希尔排序特点
l 子序列的构成不是简单的“逐段分割”,而是将相隔某个增量的记录组成一个子序列
l 希尔排序可提高排序速度,因为
u 分组后n值减小,n²更小,而T(n)=O(n²),所以T(n)从总体上看是减小了
u 关键字较小的记录跳跃式前移,在进行最后一趟增量为1的插入排序时,序列已基本有序
l 增量序列取法
u 无除1以外的公因子
u 最后一个增量值必须为1
冒泡排序
排序过程
将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序r[1].key>r[2].key,则交换;然后比较第二个记录与第三个记录;依次类推,直至第n-1个记录和第n个记录比较为止——第一趟冒泡排序,结果关键字最大的记录被安置在最后一个记录上
对前n-1个记录进行第二趟冒泡排序,结果使关键字次大的记录被安置在第n-1个记录位置
重复上述过程,直到“在一趟排序过程中没有进行过交换记录的操作”为止
算法描述
快速排序
基本思想
通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录进行排序,以达到整个序列有序
排序过程
对r[s……t]中记录进行一趟快速排序,附设两个指针i和j,设枢轴记录rp=r[s],x=rp.key
l 初始时令i=s,j=t
l 首先从j所指位置向前搜索第一个关键字小于x的记录,并和rp交换
l 再从i所指位置起向后搜索,找到第一个关键字大于x的记录,和rp交换
l 重复上述两步,直至i==j为止
l 再分别对两个子序列进行快速排序,直到每个子序列只含有一个记录为止
算法描述
简单选择排序
排序过程
l 首先通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换
l 再通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录,将它与第二个记录交换
l 重复上述操作,共进行n-1趟排序后,排序结束
算法描述
堆排序
堆的定义
n个元素的序列(k1,k2,……kn),当且仅当满足下列关系时,称之为堆
排序过程
将无序序列建成一个堆,得到关键字最小(或最大)的记录;输出堆顶的最小(大)值后,使剩余的n-1个元素重又建成一个堆,则可得到n个元素的次小值;重复执行,得到一个有序序列.
算法描述
各排序方法的性能的比较
方法 | 平均时间 | 最长时间 | 附加空间 | 稳定性 |
直接插入 | O(n2) | O(n2) | O(1) | 稳定的 |
Shell排序 | O(n1.3) |
| O(1) | 不稳定的 |
直接选择 | O(n2) | O(n2) | O(1) | 不稳定的 |
堆排序 | O(nlog2n) | O(nlog2n) | O(1) | 不稳定的 |
冒泡排序 | O(n2) | O(n2) | O(1) | 稳定的 |
快速排序 | O(nlog2n) | O(n2) | O(log2n) | 不稳定的 |
归并排序 | O(nlog2n) | O(nlog2n) | O(n) | 稳定的 |
基数排序 | O(d(n+r)) | O(d(n+r)) | O(n+r) | 稳定的 |
排序类的实现
package datastructure.sorter;
import datastructure.common.Strategy;
/**
* 排序
* @author luoweifu
*
*/
public class Sorter implements Strategy {
/**
* 直接插入排序
* @param r 要排序的数组
* @param low 左端点
* @param high 右端点
*/
public void insertSort(Object[] r, int low, int high) {
for(int i=low +1; i<=high; i++) {
//Object strategy;
if(compare(r[i],r[i-1]) < 0) {
Object temp = r[i];
r[i] = r[i-1];
int j = i-2;
for(; j>=low && compare(temp, r[j])<0; j--)
r[j+1] = r[j];
r[j+1] = temp;
}
}
}
/**
* 折半排序
* @param r 要排序的数组
* @param low 左端点
* @param high 右端点
*/
public void binInsetSort(Object[] r, int low, int high) {
for(int i=low+1; i<=high; i++) {
Object temp = r[i]; //保持待插入元素
int hi = i-1; int lo = low; //设置初始区间
while(lo <= hi) { //折半确定插入位置
int mid = (lo + hi)/2;
if(compare(temp, r[mid])<0)
hi = mid -1;
else lo = mid +1;
}
for(int j=i-1; j>hi; j--) r[j+1] = r[j];//移动元素
r[hi+1] = temp; //插入
}
}
/**
* 尔排序
* @param r 要排序的数组
* @param low 左端点
* @param high 右端点
* @param delta 增量
*/
public void shellSort(Object[] r, int low, int high, int[] delta) {
for(int k=0; k<delta.length; k++) {
shellInsert(r, low, high, delta[k]);
}
}
private void shellInsert(Object[] r, int low, int high, int deltaK) {
for(int i=low+deltaK; i<=high; i++) {
if(compare(r[i], r[i-deltaK])<0) {
Object temp = r[i];
int j=i-deltaK;
for(; j>=low && compare(temp, r[j])<0; j=j-deltaK)
r[j+deltaK] = r[j];
r[j+deltaK] = temp;
}
}
}
/**
* 冒泡排序
* @param r 要排序的数组
* @param low 左端点
* @param high 右端点
*/
public void bubbleSort(Object[] r, int low, int high) {
int n = high - low +1;
for(int i=1; i<n; i++) {
for(int j=low; j<=high -i; j++) {
if(compare(r[j],r[j+1])>0) {
Object temp = r[j];
r[j] = r[j+1];
r[j+1] = temp;
}
}
}
}
/**
* 快速排序
* @param r 要排序的数组
* @param low 左端点
* @param high 右端点
*/
public void quickSort(Object[] r, int low, int high) {
if(low < high) {
int pa = partition(r, low, high);
quickSort(r, low, pa-1);
quickSort(r, pa+1, high);
}
}
private int partition(Object[] r, int low, int high) {
Object pivot = r[low];
while(low < high) {
while(low<high && compare(r[high], pivot)>=0) high--;
r[low] = r[high];
while(low<high && compare(r[low],pivot)<=0) low++;
r[high] = r[low];
}
r[low] = pivot;
return low;
}
/**
* 简单选择排序
* @param r 要排序的数组
* @param low 左端点
* @param high 右端点
*/
public void selectSort(Object[] r, int low, int high) {
for(int k=low; k<high; k++) {
int min = k;
for(int i=min+1; i<=high; i++)
if(compare(r[i], r[min])<0) min = i;
if(k != min) {
Object temp = r[k];
r[k] = r[min];
r[min] = temp;
}
}
}
/**
* 堆排序
* 该方法有点错误,有时间再解决,也希望读者能帮忙解决
* @param r 要排序的数组
*/
public void heapSort(Object[] r) {
int n = r.length - 1;
for(int i=n/2; i>=1; i--) //初始化键堆
heapAdjust(r, i, n);
for(int i=n; i>1; i--) { //不断输出堆顶元素并调整人r[1....i-1]为新堆
Object temp = r[1]; //交换堆顶与堆底元素
r[1] = r[i];
r[i] = temp;
heapAdjust(r,1,i-1);//调整
}
}
private void heapAdjust(Object[] r, int low, int high) {
Object temp = r[low];
for(int j=2*low; j<=high; j=2*j) { //沿关键字较大的元素向下进行筛选
//指向关键字较大的元素
if(j<high && compare(r[j],r[j+1])<0) j++;
//若temp比其孩子都大,则插入到low所指位置
if(compare(temp, r[j])>=0) break;
r[low] = r[j];
low = j; //向下删选
}
r[low] = temp;
}
/**
* 归并排序
* @param r 要排序的数组
* @param low 左端点
* @param high 右端点
*/
public void mergeSort(Object[] r, int low, int high) {
if(low<high) {
mergeSort(r, low, (high+low)/2);
mergeSort(r, (high+low)/2+1, high);
merge(r, low, (high+low)/2, high);
}
}
private void merge(Object[] a, int p, int q, int r) {
Object[] b = new Object[r-p+1];
int s = p;
int t = q+1;
int k=0;
while(s<=q && t<=r) {
if(compare(a[s],a[t])<0)
b[k++] = a[s++];
else
b[k++] = a[t++];
}
while(s<=q)
b[k++] = a[s++];
while(t<=r)
b[k++] = a[t++];
for(int i=0; i<b.length; i++)
a[p+i] = b[i];
}
/**
* 把int型的数组转换成包装类Integer的数组
* @param a
* @return
*/
public Integer[] intToInteger(int[] a) {
Integer b[] = new Integer[a.length];
for(int i=0; i<a.length; i++) {
b[i] = Integer.valueOf(a[i]);
}
return b;
}
public boolean equal(Object obj1, Object obj2) {
// TODO Auto-generated method stub
return false;
}
public int compare(Object obj1, Object obj2) {
Integer a = (Integer)obj1;
Integer b = (Integer)obj2;
if(a.compareTo(b)<0) return -1;
else if(a.compareTo(b) == 0) return 0;
else return 1;
}
}
/*
class Student implements Strategy {
public Integer id ;
public Student(){
this.id = 0;
}
public Student(int id) {
this.id = id;
}
@Override
public boolean equal(Object obj1, Object obj2) {
// TODO Auto-generated method stub
return false;
}
@Override
public int compare(Object obj1, Object obj2) {
Student st1 = (Student)obj1;
Student st2 = (Student) obj2;
return st1.id.compareTo(st2.id);
}
}
*/
测试
package datastructure.sorter;
/**
* 测试
* @author luoweifu
*
*/
public class Test {
public static void main(String[] args) {
//Object[] a =
int a[] = {5,6,8,1,8,88,56,78};
Sorter sort = new Sorter();
Integer b[] = sort.intToInteger(a);
//sort.insertSort(a, 0, a.length-1);
//sort.binInsetSort(a, 0, a.length-1);
//int b[] = {3,1};
//sort.shellSort(a, 0, a.length-1, b );
//sort.bubbleSort(a, 0, a.length-1);
//sort.quickSort(a, 0, a.length-1);
//sort.selectSort(a, 0, a.length-1);
//sort.heapSort(a); //堆排序,有点错误,有时间再解决
sort.mergeSort(b, 0, b.length-1);
for(int i=0; i<b.length; i++) {
System.out.print(b[i] + " ");
}
}
}
结果:
1 5 6 8 8 56 78 88