/**
* 待排序记录类
* @author liangxiamoyi
*
*/
public class Element {
/**
* 数据
*/
private int key;
/**
* 获得数据
* @return key值
*/
public int getKey(){
return key;
}
/**
* 设置数据值
* @param key 数据值
*/
public void setKey(int key){
this.key=key;
}
}
import java.util.Scanner;
/**
* 排序方法类
* @author liangxiamoyi
*
*/
public class Sort {
/**
* 最小值
*/
public static int MINKEY=-1000;
/**
* 最大值
*/
public static int MAXKEY=1000;
/**
* 直接插入排序,将list排序
* @param list 待排序的序列,1-n,list[0]小于等于任意list[1]-[n]
* @param n 排序记录的个数
*/
public static void insertSortA(Element[] list,int n){
Element e=new Element();
list[0].setKey(MINKEY);
for(int j=2;j<=n;j++){
e.setKey(list[j].getKey());
int i=j-1;
while(e.getKey()<list[i].getKey()){//list[0]保证出循环
list[i+1].setKey(list[i].getKey());
i--;
}
list[i+1].setKey(e.getKey());;
}
}
/**
* 冒泡排序算法,对n个记录进行排序r1,r2,....,rn
* @param r 排序记录
* @param n 记录个数
*/
public static void bubble(Element[] r,int n){
int bound,j,t;
Element e=new Element();
bound=n;
while(bound>0){
t=0;//t用来记录一趟冒泡最后记录交换的位置
for(j=1;j<bound;j++){
if(r[j].getKey()>r[j+1].getKey()){
interChange(r, j, j+1);
t=j;
}
}
bound=t;//bound之后的记录已经排好序,下次冒泡只需到bound,减少比较次数
}
}
/**
* 直接选择排序算法,该算法排序文件r1,r2,...,rn
* @param e 待排序文件数组
* @param n 文件个数
*/
public static void selectSort(Element[] e,int n){
int t;
Element m=new Element();
for(int j=n;j>=2;j--){
t=1;
for(int i=2;i<=j;i++){
if(e[t].getKey()<e[i].getKey()){
t=i;
}
}
//将第i大的文件放在第i的位置上
m.setKey(e[t].getKey());
e[t].setKey(e[j].getKey());
e[j].setKey(m.getKey());
}
}
/**
* <p>改进的插入排序算法</p>
* <p>把记录按下标的一定增量分组,对每组使用直接插入排序法。</p>
* <p>随着增量逐渐减少,每组包含的记录越来越多,当增量减至1时,整个文件为一组,算法终止。</p>
* @param list 待排序文件
* @param n 文件个数
*/
public static void shellSort(Element[] list,int n){
int gap=n;//增量
int i;
while(gap>=1){
gap=gap/2;
for(i=1;i<=gap;i++){//分组
Element e=new Element();
int t;
for(int j=i+gap;j<=n;j=j+gap){//直接插入排序
e.setKey(list[j].getKey());
t=j-gap;
while(e.getKey()<list[t].getKey()){
list[t+gap].setKey(list[t].getKey());
t=t-gap;
if(t<=i){
break;
}
}
list[t+gap].setKey(e.getKey());
}
}
}
}
/**
* 两个排好序的序列sourceList[t][t+1]...[m]和sourceList[m+1][m+2]...[n]合并为一个序列mergedList[t]...[n]
* @param sourceList
* @param mergedList
* @param t
* @param m
* @param n
*/
public static void merge(Element[] sourceList,Element[] mergedList,int t,int m,int n){
int i,j,k;
i=t;j=m+1;k=t;
while(i<=m&&j<=n){
if(sourceList[i].getKey()<=sourceList[j].getKey()){
mergedList[k]=sourceList[i];
i++;
}
else{
mergedList[k]=sourceList[j];
j++;
}
k++;
}
if(i>m){
for(int p=k;p<=n;p++){
mergedList[p]=sourceList[j+p-k];
}
}
else{
for(int p=k;p<=n;p++){
mergedList[p]=sourceList[i+p-k];
}
}
}
/**
* 一趟合并算法,执行一趟合并过程,将sourceList文件中长度为length的所有子文件合并到mergedList文件中
* @param sourceList 源文件
* @param mergedList 目标文件
* @param n 原文件中记录个数
* @param length 子文件长度
*/
public static void mergePass(Element[] sourceList,Element[] mergedList,int n,int length){
int j;
for(j=1;j<=n-2*length+1;j+=2*length){
//合并相邻的两个子文件
merge(sourceList,mergedList,j,j+length-1,j+2*length-1);
}
if(j+length-1<n){//处理余留的长度小于2*length的子文件
merge(sourceList,mergedList,j,j+length-1,n);
}
else{
for(int p=j;p<=n;p++){
mergedList[p]=sourceList[p];
}
}
}
/**
* 直接两路合并排序算法
* @param list 待排序文件
* @param n 文件个数
*/
public static void mergeSort(Element[] list,int n){
Element[] tempList=new Element[n+1];
for(int i=0;i<n+1;i++){
tempList[i]=new Element();
}
for(int j=1;j<n;j*=2){//交替合并
mergePass(list,tempList,n,j);
j*=2;
mergePass(tempList,list,n,j);
}
}
/**
* 快速排序的递归算法,对文件rm,...,rn进行排序
* @param r 待排序文件
* @param m 起点
* @param n 终点
*/
public static void recQuickSort(Element[] r,int m,int n){
int i,j,k,temp;
if(m<n){
i=m;
j=n+1;
k=r[m].getKey();
while(i<j){//不断交换反序对
i++;
while(r[i].getKey()<k)i++;
j--;
while(r[j].getKey()>k)j--;
if(i<j){
temp=r[i].getKey();
r[i].setKey(r[j].getKey());
r[j].setKey(temp);
}
}
temp=r[m].getKey();
r[m].setKey(r[j].getKey());
r[j].setKey(temp);
recQuickSort(r, m, j-1);
recQuickSort(r, j+1, n);
}
}
/**
* 交换表中下标为m和n的元素位置
* @param list 记录表
* @param m 位置m
* @param n 位置n
*/
public static void interChange(Element[] list,int m,int n){
int temp=list[m].getKey();
list[m].setKey(list[n].getKey());
list[n].setKey(temp);
}
/**
* 三者取中值的分划算法
* @param list 文件
* @param m 起点
* @param n 终点
* @return 分划元素最后所在的位置
*/
public static int part(Element[] list,int m,int n){
int i,j,k;
//保证list[m].key是list[m],list[(m+n)/2],list[n]的中间值
interChange(list, (int)(m+n)/2, m+1);
if(list[m+1].getKey()>list[n].getKey())interChange(list, m+1, n);
if(list[m].getKey()>list[n].getKey())interChange(list, m, n);
if(list[m+1].getKey()>list[m].getKey())interChange(list, m+1, m);
i=m;j=n+1;
k=list[m].getKey();
//快速排序
while(i<j){
i++;
while(list[i].getKey()<k)i++;
j--;
while(list[j].getKey()>k)j--;
if(i<j)interChange(list, i, j);
}
interChange(list, m, j);
return j;
}
/**
* <p>快速排序的非递归算法,对r1,...,rn进行排序,变量m给定,5<=m<=15</p>
* <p>r包含n+2个记录,r[0]=MINKEY,r[n+1]=MAXKEY</p>
* @param n 记录个数
* @param r 文件
* @param m
*/
public static void hoareQuickSort(int n,Element[] r,int m){
class StackType{
private int x;
private int y;
}
AStack<StackType> stackptr=new AStack<StackType>(30);
StackType temp=new StackType();
int f,t,j;
temp.x=temp.y=0;
stackptr.push(temp);//设置栈底元素
f=1;t=n;
while(f<t){
j=part(r,f,t);
if(j-f<m&&t-j<m){
temp=stackptr.pop();
f=temp.x;
t=temp.y;
continue;
}
if(j-f<m&&t-j>=m){
f=j+1;
continue;
}
if(j-f>=m&&t-j<m){
t=j-1;
continue;
}
if(j-f>=m&&t-j>=m){//当两个文件都大于等于m时,存储较大的子文件
if(j-f>t-j){
temp.x=f;
temp.y=j-1;
stackptr.push(temp);
f=j+1;
}
else{
temp.x=j+1;
temp.y=t;
stackptr.push(temp);
t=j-1;
}
}
}
insertSortA(r, n);
}
/**
* 重建堆,根为tree[rot]的二叉树,树中任意节点编号<=n
* @param tree 二叉树
* @param root 根
* @param n 个数
*/
public static void restore(Element[] tree,int root,int n){
int m;
int j=root;
while(j<=(int)n/2){
if((2*j<n)&&(tree[2*j].getKey()<tree[2*j+1].getKey())){
m=2*j+1;
}
else m=2*j;
if(tree[j].getKey()<tree[m].getKey()){
interChange(tree, j, m);
j=m;
}
else j=n;
}
}
/**
* 堆排序算法,对文件r1,...,rn进行排序
* @param r 待排序文件
* @param n 个数
*/
public static void heapSort(Element[] r,int n){
int i;
for(i=n/2;i>=1;i--){//初始建堆
restore(r, i, n);
}
for(i=n;i>1;i--){//排序
interChange(r, 1, i);
restore(r, 1, i-1);
}
}
//测试
public static void main(String[] args){
int num;
Scanner s=new Scanner(System.in);
System.out.println("请输入文件个数:");
num=s.nextInt();
Element[] e=new Element[num+2];
System.out.println("请依次输入文件关键词:");
e[0]=new Element();
e[0].setKey(MINKEY);
e[num+1]=new Element();
e[num+1].setKey(MAXKEY);
for(int i=1;i<num+1;i++){
e[i]=new Element();
e[i].setKey(s.nextInt());
}
Sort.insertSortA(e, num);
for(int i=1;i<num+1;i++){
System.out.print(e[i].getKey()+" ");
}
System.out.println();
Sort.bubble(e, num);
for(int i=1;i<num+1;i++){
System.out.print(e[i].getKey()+" ");
}
System.out.println();
Sort.selectSort(e, num);
for(int i=1;i<num+1;i++){
System.out.print(e[i].getKey()+" ");
}
System.out.println();
Sort.shellSort(e, num);
for(int i=1;i<num+1;i++){
System.out.print(e[i].getKey()+" ");
}
System.out.println();
Sort.mergeSort(e, num);
for(int i=1;i<num+1;i++){
System.out.print(e[i].getKey()+" ");
}
System.out.println();
Sort.recQuickSort(e, 1, num);
for(int i=1;i<num+1;i++){
System.out.print(e[i].getKey()+" ");
}
System.out.println();
Sort.hoareQuickSort(num, e, 1);
for(int i=1;i<num+1;i++){
System.out.print(e[i].getKey()+" ");
}
System.out.println();
Sort.heapSort(e, num);
for(int i=1;i<num+1;i++){
System.out.print(e[i].getKey()+" ");
}
System.out.println();
}
}