首页 > 技术文章 > 关于冒泡,选择,插入,快速排序的测试整理。

invoker- 2017-04-23 17:27 原文

关于生成随机数组的一种方法

本质是先生成有序的数组,接着对里面的元素进行随机的替换遍历,是一个简单的方法,缺点是内容始终是1~数组大小,并不算真正的随机,不过依旧可以改进。

//得到数组内容从0到log-1的随机数组
//得到数组内容从0到log-1的随机数组
 2   public int[] getrandomarray(int log){
 3                 int[] result = new int[log];
 4                 for (int i = 0; i < log; i++) {
 5                         result[i] = i;
 6                 }
 7                 for (int i = 0; i < log; i++) {
 8                         int random = (int) (log * Math.random());
 9                         int temp = result[i];
10                         result[i] = result[random];
11                         result[random] = temp;
12                 }
13                 return result;
14             }

 

 

算法用的小轮

package com.jhdx.uitl;

public class usualMethod {
	public static long beforeTime;
	public static long afterTime;
	public static long runTime;
	
	/**
	 * 这是一个创建随机数组的方法,原理是对数组里面的数字进行随机的换位
	 * @param 数组长度
	 * @return 返回一个随机数组
	 */
	public static int[] getRandomArray(int num){
		int[] array=new int[num];
		for (int i = 0; i < array.length; i++) {//给数组里每个元素按照下标赋值
			array[i]=i;
		}
		for (int i = 0; i < array.length; i++) {
			int random=(int) (num*Math.random());
			int temp=array[i];
			array[i]=array[random];
			array[random]=temp;//随机交换数组里面的数字
		}
		return array;
	}
	
	/**
	 * 数组排序前的测试
	 * @param array
	 */
public static void beforeMethod(int[] array){
	System.out.println("排序测试");
	System.out.print("原始数组顺序为");
//	for (int i = 0; i < array.length; i++) {
//		System.out.print(array[i]+" ");
//	}
	beforeTime=System.currentTimeMillis();
}

/**
 * 数组排序后的测试
 * @param array
 */
public static void afterMethod(int[] array){
	afterTime=System.currentTimeMillis();
	runTime=afterTime-beforeTime;
	System.out.println("========================");
	System.out.println("排序结束,算法花费"+runTime+"毫秒,正确顺序为");
//	for (int i = 0; i < array.length; i++) {
//		System.out.print(array[i]+" ");
//	}
	
}
}

 

 

 

快速排序:

package 排序;

import com.jhdx.uitl.usualMethod;

/*算法思想:选定一个数字,以这个数字为基准,将数组一分为二,将比他小的放在他左边,比他大的放在他右边
 * 接着分别再对左右两边的小数组进行同样的递归操作,直到数组有序
 * */
public class 快速排序 {
public static int getMiddle(int[] array,int low,int high){
	int temp=array[low];//默认将数组的第一个数作为中轴
	while (low<high) {
		while (low<high&&array[high]>=temp) {//如果高位数字大于等于中轴数字,则将高位标记往前推一位
			high--;
		}
		array[low]=array[high];	//一直推到小于中轴数字为止,将这个高位数字换到低位去
		while (low<high&&array[low]<=temp) {//同理如果低位数字小于等于中轴数字,则将低位标记往后推一位
			low++;
		}
		array[high]=array[low];//同理一直推到低位标记的数字大于中轴数字为止,将这个低位数字换到高位去
	}
	array[low]=temp;//将中轴数字放到应该在的位置
	return low;
}

public static void quickSort(int[] array,int low,int high){
	if (low<high) {
		int middle=getMiddle(array, low, high);
		quickSort(array, low, middle-1);//对一分为二的低位数组再次分割排序
		quickSort(array, middle+1, high);//对一分为二的高位数组再次分割排序
	}
}
public static void main(String[] args) {
	int array[]=usualMethod.getRandomArray(50000);
	usualMethod.beforeMethod(array);
	int low=0;
	int high=array.length-1;
	quickSort(array, low, high);
	usualMethod.afterMethod(array);
}
}

 

插入排序

package 排序;

import com.jhdx.uitl.usualMethod;

/*给定一个标记元素,元素左边的是有序排列的,元素右边无序排列,将元素插入左边有序的正确位置,然后重复插入操作*/
public class 插入排序 {
public static void main(String[] args) {
	int[] array=usualMethod.getRandomArray(50000);
	usualMethod.beforeMethod(array);
	//算法部分
	for (int i = 0; i < array.length; i++) {
		for (int j = 0; j < i; j++) {
			if (array[i]<array[j]) {
				int temp=array[i];
				System.arraycopy(array, j, array, j+1, i-j);//复制数组,从j序列复制到j+1,腾出一个位子,下标是j
				array[j]=temp;
			}
		}
	}
	//输出
	usualMethod.afterMethod(array);
	
}
}

 

选择排序

package 排序;

import com.jhdx.uitl.usualMethod;

/*
 * a) 原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。
 * 也就是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。
 * 基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。(这里只介绍常用的简单选择排序)

b) 简单选择排序的基本思想:给定数组:int[] arr={里面n个数据};第1趟排序,在待排序数据arr[1]~arr[n]中选出最小的数据,将它与arrr[1]交换;
第2趟,在待排序数据arr[2]~arr[n]中选出最小的数据,将它与r[2]交换;以此类推,第i趟在待排序数据arr[i]~arr[n]中选出最小的数据,将它与r[i]交换,直到全部排序完成。
 */
public class 选择排序 {
	public static void main(String[] args) {
		int[] array=usualMethod.getRandomArray(50000);//测试数组
		usualMethod.beforeMethod(array);//排序前
		
		//算法部分
		for (int i = 0; i < array.length-1; i++) {//同样比较次数为数的总数-1
			int k=i;//k用于记录最小数字的位置的,默认给个i即每次循环的第一个位置
			for (int j = k+1; j < array.length; j++) {
				if (array[j]<array[k]) {//对每一个数进行比较,记下最小数字的位置
					k=j;
				}
			}
			if (k!=i) {//每趟遍历完之后,如果k的位置(即最小数的记录位置)发生了变化(因为一开始给的是i,!=i意味着发生了变化),那么交换i和k位置的数字
				int temp;
				temp=array[i];
				array[i]=array[k];
				array[k]=temp;
			}
		}
		
		usualMethod.afterMethod(array);//排序后
		

	}
}

 

冒泡排序

package 排序;

import com.jhdx.uitl.usualMethod;

//原理:比较两个相邻的元素,将值大的元素交换至右端。

//思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。
//即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。
//然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,
//直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。
public class 冒泡排序 {
	public static void main(String[] args) {
		int[] array=usualMethod.getRandomArray(50000);//测试随机数组

		usualMethod.beforeMethod(array);//排序前
		System.out.println("");
		System.out.println("========================");
		//算法部分
		for (int i = 0; i < array.length-1; i++) {//设置循环次数,两个数只需要比较一次,三个数要比较两次
			for (int j = 0; j < array.length-1-i; j++) {//每次循环中将已经排好的给去掉,不去也没有关系,但是后面的计算是无意义的
				if (array[j]>array[j+1]) {//对于每个数字,前后两两进行比较,将大的放到后面去
					int temp;
					temp=array[j];
					array[j]=array[j+1];
					array[j+1]=temp;
				}
		}
	}
		usualMethod.afterMethod(array);//排序后
}
}

 

推荐阅读