Java实现数据排序(冒泡、选择、插入、快速排序)---方法持续更新中

【Added by Light on 2014-07-27】

今天终于又来更新文章了,也是因为笔者上周忙的要死,又跟一群人去搞了搞课外活动,下面的代码又更新了一个快速排序法,确实很快,也确实耗CPU内存很多……

实测80000000随机数据排序,耗时4秒,CPU瞬间飙到28%.

 

/**************************************/

再一次贴出代码来,一是想激励一下自学的自己,再一个是想帮助需要的人,还有一个是希望有大神看到并不吝赐教。呵呵。。。

 

简单说明:

1.每种排序方法均封装在了一个单独的类中;

2.个人测试使用时,可在main中自己选择注释与解除注释来调用不同方法;

友情提示:个人测试时,千万不要用我的随机生成80000000个数的数组,用我下面那个注释掉的8个元素的数组就OK了。

 

另外,有个问题,希望看到文章的并有心看完的同仁发表下见解---->

我本机笔记本(Lenovo T440p 4GB - I5-4200M-2.50GHz )测试的排序效率:

冒泡:(本机实测:80万随即数据排序-->排序前:Fri Jul 18 18:20:27 CST 2014 排序前:Fri Jul 18 18:22:17 CST 2014)

选择:(本机实测:80万随机数据排序-->排序前:Fri Jul 18 19:56:43 CST 2014 排序前:Fri Jul 18 19:58:54 CST 2014)

插入:80000000万随机数据,1秒钟;

我确定用8个元素的数组都已经测试过了,排序方法是没有问题的,但是我很质疑插入排序方法的这个效率。

大家可以检查下我的代码,看哪里有问题没?

 

 

/**
 * 展示各种排序方法:冒泡,选择,插入,快速排序法
 * 排序方法均采用封装在类中的方式
 * created by Light on 2014-7-18
 */

package com.second;
import java.util.*;
public class DoSorting {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//随机产生一个长度为80000的数据,这里先产生整数数组
		//int a = 800000;
		int [] arr = new int[80000000];
		
		//int arr[] = {0,-1,2,4,-6,33,10,11};
		
		//初始化数组,使用for循环
		
		for(int i=0;i<arr.length;i++)
		{
			arr[i] = (int)Math.random()*100000;
		} 
		
		//使用冒泡法排序
		//Bubble b = new Bubble();
		//使用选择法
		//Selection s = new Selection();
		//插入法
  		//Insertion it = new Insertion();
  		//快速排序法
  		  QuickSort qc = new QuickSort();
  
  
 		 //排序之前打印系统时间
 		 //Calendar  c = Calendar.getInstance();
 		 //Date d = new Date();
 		 System.out.println("排序前:"+ new Date());
  
 		 //调用排序
 		 //冒泡
 		 //b.sort(arr);
 		 //b.showArray(arr);
 		 //选择
  		//s.sort(arr);
 		 //s.showArray(arr);
 		 //插入
 		 //it.sort(arr);
 		 //it.showArray(arr);
 		 //快速
 		   qc.sort(0, arr.length-1, arr);
 		 //qc.showArray(arr);
 		 //排序之后打印系统时间
  		System.out.println("排序前:"+ new Date());

	}

}

//冒泡法类
class Bubble
{
	//Define public function directly
	public void sort(int arr[]) //using Array as kind of reference
	{
		for(int i=0;i<arr.length-1;i++)//外层循环控制轮询比较回合
		{
			//内层循环控制每个回合中的比较范围,没完成一个回合,范围应该减小一个元素
			//因为上一轮已经保证最大的排在了最后
			for(int j=0;j<arr.length-1-i;j++)
			{
				int temp = 0;
				//判断大小
				if(arr[j]>arr[j+1])
				{
					temp=arr[j];
					arr[j]=arr[j+1];
					arr[j+1]=temp;
				}
			}
		}
	}
	
	//提供打印数组的方法
	public void showArray(int arr[])
	{
		System.out.print("数组排序后为:");
		//for循环打印
		for(int i=0;i<arr.length;i++)
		{		
			System.out.print(arr[i]+" ");
		}
		System.out.println();
	}
}


