Sorting

//排序
/*	排序就是将一组数据按照某个域的值的递增或递减的次序重新排列的过程
 * 
 * 排序就是将一群数据,根据指定的顺序进行排列的过程
 * 排序分为: 内部排序和外部排序两类
 * 内部排序:
 * 		将需要处理的所有数据 全部加载到内部存储器中进行排序
 * 		交换式排序
 * 		选择式排序
 * 		插入式排序
 * 
 * 外部排序:
 * 		如果数据量过大,需要处理的数据无法全部加载到内存中,则需要借助外部排序
 * 		合并排序
 * 		直接合并排序
 * 
 * 1/交换式排序法:
 * 	内部排序发之一,是对数据的值进行比较以后根据判断条件对数据位置进行交换,已达到排序的的目的
 * 	冒泡排序:	bubble sort
 * 		基本思想:通过对待排序序列 从后向前(或从现向后)依次比较相邻元素的排序码 若发现逆序则交换排序码
 * 				 使较小的元素逐渐从后向前移动,就像水底的气泡一样逐渐向上冒
 * 
 * 				 因为使用冒泡的排序过程中,各个元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序
 * 				 因此要在排序的过程中设置一个标志(flag)判断元素是否进行过交换,从而减少不必要的比较
 * 		
 * 	快速排序:	Quick sort
 * 
 * 
 * 
 */
public class TestArraySorting {
	public static void main(String[] args){
		//buuble(); //冒泡排序
		//selectsort();//选择排序
		//test();//测试冒泡和选择排序的效率
		//insertSort();//插入排序
		quickSort();
	}
	//冒泡排序法
	public static void buuble(){
		int[] data = {1,6,0,-1,2};	
		Buule bl = new Buule();
		bl.sort(data);
		for(int i = 0;i<data.length;i++){
			System.out.println(data[i]);
 		}
		System.out.println("========================");		
	}
	//选择排序法
	public static void selectsort(){
		int[] data = {5,1,3,6,2};
		SelectSorting ss = new SelectSorting();
		ss.sort(data);
	}
	//测试冒泡和选择排序的效率
	public static void test(){
		Test t = new Test();
		int len = 50000;
		int[] data = new int[len];
		for(int i = 0;i<len;i++){
			int random = (int)(Math.random()*10000);			
			data[i] = random;
		}
		t.sort(data);
	}
	public static void insertSort(){
		InsertSort is = new InsertSort();
		int len = 500000;
		int[] data = new int[len];
		for(int i = 0;i<len;i++){
			int random = (int)(Math.random()*10000);			
			data[i] = random;
		}
		is.sort(data);
	}
	//快速排序
	public static void quickSort(){
		QuickSort qs = new QuickSort();
		int[] data = {123,456,789,000,213};
		qs.sort(0, data.length-1, data);
	}
}
//内部排序法
/**
 * 冒泡排序法:
 * 		基本思想:通过对待排序序列 从后向前(或从现向后)依次比较相邻元素的排序码 若发现逆序则交换排序码
 * 				 使较小的元素逐渐从后向前移动,就像水底的气泡一样逐渐向上冒
 * 				 由于使用冒泡的排序过程中,各个元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序
 *  			 因此要在排序的过程中设置一个标志(flag)判断元素是否进行过交换,从而减少不必要的比较
 * 				 
 * */
class Buule{
	public void sort(int[] args){
		//排序
		//外层循环,它决定一共执行多少次
		int temp;
		//length-1 比较的次数-1 例如一共五个元素  只进行四次比较即可
		for(int i = 0;i<args.length - 1;i++){
			//内层循环 对数据进行逐个比较 如果发现前一个数比后一个数大,则交换位置 
			// length-1-i 因为随着不停的比较,最大的元素在不停地向后面累积,累积到最后面的那个元素就可以不进行参与比较了,这样可以了提高效率
			for(int j = 0;j<args.length-1-i;j++){
				if(args[j]>args[j+1]){//相当于 data[0]>data[0+1]的值
					//进行交换
					/*temp = data[j];
					data[j] = data[j+1];
					data[j+1] = temp;*/
					args[j] = args[j]^args[j+1];
					args[j+1] = args[j]^args[j+1];
					args[j] = args[j]^args[j+1];
				}
			}			
		}
	}
}
/**
 * 选择排序法:
 * 		思想:	第一次从data[0] -> data[n-1]中选取最小值,然后与data[0]进行交换
 * 				第二次从data[1] -> data[n-1]中选取最小值,然后与data[1]进行交换
 * 				第三次...
 * 
 * 				* 选择排序法就是 每次选取最小的值 然后与数组中第一个值进行交换
 * */
