各种排序的实现Java

/**
 * 待排序记录类
 * @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();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值