java中的冒泡排序,插入排序,快速排序

冒泡排序:

package Sort;

/*Created by Anshay on 2017年10月2日
 *email: anshaym@163.com
 *冒泡排序
 */

import java.util.Random;

public class BubbleSort {

	public static void main(String[] args) {
		int[] a = new int[10];// 定义一个长度为10的数组a。
		Random r = new Random();
		for (int i = 0; i < a.length; i++) {
			a[i] = r.nextInt(100);// 每个字符为0到100之间的随机数
		}
		print(a);
		bubbleSort(a);
		print(a);
	}

	public static void bubbleSort(int[] a) {
		for (int i = a.length - 1; i >= 0; i--) {
			int temp = 0;
			for (int j = 0; j < i; j++) {
				if (a[j] > a[j + 1]) {
					temp = a[j + 1];
					a[j + 1] = a[j];
					a[j] = temp;
				}
			}
		}
	}

	public static void print(int[] a) {
		for (int i = 0; i < a.length; i++) {
			System.out.print(" " + a[i]);
		}
		System.out.println(" ");
	}
}



插入排序:

package Sort;

import java.util.Random;

/*Created by Anshay on 2017年10月2日
 *email: anshaym@163.com
 *插入排序
 */

public class InsertSort {
	public static void main(String[] args) {
		int a[] = new int[10];
		Random r = new Random();
		for (int i = 0; i < a.length; i++) {
			a[i] = r.nextInt(100);// 0到100之间的随机整数
		}
		print(a);// 打印排序之前的数组
		insertQuick(a);
		print(a);// 打印排序之后的数组
	}

	public static void insertQuick(int[] a) {
		int j;
		for (int p = 1; p < a.length; p++) {// 从a[1]开始往后一个一个把元素插入到排好了的a[0]到a[p-1]这一段中进去
			int temp = a[p];
			/*
			 * 左边a[0]到a[p-1]这一段是已经排列好了的, 每次从a[p]开始向前比较,找到第一个小于于a[p]的元素,把a[p]插入进去
			 */
			for (j = p; j > 0 && temp < a[j - 1]; j--) {
				a[j] = a[j - 1];// 从后往前,每个大于a[p]的元素向后挪一位
			}
			a[j] = temp;// 此时的j是for循环中上一次满足条件的j值减1;
		}
	}

	// 打印方法
	public static void print(int[] a) {
		for (int i = 0; i < a.length; i++) {
			System.out.print(" " + a[i]);
		}
		System.out.println(" ");
	}
}



快速排序:

package Sort;

import java.util.Random;

/*Created by Anshay on 2017年10月2日
 *email: anshaym@163.com
 *快速排序
 */

public class QuickSort {
	/*
	 * 当待排序的数的数量较少时,使用简单插入排序的实际耗时会小于快速排序,这是无数人经过实际测试或实验得出的结论,
	 * 至于原因应该是当数量较少时,使用递归所需的反复调用函数所增加的时间超过了时间复杂度降低所减少的时间。
	 * Cutoff可以认为是代码中对于“较少”和“较多”的分界线,较多时使用快速排序,较少时使用InsertionSort(插入排序)
	 */
	static int CUTOFF = 3;// 快排和插入排序的分界值

	public static void main(String[] ars) {
		int[] a = new int[10];// 定义一个长度为10的数组a。
		Random r = new Random();
		for (int i = 0; i < a.length; i++) {
			a[i] = r.nextInt(100);// 每个字符为0到100之间的随机数
		}
		print(a);
		quickSort(a, 0, a.length - 1);
		print(a);

	}

	// 快排的主要程序
	public static void quickSort(int[] a, int left, int right) {
		if (left + CUTOFF <= right) {// 当两者差异大于3时采用快排,否则采用插入排序
			// System.out.println(a[left] + "到" + a[right] + "进行快速排序");
			int pivot = median3(a, left, right);

			// print(a);
			// 开始分割
			int i = left, j = right - 1;
			for (;;) {
				while (a[++i] < pivot) {
				}// 找到第一个不小于枢纽元的元素时停止,这个数索引为i
				while (a[--j] > pivot) {
				}// 找到第一个不大于枢纽元的元素时停止,这个数索引为j
				if (i < j)
					swapReferences(a, i, j);// 如果这两个数是前大后小,则交换这两个数
				else {
					break;// 否则结束循环,此时已经根据枢纽元分好了
				}
			}

			// 此时i是第一个比枢纽元大的元素索引,枢纽元处在right-1处
			swapReferences(a, i, right - 1);// 交换,此时a[i]小于所有后面的,大于所有前面的
			// System.out.println("一次快速排序结束");
			// print(a);

			quickSort(a, left, i - 1);// 递归整理比枢纽元小的那部分排序
			quickSort(a, i + 1, right);// 递归整理比枢纽元大的那部分排序
		} else {
			insertionSort(a, left, right);
		}
	}

	// 插入排序,原插入排序中没有left和right参数,默认为left为0,a.length为right-left+1
	public static void insertionSort(int[] a, int left, int right) {
		// System.out.println("第" + (left + 1) + "位" + a[left] + "到第"
		// + (right + 1) + "位" + a[right] + "进行插入排序");
		int j;
		for (int p = left + 1; p < right + 1; p++) {// 中间索引限制条件是p在[left,right]上的整数
			int temp = a[p];
			for (j = p; j > left && temp < a[j - 1]; j--) {
				a[j] = a[j - 1];
			}
			a[j] = temp;// 此时的j是for循环中上一次满足条件的j值减1;
		}
		// System.out.println("完成插入排序:");
		// print(a);

	}

	// 三数中值分割法
	public static int median3(int[] a, int left, int right) {
		int center = (left + right) / 2;// 左和右之间的中间索引

		if (a[center] < a[left]) {
			swapReferences(a, left, center);
		}
		if (a[right] < a[left]) {
			swapReferences(a, left, right);
		}
		if (a[right] < a[center]) {
			swapReferences(a, center, right);
		}
		// 去中间数,和right-1位置交换,并把枢纽元放在right-1这个位置
		swapReferences(a, center, right - 1);
		// System.out.println("枢纽元是" + a[right - 1]);
		return a[right - 1];// 返回预备做枢纽元的元素
	}

	// 交换数组中两个数据
	public static void swapReferences(int[] a, int i, int j) {
		int temp = a[i];
		a[i] = a[j];
		a[j] = temp;
	}

	// 打印方法
	public static void print(int[] a) {
		for (int i = 0; i < a.length; i++) {
			System.out.print(" " + a[i]);
		}
		System.out.println(" ");
	}
}


注:快速排序中如果对38-42行采用如下代码:

int i = left+1,j=right-2;
			for(;;){
				while (a[++i]<pivot ) { i++ }// 找到第一个不小于枢纽元的元素时停止,这个数索引为i
				while (a[--j]>pivot) { j-- }// 找到第一个不大于枢纽元的元素时停止,这个数索引为j
			if (i < j)
				swapReferences(a, i, j);// 如果这两个数是前大后小,则交换这两个数
			else
				break;// 否则结束循环,此时已经根据枢纽元分好了
			    
		    }

则不能正常运行,因为如果a[i] = a[j]=pivot,会产生一个无限循环。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值