常用排序算法(java实现)

一、冒泡法排序

冒泡排序思想:两两比较相邻的关键字,如果顺序相反则交换,知道没有反序的记录为止。

  • 每遍历一次,将一个最小的元素冒到顶。数据从a[0]开始存储。

	public static void BubbleSort1(int[] arr) {
		int i, j;
		for (i = 0; i < arr.length - 1; i++) {
			//
			for (j = arr.length - 2; j >= i; j--) {
				if (arr[j] > arr[j + 1]) {
					swap(arr, j, j + 1);
				}
			}
		}
	}

  • 冒泡法优化:如果前依次排序已经是有序的,则后序无需排序。直接可以出结果。

	public static void BubbleSort2(int[] a) {
		int i, j;
		boolean flag = true;
		for (i = 0; i < a.length - 1 && flag; i++) {
			flag = false;// 初始为false。
			for (j = a.length - 2; j >= i; j--) {
				if (a[j] > a[j + 1]) {
					swap(a, j, j + 1);
					flag = true;// 如果数据交换 flag变为true
				}
			}
		}
	}

	public static void swap(int[] a, int i, int j) {
		int tmp;
		tmp = a[i];
		a[i] = a[j];
		a[j] = tmp;
	}

}

二、插入排序

-记录数据比较少、基本有序的话,效率高。
插入排序思想:在要排序的数组中,假设前面n-1个数,已经排好序,现在要把第n的数插到前面的有序数列中去。此插入排序 从a[0]开始存储数据

	public static void InsertSort(int[] arr) {
		
		for (int i = 1; i < arr.length; i++) {	
			for (int j = i; j<arr.length; j--) {
				int tmp = arr[i];
				arr[j] = arr[j - 1];
				arr[j] = tmp;
			}
			
		}
	}

三、希尔排序

希尔排序思想:将一组数据按某个增量分成若干组(每组记录的小标相差d),每组进行插入排序。

	public static void ShellSort(int[] a) {
		int i, j;
		int increment = a.length;
		do {
			increment = increment / 3 + 1; // 增量序列
			for (i = increment + 1; i < a.length; i++) {
				if (a[i] < a[i - increment]) {
					// 将a[i]插入有序增量子表
					a[0] = a[i];// 暂存a[0]
					for (j = i - increment; j > 0 && a[0] < a[j]; j -= increment) {
						a[j + increment] = a[j];// 记录后移 查找插入位置
					}
					a[j + increment] = a[0];// 插入
				}
			}
		} while (increment > 1);
	}

四、堆排序
注意:堆是完全二叉树,结点比左子树都大,比右子树都小。
堆排序思想:先将序列组成完全二叉树,然后利用大顶堆,将待排序的序列构造成一个大顶堆,此时这个序列的
最大值即为根节点。将根节点移走(就是讲根节点与堆数组的为元素交换,此时*尾元素变成最大值。),将剩下的n-1个元素重新构建成一个堆,这样就会得到n *个元素的次大值,如此反复就可以得到有序序列。堆排序,需要O(1)辅助空间。

public static void HeapSort(int[] a) {
		//将数组构建成大顶堆,a.length-0的结点 都有孩子。
		for (int i = a.length / 2; i > 0; i--) {
            //i为小树的根节点。
			HeapAdjust(a, i, a.length - 1);
		}
		for (int i = a.length - 1; i > 1; i--) {
			//将堆顶记录和当前为排序的子序列的最后一个记录交换
			swap(a, 1, i);
			//将arr[1….i_1]重新调整成大顶堆
			HeapAdjust(a, 1, i - 1);
		}
	}
	/**调整堆结构  :a 堆排序数组 ; i  要调整的节点;n 尾节点*/
	private static void HeapAdjust(int[] a, int i, int n) {
		int child;
		int temp = a[i];
		for (; 2 * i <= n; i = child) {
			// for循环进行调整左右节点与父亲节点互换。并使i指向最后一个堆数组。并把i元素移到最后边。
			// 相当于调整第i个元素。(将其位置变成空穴,将堆数组的a[i]放到合适的空穴中。)
			child = 2 * i;
			if (child < n && a[child] < a[child + 1])
				++child;
			if (temp <= a[child])
				a[i] = a[child];
			else {
				break;
			}
		}
		a[i] = temp;
}

五、归并排序:

归并排序思想 :将两个或两个以上有序合并成一个新的有序序列。即把待排序的序列跟个城若干个子序列,每个子序列都是有序的。

/**
	 * @param left 数组开始下标
	 * @param right 数组末尾下标
	 */
	public static void mergeSort(int[] arr, int[] tempArray, int left, int right) {
		if (left < right) {
			int middle = (left + right) / 2;
			mergeSort(arr, tempArray, left, middle);
			mergeSort(arr, tempArray, middle + 1, right);
			Merge(arr, tempArray, left, middle + 1, right);
		}
	}

	/**
	 * @param letf 第一段的开始
	 * @param middle 第二段的开始
	 * @param righ 第二段的结束
	 */
	private static void Merge(int[] arr, int[] tempArray, int left, 
			int middle,int right) {
		int leftEnd = middle - 1;
		int tempIndex = left;
		int tempLength = right - left + 1;
		while ((left <= leftEnd) && (middle <= right)) {
			if (arr[left] <= arr[middle])
				tempArray[tempIndex++] = arr[left++];
			else
				tempArray[tempIndex++] = arr[middle++];
		}
		while (left <= leftEnd)
			tempArray[tempIndex++] = arr[left++];
		while (middle <= right)
			tempArray[tempIndex++] = arr[middle++];
		for (int i = 0; i < tempLength; i++) {
			arr[right] = tempArray[right];
			right--;
		}
	}

六、快速排序

快速排序:通过一趟排序将待排序记录分割成独立的两半部分,其中一部分记录的关键字均比领一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的

public static void quickSort(int[] arr,int low,int high){
		if(low<high){
			//找出中枢关键字,并且把数组分成[low,mid-1],[mid+1,high].
		int mid=getmiddle(arr,low,high);
		quickSort(arr,low,mid-1);
		quickSort(arr,mid+1,high);
		}
	}
	public static int getmiddle(int[] arr,int low,int high){
		//选取arr[low]为中枢关键最
		int pivotkey=arr[low];
		while(low<high){
			while(low<high&&arr[high]>=pivotkey){
				high--;
			}
			//将比中枢关键字小的交换到低端。
			swap(arr,low,high);

			while(low<high&&arr[low]<=pivotkey){
				low++;
			}
			//将比枢轴关键字大的交换到高端。
			swap(arr,low,high);
		}
		return low;
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值