//选择法类
class Selection
{
	//直接创建选择方法
	public void sort(int arr[])
	{
		//外层循环控制回合数,每一个回合都把最小的一个数与arr[i]交换
		for(int i=0;i<arr.length-1;i++)
		{
			//内存循环保证每个回合,即每一次内层循环退出时,找到一个最小值
			int minArr = arr[i];
			int minIndex = i;
			int temp =0 ;
			for(int j=i+1;j<arr.length;j++)
			{

				//判断所去元素与minArr的大小,如果arr[j]比minArr小,则两者交换位置,否则不做处理
				if(arr[j]<minArr)
				{
					minArr = arr[j];
					minIndex = j;
				}
			}//当循环退出时,minArr保证是本轮比较数组中最小的一个数
			
			temp = arr[i];
			arr[i] = minArr;
			arr[minIndex] = temp;
			
		}
	}
	
	//showArray
	public void showArray(int arr[])
	{
		System.out.print("数组排序后为:");
		//for循环打印
		for(int i=0;i<arr.length;i++)
		{		
			System.out.print(arr[i]+" ");
		}
		System.out.println();
	}
}


//插入法类
class Insertion
{
	//直接创建插入方法
	public void sort(int arr[])
	{
		//外层循环保证-->从第二个元素开始,一直到最后一个数-->进入内层处理逻辑,即在前面找到自己合适的位置
		for(int i=1;i<arr.length;i++)
		{
			int tempArr = arr[i];
			//int minArr = arr[i-1];
			int minIndex = i-1;
			while(minIndex>=0 && arr[minIndex] > tempArr)
			{
				arr[minIndex+1]=arr[minIndex];
				minIndex--;
			}//内层循环退出,表示找为arr[i]到了合适的位置,即arr[minIndex+1]
			
			//需要把tempArr赋给前面空出来的位置
			arr[minIndex+1] = tempArr;
		}
	}
	
	//showArray
	public void showArray(int arr[])
	{
		System.out.print("数组排序后为:");
		//for循环打印
		for(int i=0;i<arr.length;i++)
		{		
			System.out.print(arr[i]+" ");
		}
		System.out.println();
	}
}



//快速查询法
class QuickSort
{
 //定义sort方法
 public void sort(int left,int right, int array[])
 {
     int l = left;
  int r = right;
  int pivot = array[(left+right)/2];
  int tempArray = 0;//后面做交换使用
  
  while(l<r)//大的条件是l<r,即左边界要小于右边界
  {
   //内层分隔处理,左右各自处理
   while(array[l]<pivot) {l++;}
   while(array[r]>pivot) {r--;}
   //如果在上面两个循环退出时,l>=r,则表示pivot的左边都比pivot小,右边都比pivot大,此轮排序目的达到,即将array分为两部分
   if(l>=r) break;
   //如果上面条件不成立,则将上面while循环找出的不符合条件的左右元素对调,目的也是向把array分为两部分靠拢
   tempArray = array[l];
   array[l] = array[r];
   array[r] = tempArray;
   //有可能存在array[l] or array[r]正好就是pivot,此时可在对调之后直接越过此元素,此时可以返回顶层while去检查l<r是否为true
   if(array[l]==pivot) {r--;}
   if(array[r]==pivot) {l++;}  
  }
  
  //如果while退出,此时返回l=r,为了保证这个值不再参与排序,同样要保证能进入递归,需要将l and r 都处理一下
  
  if(l==r) 
  {
   l++;
   r--;
  }
  //到此,第一轮的排序(分组)就完成了,将原array分为三部分--> array[0]~array[r] , array[l]~array[length-1]和array[l-1]不动元素
  //并且,array[0]~array[r] 均小于array[l-1]; array[l]~array[length-1] 均大于 array[l-1]
  //下面调用本身,实现上面逻辑的递归,只是入参会适当修改
  if(r>left)  {sort(left, r, array);}
  if(l<right) {sort(l, right, array);}
  
  
 }
 //定义showArray方法
 public void showArray(int arr[])
 {
  System.out.print("数组排序后为:");
  //for循环打印
  for(int i=0;i<arr.length;i++)
  {  
   System.out.print(arr[i]+" ");
  }
  System.out.println();
 }
 
}






 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值