//选择排序法	
class SelectSorting extends Buule{
	@Override //方法覆盖
	public void sort(int[] args){		
		//最后一个数字不需要参与 所以length-1
		int temp ;
		for(int i = 0;i<args.length-1;i++){
			//设第一个数是最小的
			int min = args[i];
			int minindex = i;//最小值的下标
			for(int j = i+1;j<args.length;j++){
				if(min>args[j]){
					//修改最小值的位置
					min = args[j];
					minindex = j;
				}
			}
			//退出内层否循环时 找到最小值  则进行变量交换
			temp = args[i];
			args[i] = args[minindex];
			args[minindex] = temp;//1 2 3 5 6 
			//思考:	不借助底三块空间 如何交换变量?
		}
		for(int a:args){
			System.out.print(a+" ");
		}
	}
}
//测试 冒泡和选择排序法两个的执行效率
class Test extends Buule{
	@Override
	public void sort(int[] args){
		//冒泡
		long time1 = System.currentTimeMillis();
		for(int i = 0;i<args.length-1;i++){
			for(int j = 0;j<args.length-1-i;j++){
				if(args[j]>args[j+1]){
					args[j] = args[j]^args[j+1];
					args[j+1] = args[j]^args[j+1];
					args[j] = args[j]^args[j+1];
				}
			}
		}
		long time2 = System.currentTimeMillis();
		System.out.println("冒泡耗时:"+(time2 - time1));
		for(int a1:args){
			//System.out.print(" "+a1);
		}
		//选择排序
		
		int temp;
		long time3 = System.currentTimeMillis();
		for(int h = 0;h<args.length-1;h++){
			int min = args[h];
			int minindex = h;
			for(int k = h+1;k<args.length;k++){
				if(min>args[k]){
					min = args[k];
					minindex = k;
				}
			}
			//退出内层循环变量交换
			temp = args[h];
			args[h] = args[minindex];
			args[minindex] = temp;//1 2 3 5 6 
			//思考:	不借助第三块空间 如何交换变量?
		}
		long time4 = System.currentTimeMillis();
		System.out.println("\n选择排序时间:"+(time4 - time3));
	}	
}
//插入式排序法
/*
 * 插入式排序法(3种)
 * 	1.插入式排序
 * 	2.shell 排序
 * 	3.二叉树排序
 * 基本思想:
 * 		把N个待排序的元素看成一个有序表和一个无序表,开始时有序表只包含一个元素,无序表中包含N-1个元素
 * 		排序的过程中,每次从无序表中取出第一个元素,把它的排序码依次与有序表中的元素进行比较
 * 		然后将它插入到有序表中适当地位置,使之形成新的有序表
 * 
 * */
class InsertSort extends Buule{
	@Override
	public void sort(int[] args){
		//第一个数是有序的
		for(int i = 1;i<args.length;i++){
			//准备和前一个进行比较的数
			int insV = args[i];
			//index = i-1        如果上面的i=1的话,这里实际上就是前面一个数
			int index = i-1;
			//如果需要插入的数比现有的这个有序表中的数还小的话,就把这个数的下标向后移动一位
			while(index>=0 && insV<args[index]){
				//将args[index] 向后移动一位
				args[index+1] = args[index];
				//让index向前移动一位
				index--;
			}
			//将insV添加到适当地位置
			args[index+1] = insV;
		}
		for(int i:args)
				System.out.println(i);
	}
}
/**
 * 快速排序法:(多线程)
 * 		基本思想:
 * 			通过一趟排序将要进行排序的数据分为独立的两部分,其中一部分的数据要比另一部分的所有数据要小
 * 				然后再按此方法对两部分数据进行快速排序,整个排序过程可以以递归形式进行,已达到整个数据变成有序序列
 * 
 * 			假设一堆数据,先找到中间的数,然后以中间数为基准,分为两段,然后再从两段中分别找出中间数......然后在进行排序
 * */
class QuickSort{
		public void sort(int left,int right,int[] args){
			int l = left;
			int r = right;
			int pivot = args[(left+right)/2];
			int temp = 0;
			while(l<r){
				while(args[l]<pivot) l++;
				while(args[r]>pivot) r--;
				
				if(l>=r){
					temp = args[l];
					args[l] = args[r];
					args[r] = temp;
					if(args[l] == pivot){
						--r;
					}
					if(args[r] == pivot){
						++l;
					}
					if(l == r){
						l++;
						r--;
					}
					if(left<r){
						sort(left,r,args);
					}
					if(right>l){
						sort(l,right,args);
					}
				}
			}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值