黑马程序员—数组(选择排序和冒泡排序深入及总结)

------- android培训java培训、期待与您交流! ----------

 

import java.util.*;
class ArrayTest2// 数组排序 面试常考 选择排序和冒泡排序 总结  
{

//对给定数组进行排序  {5,1,6,4,2,8,9} 从小到大 参看示意图



//数组排序之选择排序:特点 内循环结束一次 最值出现头角标位置上 


	
	public static void selectSort(int [] arr)
	{
		for (int x=0;x<arr.length-1 ;x++ )
		//当剩下最后一个数时 它就是最大值了 所以是x<arr.length-1
		{

			for (int y=x+1;y<arr.length;y++ )//y代表x角标后面的数

/*
在前面的嵌套循环里,x代表的是打印的行数.y代表的是每行的元素从左到
右的个数显示 这里是x便是要和y进行比较的角标所在的数 y表示x角标后一
位的数
		注意看图是int y=x+1 不是y=0+1 使x总是和后一个比:
			① 0角标先和1及后面的角标相比 得到最小的值
			② 1角标再和2及以后的角标相比 得到第二小的值
			③ 其他以此类推

			①		1
			②		2
			③		4
			.		5
			.		6
			.		8
			⑦		9

总结:
即y随着x变化 在图中是0角标和0角标右边的(在计算机里表现为后面的 所以这里是int 
y=x+1)比完一个循环后 0角标的数就确定了 接着x自增1 就是图中从第1个角标开始 又
和1角标后面的比 比完一个循环后 1角标的数也确定了 接着2角标和2角标后面的继续
比 直到只剩下一个数时 它就是最大的值了(就是从左向右推) 所以外循环的x范围是x<a
rr.length-1 而不是<arr.length
*/
		
			{
				if (arr[x]>arr[y])/*注意这里是x>y 不是y>x 因为只有x>y 才会替换 
				后面的y比前面的x大就不会替换了*/
				{
					int temp = arr[x];
					  arr[x] = arr[y];
					  arr[y] = temp ;
					将if的执行语句注释掉 换成swap(arr,x,y) 可优化 解释见下
				}
			}
		}
		System.out.println("---------------注意排序函数与打印矩形的区别--------------");	
	}

//若是要求打印从大到小 只需改if条件为arr[x]<arr[y]

	public static void main(String[] args) 
	{	
        int [] arr = {5,1,6,4,2,8,9};
		//排序前
		printArray(arr);
		
		System.out.println();
		
		//选择排序
		//selectSort(arr);
		//排序后打印
		//printArray(arr);
		//冒泡排序
		//bubbleSort(arr);
		Arrays.sort(arr);
		//排序后打印
		printArray(arr);

		//System.out.println("Hello World!");
	}


/*
数组排序之冒泡排序:相邻的两个元素进行排序 如果符合条件就换位 先从小到大
			特点:最值出现在了最后位
*/

  public static void bubbleSort(int [] arr)
	 {
		 for (int x=0;x<arr.length-1;x++)/*看图 是从右向左推的 最后只剩一个 
		 没有相邻的 所以是arr.length-1*/
		 {
			 for (int y=0;y<arr.length-x-1;y++)/*每次冒泡都是从0开始 所以y=0
			 这里的y<arr.length应该换成y<arr.length-x-1 因为每次循环都最高位的
			 角标都固定下了 所以就没必要再去比一次 所以应该减去x 但是只减去x 
			 y在第一次循环是可以取到最高位角标的 即arr[4]但是是没有arr[5]角标的
			 所以这里还应该再减去1 总之:-x让每一次比较的元素减少 -1避免角标越界*/
			 {
				 /* if (arr[x]<arr[y])
				 {
					int temp=arr[x]
					  arr[y]=arr[x]
					  arr[x]=temp
					 这里为什么是错的呢? 因为选择排序是每一个x角标都和后面所有的
					 y角标进行对比 得出结果 所以在定义if时 条件必然是arr[x]与
					 arr[y]的对比 但是在冒泡排序里是相邻之间元素的比较 不是
					 选择排序那样跳跃式的对比(对比两个图) 所以这里if的条件应该
					 是 如下:*/
				if (arr[y]>arr[y+1])
				{
					int temp = arr [y];
					 arr[y]=arr[y+1];
					 arr[y+1]=temp;/*这里的替换是和选择排序一致的 尽管先固定的角标位
					 不同(选择排序是x完成一次循环后0位先固定再从左向右推 冒泡
					 是y完成一次循环后最高位角标先固定再然后接着从左往右推) 都
					 是从左向右推 所以这里是一致的*/
					 
					 //将if的执行语句注释掉 换成swap(arr,y,y+1) 可优化 解释见下
				}
				//从大到小将if >改成<就行
			 }
		 }
	 }
/*
 替换功能抽取:
 发现无论什么排序 都需要对满足条件的元素进行位置置换 
 所以可以把这部分相同的代码提取出来 单独封装成一个函数 
*/
 public static void swap(int[] arr,int a,int b)
 {
  int temp=arr[a];
  arr[a]=arr[b];
  arr[b]=temp;
 }
					


//引用前面的遍历函数如下 

