排序
2015-01-10 00:00
543 查看
直接插入排序
排序过程
整个排序过程为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.keyl 初始时令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
相关文章推荐
- 多线程编程实例----多线程同时排序
- 运算符重载函数应用---从小到大排序三个数
- PHP算法——文件大小排序(KB、MB、GB、TB)
- 菜鸟学排序----插入排序
- 数据结构 27 排序 排序-选择 插入 冒泡 希尔 快速归并 6种排序
- 对vector等STL标准容器进行排序操作
- 冒泡排序 快速排序 选择排序 堆排序 直接插入排序 希尔排序 归并排序
- GO语言为结构体排序
- 1801: xue姐的小动物【排序】
- JAVA语言之基数排序
- 排序算法(2)—归并排序,快速排序
- 九大基础排序总结与对比
- 使用ORDER BY & CHARINDEX 进行自定义排序
- 堆排序建堆的时间复杂度
- DEV gridview不自动排序
- 华为笔试题---“去重”与“排序”
- Firefox打开文件窗口的文件排序问题
- c++中vector排序的问题二(转载)
- 排序之插入排序
- mysql中null值的排序问题分析