Java排序算法冒泡排序和快速排序

一、冒泡排序

(1)原理如下:  
比较相邻的元素。如果前面的数比后面的大,就交换他们两个。 
从下标为0的数开始,结束于下标为arr.length-1的数,则判断条件:if ( arr[ j ]>arr[ j+1] ),把大的数换到后面,小的数放前面
时间复杂度: O(n²) 
算法稳定性:稳定排序算法 

(2)实现

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

二、快速排序

(1)基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列

(2)按照这种思想,我们设第一个数为一个标志数,比它小的排左边,比它大的排右边。然后设两个变量来推进数与数之间的比较。然后递归再来排左右两边的数。

import java.util.Arrays;

public class QuickSort1 {
	public static void main(String[] args) {
		// 随便设的数组
		int[] arr = { 3, 4, 1 };
		quickSort(arr, 0, arr.length - 1);
		System.out.println(Arrays.toString(arr));
	}

	public static void quickSort(int[] arr, int start, int end) {
		// 递归要有一个结束条件,当start>=end的时候就不用比较了
		if (start < end) {
			// 设第一个为标志数
			int pivot = arr[start];
			// 第一个设start,最后一个数设end
			// 然后再设两个变量作为临时变量,推进比较
			int low = start;
			int high = end;
			while (low < high) {
				//如果从最后一个来比较的话,arr[high]<pivot,说明后面的数比前面的数小,就要拿来排序
				while (pivot < arr[high]) {
					high--;
				}
				//arr[high]<pivot的话,前面大数的位置放小的数
				arr[low] = arr[high];
				//又从前面开始,如果前面的数小于标志数,就不用变前面的数,因为我们就是要前面的数小于标志数,后面的数大于标志数
				//这里需要low<high,因为前面high在变化
				while (low<high&&arr[low] <= pivot) {
					low++;
				}
				//如果前面的数有>标志位的,就放在刚才卡住的high的位置
				arr[high] = arr[low];
			}
			//上面就相当于把数排成两部分,中间要填入标志数
			arr[low] = pivot;
			// 递归:处理小的,将小的那部分从小到大再排
			quickSort(arr, start, low - 1);
			// 递归:处理大的
			quickSort(arr, low + 1, end);
		}
	}
}

还有一种方法是为了更方便理解快速排序,按照思想,将其分为三部分,最后合并。

import java.util.ArrayList;
import java.util.Arrays;
/*
 * 把需要排序的数组分成三份,按照快排的思想排序,最后讲三部分合在一起
 */
public class QuickSort {
	public static void main(String[] args) {
		int[] arr = { 2, 1, 0, 7, 9 };
		quickSort(arr, 0, arr.length - 1);
	}
	public static void quickSort(int[] arr, int start, int end) {
		//递归需要结束条件
		if (start >= end) {
			return;
		}
		int part = partion(arr, start, end);//标准数应该放的位置
		quickSort(arr, start, part - 1);//左部分
		quickSort(arr, part + 1, end);//右部分
	}

	public static int partion(int[] arr, int start, int end) {
		//把第一个作为标志数
		int pivot = arr[start];
		//设两个动态数组,a存左边,b存右边
		ArrayList<Integer> a = new ArrayList<>();
		ArrayList<Integer> b = new ArrayList<>();
		//从标志数下一个开始比较,两两比较,凡是比它小的放a,凡是比它大的放b
		for (int i = start + 1; i <= end; i++) {
			if (arr[i] > pivot) {
				b.add(arr[i]);
			} else if (arr[i] <= pivot) {
				a.add(arr[i]);
			}
		}
		//开始合并这三部分
		for (int i = 0; i < a.size(); i++) {
			arr[start++] = a.get(i);//比中间数小的
		}
		int temp = start;//记录中间数
		arr[start++] = pivot;//start++(start先用,之后再+1是为了保证从中间数的下一个位置开始来合并b
		for (int i = 0; i < b.size(); i++) {
			arr[start++] = b.get(i);
		}
		System.out.println(Arrays.toString(arr));
		return temp;//返回标志数
	}
}

快速排序的一次划分算法从两头交替搜索,直到low和high重合,因此其时间复杂度是O(n);而整个快速排序算法的时间复杂度与划分的趟数有关。
理想的情况是,每次划分所选择的中间数恰好将当前序列几乎等分,经过log2n趟划分,便可得到长度为1的子表。这样,整个算法的时间复杂度为O(nlog2n)。  
最坏的情况是,每次所选的中间数是当前序列中的最大或最小元素,这使得每次划分所得的子表中一个为空表,另一子表的长度为原表的长度-1。这样,长度为n的数据表的快速排序需要经过n趟划分,使得整个排序算法的时间复杂度为O(n2)。
快速排序的空间复杂度为O(log2n))

end.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值