	public static void printArray(int[] arr)
	{
		System.out.print("[");
		for (int x=0;x<arr.length;x++ )
		{
//System.out.print("["); 应该放在for上面

			if (x!=arr.length-1)
/*
条件是x!=arr.length-1(因为数组是从0开始的 所以arr.length-1代表最后一个元素)
不是x<arr.length
*/
			{
				System.out.print(arr[x]+",");
			}
			else
				System.out.println(arr[x]+"]");
		}
				
	}
/*
这两个排序是经常考的面试题 其实排序是一种算法 最高效的算法是 希尔排序(三层循环
加上位运算) 今天学的两种虽然效率低(因为在堆内存中替换了多次才得到结果 上面的swap
就是优化后的老师说的在栈内存中定义变量的算法) 但是代码容易记忆

这里重新打一下 都是从小到大排序
选择排序
public static void selectSort(int [] arr)
	{
		//for (int x=0,x<arr.length-1,x++)很致命的一点 竟然把;写成,了 晕
		for (int x=0;x<arr.length-1;x++)
			{
			//for (int y=x+1,y<arr.length,y++)很致命的一点 竟然把;写成,了 晕
			  for(int y=x+1;y<arr.length;y++)
				if (arr[x]>arr[y]) //小的不换 只换大的
					{
						int temp=arr[x];
						// arr[y]=arr[x];这里是arr[x]=arr[y]有个窍门就是按时针顺序走
						 arr[x]=arr[y];
						 arr[y]=temp;
					}
			}	
	}
冒泡排序
public static void bubbleSort(int [] arr)
	{
		for (int x=0;x<arr.length-1;x++)//还是x<arr.length
		{
			for (int y=0;y<arr.length-x-1;y++)
			{
				if (arr[y]>arr[y+1])//小的不换 只换大的
				{
					int temp=arr[y];
					 arr[y]=arr[y+1];
					 arr[y+1]=temp;
				}
			}
		}
	}
其实java中已经提供了排序的方法就是在文件开始输入import java.util.*;
然后在公共类里输入Arrays.sort(arr);再打印就可以了 开发中为了优化代码都是
直接用这个 但是在这里学习有两个目的 1.可以掌握一些简单的算法(排序)2.为面
试做准备 面试的时候考算法 是不能写 Arrays.sort(arr);的

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

	public static void bubbleSort(int [] arr)
	{
		for (int x=0;x<arr.length-1;x++)//还是x<arr.length
		{
			for (int y=0;y<arr.length-x-1;y++)
			{
				if (arr[y]>arr[y+1])//小的不换 只换大的
				{
					int temp=arr[y];
					 arr[y]=arr[y+1];
					 arr[y+1]=temp;
				}
			}
		}
	}
	public static void printArray(int[] arr)
	{
		System.out.print("[");
		for(int x=0; x<arr.length; x++)
		{
			if(x!=arr.length-1)
				System.out.print(arr[x]+", ");
			else
				System.out.println(arr[x]+"]");

		}		
	}

*/


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值