数据结构 JAVA描述(十二) 归并排序 链式基数排序
2016-01-05 17:13
211 查看
归并排序
/** * @description 2-路归并排序算法 归并过程中引入数组temp[],第一趟由a归并到temp,第二趟由temp归并到a,如此反复直到n个记录为一个有序表 * 返回的是a[]。不论是偶数趟还是奇数趟,最后都会mergepas(temp, a, s, n); 数据都会在a中 * @return * @author liuquan * @date 2016年1月5日 */ public static int[] mergeSort(int[] before){ int[] a= Arrays.copyOf(before, before.length); int s = 1; //s为已排序的子序列长度 int n = a.length; int[] temp = new int ; while(s < n){ mergepas(a, temp, s, n); s *= 2; mergepas(temp, a, s, n); s *= 2; } return a; } /** * @description 一趟归并排序的算法 * @param a * @param b * @param s s是待归并的有序子序列的长度 * @param n n是待排序序列的长度 * @author liuquan * @date 2016年1月5日 */ private static void mergepas(int[] a, int[] b, int s, int n){ int p = 0; //p为每一对待合并表的第一个元素的下标 //首先两两归并长度均为s的有序表 while(p + 2 * s - 1 <= n - 1){ merge(a, b, p, p + s - 1, p + 2 * s -1); p += 2 * s; } //归并最后两个长度不相等的有序表 if(p * s - 1 < n - 1){ merge(a, b, p, p + s - 1, n - 1); } else{ //只剩余一个有序表了,直接复制到b中 for(int i = p; i <= n - 1; i++){ b[i] = a[a]; } } } /** * @description 把两个相邻的有序表a[h……m]和a[m+1……t]归并成一个有序表 b[h……t] * @author liuquan * @date 2016年1月5日 */ private static void merge(int[] a, int[] b, int h, int m, int t){ int i = h, j = m +1, k = h; //将a中两个相邻子序列归并到b中 while(i <= m && j <= t){ if(a[i] <= a[j]){ b[k++] = a[i++]; } else{ b[k++] = a[j++]; } } //将剩余子序列复制到b中 while(i <= m){ b[k++] = a[i++]; } while(j <= t){ b[k++] = a[j++]; } }
算法性能分析
空间复杂度:O(n),存在一个辅助数组时间复杂度:归并趟数为[㏒₂ n],而每一对有序序列的归并时的比较次数均不大于记录的移动次数,而记录的移动次数=n,所以时间复杂度是O(n ㏒₂ n)
算法稳定性:稳定
基数排序
假设n个记录的排序表中的每个记录包含d个关键字{k1,k2,……kd},排序的有序表是指表中任意两个记录a[i]和a[j]都满足有序关系:(ki1,ki2,ki3……kid) < (kj1,kj2……kjd)
其中k1称为最主位关键字,kd称为最次位关键字
多关键字的排序有两种:
最主位优先(Most Significant Digit First),简称MSD法
最次位优先(Least Significant Digit First),简称LSD法
链式基数排序
在基数排序中,常使用d表示关键字的位数,用rd表示关键字可取值的种类数,例如:关键字为一个3位数,则d = 3,每一个关键字为数字,rd=10.执行基数排序可采用链表的存储结构,用一个长度为n的单链表r存放待排序的n个记录,再使用两个长度为rd的一维数组f和e,分别存放rd个队列中指向队首结点和队尾结点的指针:
形成初始链表
将最小的关键字值作为当前关键字,即i=d
执行第i趟分配和收集。链头和链尾分别由f[0……rd-1]和e[0……rd-1]指向,再将这rd个子序列头尾相连形成一个新的当前处理序列。
将当前关键字向高位推进一位,即i = i-1;重复执行上面步骤,直到d位关键字处理完毕。
算法性能分析
空间复杂度: 2*rd个队首和队尾的辅助空间,n个链表指针时间复杂度:O(d(n+rd))
其中一趟分配的时间复杂度为0(n),一趟收集的时间复杂度为O(rd),共进行了d趟分配和收集,所以时间复杂度是O(d(n+rd))
算法稳定性:稳定
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树