Java数据结构和算法(一)---冒泡,选择,插入排序算法。

1、 冒泡排序

    冒泡排序的主要规律:

    1、比较两个相邻的元素,如果第一个比第二个大,交换他们两个。

    2、对每一对相邻元素都进行第一步操作,从开始的第一对到结束的最后一对。这步做完后,最后一个元素会是最大的数,也

是第一波冒泡结束。

    3、对所有元素都进行以上步骤,除了最后一个数。

    4、持续每次对越来越少的元素进行以上步骤,直到没有需要进行比较的元素。

    代码如下:

public class BubbleSort 
{
	public static void main(String[] args) 
	{
		//冒泡算法 相邻两个数比较 每次循环会将最大的数放到最右边
		int[] array = {4,2,8,9,5,7,6,1,3};
		int[] result = bubble(array);
		
	}
	public static int[] bubble(int[] array){
		int sum=0;
		//循环的次数
		for(int i=1;i<=array.length;i++){
			//标记 当结果为true时 说明没有进行交换 排序结束
			boolean flag = true;
			//j用作数组的下标 对当前无序数组进行排序
			for(int j= 0;j<array.length-i;j++){
				if(array[j]>array[j+1]){
					sum=array[j];
					array[j]=array[j+1];
					array[j+1]=sum;
					flag=false;
				}
			}
			if(flag){
				break;
			}
			//每一轮的排序的结果
			System.out.println("第"+i+"轮排序后的结果");
			display(array);
		}
		return array;
	}
	public static void display(int[] array){
		for(int a:array){
			System.out.print(a+" ");
		}
		System.out.println();
	}
}
    冒泡排序解释:

    冒泡排序由两个for循环构成,第一个for循环中,变量i用来表示需要进行多少轮比较,第二个for循环中的变量j用作每轮参与比较的数组下标,因为每轮都会产生一个最大数在最右边,因此,每轮比较之后都会减少一个,j的范围是逐渐减小的。

    冒泡排序性能分析:

    假设参与比较的元素有N个,那么第一轮就需要比较N-1次,第二轮需要比较N-2次(每轮递减一个),以此类推(共需进行N-1轮),求和公式为:

    (N-1)+(N-2)+(N-3)+...+2+1=N*(N-1)/2

    当N的值足够大时,算法比较次数约为N²/2,忽略减一。

    假设数据是随机的,每次比较可能交换位置,可能不交换位置,假设概率为50%,则交换次数为N²/4。(最坏的情况是逆序,每次比较之后都需要交换位置)

    比较和交换的次数都与N²成正比,由于常数不算大,在O表示法中,忽略2和4,冒泡排序运行都是O(N²)时间级别。

2、选择排序

    选择排序的主要规律:

    1、从待排序的序列当中,找到最小的元素。

    2、如果最小元素不是第一个元素,将其和第一个元素互换。

    3、对余下N-1个元素,找出最小的元素,进行上述操作,知道排序结束。

    代码如下:

public class  ChoiceSort
{
	public static void main(String[] args) 
	{
		int[] array = {4,2,8,9,5,7,6,1,3};
		choice(array);
	}

	public static int[] choice(int[] array){
		//总共进行n-1轮比较
		for(int i=0;i<array.length;i++){
			
			int min=i;
			//每轮比较的次数
			for(int j=i+1;j<array.length;j++){
				if(array[j]<array[min]){
					min=j;//目前能找的最小值的下标
				}
			}
			//将找到的最小值和i位置互换
			if(i!=min){
				int temp = array[i];
				array[i] = array[min];
				array[min] = temp;
			}
			System.out.print("第"+i+"轮排序后的结果是:");
			display(array);
		}
		return array;
	}

	public static void display(int[] array){
		for(int a:array){
			System.out.print(a+" ");
		}
		System.out.println();
	}
}
    选择排序性能分析:

    选择排序和冒泡排序执行了相同次数的比较:N*(N-1)/2,但是在交换次数上,至多只进行了N次交换。

    当N的值很大的时候,比较次数是主要的,因此选择排序也是O(N²)时间级别的。但是由于交换次数少,所以选择排序是比冒泡排序快的。当N的值比较小时,如果交换的时间比比较的时间多,那么选择排序比冒泡排序快的多。

3、插入排序

    插入排序的主要规律:

    插入排序的基本思想是每一步将一个元素插入到已经排好序的序列当中去,知道插完所有元素为止。

    代码如下:

public class InsertSort 
{
	public static void main(String[] args) 
	{
		int[] array = {4,2,8,9,5,7,6,1,3};
		insert(array);
	}
	public static void insert(int[] array){
		int a=0;
		//从下标为1开始插入
		for(int i=1;i<array.length;i++){
			int temp = array[i];//要插入的数据 
			a = i;
			while(a>0 && temp<array[a-1]){
				array[a] = array[a-1];//对已经排好序的进行比较 找到比temp小的数
				a--;				  //向后移动
			}
			array[a] = temp;
		}
		display(array);
	}
	public static void display(int[] array){
		for(int a:array){
			System.out.print(a+" ");
		}
		System.out.println();
	}
}
    插入排序性能分析:

    在第一轮中,最多比较一次,第二轮中,最多比较两次,以此类推,共需比较1+2+...+(N-2)+(N-1)=N*(N-1)/2

    假设在每一轮发现插入点前,平均只有一半数据进行了比较,相当于N*(N-1)/4,用大O表示法需要O(N²)时间级别。

    复制的次数大致等于比较的次数,但是一次复制和一次交换消耗的时间不同,相对于随机数据来说,插入排序比冒泡排序快一倍,比选择排序略快。但是,如果要进行逆序排列,这个时候每次比较和移动都需要进行,并不比冒泡排序快。

    传送门:http://www.cnblogs.com/ysocean/p/7896269.html

    

猜你喜欢

转载自blog.csdn.net/xianjianwz/article/details/81015242