黑马程序员_数组、冒泡、选择、插入排序法,查找。

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

数组

所谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。数组是在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。
数组的概念:同一种数据类型的集合,其实数组就是一个容器。
数组的好处:可以自动给数组中的元素从0开始编号,方便操作这些元素。
数组的格式
一、 元素类型 [ ] 数组名 = new 元素类型 [ 元素个数或数组长度 ];
示例:int[] arr = new [5];
二、元素类型 [ ] 数组名 = new 元素类型 [ ] {元素,元素,元素......};
示例:int [ ] arr = new int [ ] {3,1,5,7}; 这种叫做静态初始化方式。
int [ ] arr = {3,1,5,7};
数组在内存里面以栈和堆的形式存储。
栈里面的数据使用完过后会自动释放,而堆不会。
数组赋值的原理:
如下:[]x 只是引用了堆里面的数组(所以数组也是引用数据类型),数组只是把地址赋值给了[]x
所有的临时变量都是存储在栈里面,而new出来的都在堆里面。
在new int[3] 出来后把在堆里面的地址0x0079赋给数组x后就称x数组指向堆里面的这个数组。也叫引用了堆里面的这个数组。所以数组类型叫做引用数据类型的原因。
当不想x指向这个数组的时候定义x=null;这时候x就不再是数组了;
Java垃圾回收机制:
当一个实体在堆内存当中没有任何引用所使用的话就会被JAVA虚拟机视为垃圾,这个垃圾不会被立刻清除掉,而是在不定时的时间内,启动一个垃圾回收机制将这个数组实体在堆里面清除。
可以简单的看看内存在电脑里面存在的形式:
内存地址:
1:寄存器。2:本地方法区。3:方法区。4:栈。5:堆。
栈:存储的都是局部变量 ( 函数中定义的变量,函数上的参数,语句中的变量 );
只要数据所在的区域结束,该数据就会被释放。
堆:用于存储数组和对象成员变量,也就是实体。就是用于封装多个数据的。
1:每一个实体都有内存首地址值。
2:堆内存中的变量都有默认初始化值。因为数据类型不同,值也不一样。
3:垃圾回收机制。
数组定义后的值

当数组一被定义后都会赋予一个值,而并非是null,值是多少根据数据数据类型而定
int默认值为0; double 为0.0; float为0.0f; boolean为false;
所以千万不要认为当数组在堆内存里面存在后只是一个空壳。而并没有具体的值。

数组中常见的异常:

当数组被指为null后,在去使用这个数组就会出现数组中一个常见的异常NullPointerException为空指针异常,表面该对象已经不存在,而你还在对它进行操作。

但是当数组的长度定义为5-->int[] arr = new [5],这时候你需要去取到arr[5]这时候或许是你不经意,或者根本不明白数组角标的机制的时候。取超出了数组长度的数的时候会出现ArrayIndexOutOfBoundsException,为数组下标越界的异常。

这两个异常是数组最为常见的异常,当见到的时候要从细节去分析。

对数组的常见操作:

首先肯定是取出数组里面的每个元素,在想想怎么取出的问题了!

数组因为是固定长度的一个容器,就通过arr.length能取出数组的长度,在通过for循环通过角标肯定就能取到。

下面是代码:

<pre name="code" class="html"><span style="white-space:pre">		</span>//数组的操作
		//获取数组中的元素,通常会用的遍历。
		int[] s = {3,6,5,4,6,2,3};
		//数组中有一个属性可以直接获取到数组中的元素个数,length
		//使用方法:数组名称.length = 
		for (int x=0;x<s.length ;x++ )
		{
			System.out.println("s["+x+"]="+s[x]+";");
		}
		printArray(s);
	}
	//定义一个功能,用语打印数组中的元素,元素间用,隔开。
	public static void printArray(int[] m)
	{
		for (int x=0;x<m.length ;x++ )
		{
			if(x!=m.length-1)
				System.out.print(m[x]+",");//元素不是最后一位的时候就在后面加","
			else
				System.out.print(m[x]);//当是最后一位元素的时候不加","
		}
	}

|--排序:

我们通过循环取出来了数组里面的元素,就要想到在int[]类型数组里面的元素能不能排序的问题,答案是当然能!你说当你把成绩一个个录入数组,想要排序的时候告诉你说不能办到,那肯定就哭死了!首先我们来讲解下集中简单的排序。

第一种选择排序:

它的原理很简单,就是把第一个元素拿到去和后面每一个元素进行比较,当要进行递增的时候,就将比第一个元素小的目标元素赋值给第一个元素,简单的说就是将第一个元素与比它小的元素进行换位置,知道最后一个元素,这时候该数组中最小的那个元素就排到了数组的0角标元素,也就是第一个元素的位置,那个第二次就将数组的第二个元素依次拿去比较,小的在进行换位。那么当整个数组循环一边的时候该数组就成了一个递增的有序的数组。

/*
选择排序
*/
public static void selectSort(int[] arr)
	{
		for (int x=0;y<arr.length-1 ;x++ )//最后一个值不用比,当最后一个值的时候不用在比较了。
		{
			for (int y=x+1;x<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++ )
		{
			for (int y=0;y<arr.length-x-1 ;y++ )//-x:让每一次比较的元素减少,-1:是为了避免下标越界。
			{
				if(arr[y]>arr[y+1])
				{
					int temp = arr[y];
					arr[y] = arr[y+1];
					arr[y+1] = temp;
				}
			}
		}
	}

排序是一种算法,效率最高的是希尔排序,是三层循环加位运算。希尔排序属于插入排序的一种。

我来简单讲解一下插入排序的原理:

第三中插入排序:


插入排序是一种效率较高的排序方式,它定义了一个名为监视哨temp的临时变量来存储遍历到的数组中的第一个无序的元素i,然后将j(i-1)的元素赋值给i,这时的temp就是将要插入数组的元素,而j则变成了一个来寻找该元素需要插入哪个位置的指针,该指针一定需要大于0,这时候就将temp的元素与j所对应的元素去进行比较,若temp的值大于或者等于了j所对应的值那么就将temp,放入j+1的位置上使得j+1之前全为有序的数组这时就继续去寻找下一个无序元素进行上诉操作。

public static int[] insertSort(int[] arr)
	{
		int temp;//定义一个变量temp。作为监视哨来存储将要插入的值。
		int y=0;//定义一个变量y作为指针去寻找判断temp将要插入的位置。
		for(int x=1;x<arr.length;x++)//将x之前的数都作为有序数组来遍历后面的元素
		{
			if(arr[x]<arr[x-1])//将0~x-1作为了有序数组,当arr[x]<arr[x-1]时,进入要执行的语句
			{
				temp = arr[x];//此时arr[x]作为要插入的元素用temp记录
				//将指针y定义为arr[x-1]与temp比较如为temp<arr[y]则继续往前寻找要插入的位置,并将arr[y]
				//后移一位到arr[y+1],并自减1,直到temp的值>=arr[y]则将temp的值插入到arr[y]的后面一位为
				//arr[y+1],循环完成后将数组返回集合。
				for(y=x-1;y>=0 && temp<arr[y];y--)
				{
					arr[y+1] = arr[y];
				}
				arr[y+1] = temp;
			}
		}

这时一个演示插入排序过程的动态演示网页不懂得就点我 点击打开链接

数组的查找:

前面对数组进行了排序,我对发现插入排序这个算法的人简直就是佩服得五体投地。是不是觉得还不够!

那我们就来讲讲数组中一个很常用的对数组的操作那就是对数组进行查找。

通过角标去寻找数组中与之对应的那个元素的值,或者给定一个值,去数组中寻找相对应的角标。

首先我们来看看一半的查找:

这个方法的原理就是拿到所有的数组中的元素的值,与已有值相比较。从而找到需要的值。

public static void main(String[] args) 
	{
		int[] arr = {3,1,5,4,2,9};
		int index = getIndex(arr,2);//查找数组中元素2的下标索引位置。
		System.out.println("index="+index);
	}
	/*
		数组的查找
	*/
	//定义功能,获取key第一次出现在数组中的位置,如果返回的为-1,那么代表该key在数组中不存在。
	public static int getIndex(int[] arr,int key)
	{
		for (int x=0;x<arr.length ;x++ )
		{
			if(arr[x]==key)
				return x;
		}
		return -1;
	}

当然上诉打印的结果为4,表明了2这个元素在数组中存在于角标为4的这个位置。


当然这种方法的效率较低,那我们看介绍一种相对而言高些的折半查找。

这种方法对数组有个要求就是,数组必须是有序的。

折半查找原理取到三个角标,第一个为角标为0的min,第二个是角标为arr.length-1的最后一个元素,第三个为角标为中间元素的mid=(min+max)/2

拿到他们三个角标与之对应的元素,通过mid的值与需要查找的值key对比,当key>arr[mid]就改变min = mid + 1;反之key<arr[mid]则max = mid - 1;

反复寻找则可以找到与之对应的元素。

我们来看看它的实现代码:

 /*
		折半查找:可以提高效率但是必须保证该数组是有序的数组。
	*/
	public static int halfSearch(int[] arr, int key)
	{
		int min,mid,max;
		min = 0;
		max = arr.length-1;
		mid = (max + min)/2;
		
		while(arr[mid] != key)//当mid对应的值不是需要查找的值的时候
		{
			if (arr[mid]>key)如果中间值大于key的时候继续折半,改变最大值的值。
				max = mid - 1;
			else
				min = mid + 1;
			if(min>max)//当min>max的时候表明该值并未在数组中存在。则返回1;
				return -1;
			mid = (max + min) / 2;//当min或者max的值改变后mid的值也随之改变。
		}
		return mid;//然后将找到的角标返回。
	}
public static void main(String[] args) 
	{
		//int[] arr = {3,1,5,4,2,9};
		//int index = getIndex(arr,2);//查找数组中元素2的下标索引位置。
		int[] arr = {1,2,3,5,6,15,18,19,22,25};
		int index = halfSearch(arr,22);
		int index2 = halfSearch2(arr,3);
		System.out.println("index="+index);
		System.out.println("index2="+index2);
	}

折半的第二种实现方式:

/*
		折半查找的第二种方法
	*/
	public static int halfSearch2(int[] arr, int key)
	{
		int min = 0,max = arr.length-1,mid;
		while(min<=max)//此处表明min与max并未重合。他们中间还有元素。
		{
			mid = (min+max) >> 1;
			if(key>arr[mid])
				min = mid + 1;
			else if (key<arr[mid])
				max = mid - 1;
			else
				return mid;
		}
		return -1;
	}
public static void main(String[] args) 
	{
		//int[] arr = {3,1,5,4,2,9};
		//int index = getIndex(arr,2);//查找数组中元素2的下标索引位置。
		int[] arr = {1,2,3,5,6,15,18,19,22,25};
		int index = halfSearch(arr,22);
		int index2 = halfSearch2(arr,3);
		System.out.println("index="+index);
		System.out.println("index2="+index2);
	}

但是你会有疑问假如我寻早的这个数key,在数组中没有那返回的mid这个脚标又是什么呢?

其实返回的mid就是该数key,在数组中应该存在并且保证数组还为有序的条件你想想,min,man,mid都在某一个点重合了是不是证明

这个点的前面一个数比key小而后一个数比它 大、是不是就应该是这个数存在的位置。代码其实就和上面查找一样的:

	练习:有一个有序的数组,将一个元素8插入到该数组中,并且保证数组还是有序的。
	*/
	public static int getIndex2(int[] arr.int key)
	{
		int min = 0,max = arr.length-1,mid;
		while(min<=max)
		{
			mid = (min+max) >> 1;
			if(key>arr[mid])
				min = mid + 1;
			else if (key<arr[mid])
				max = mid - 1;
			else
				return mid;
		}
		return min;//直接返回的min就是8应该所在的地方。当min与max中间无元素的时候max会-1
				   //导致的min>max这时直接返回min的值就是8>min的值8<max的值
	}

一维数组的基本操作差不多就是这些了,很简单的应用,下面我就介绍一下二维数组:

二维数组 [ ] [ ]:

格式1:int[] [] arr = new int[][];
          定义了一个名称为arr的二维数组,
          二维数组中有三个一维数组,
          每一个一维数组中有2个元素,
          一维 数组的名称分别为arr[0],arr[1],arr[2].
          给第一个一维数组下标1位置赋值为78的写法是:arr[0][1] = 78;
这个就是黑马程序员毕向东老师的示例图:

格式2:int[][] arr = new int[3][];
          二维数组中有3个一维数组。
          每个一维数组都是默认初始化值null。
          可以对这三个一位数组分别进行初始化
              arr[0] = new int[3]; 
              arr[1] = new int[1];
              arr[2] = new int[2];
这个就是黑马程序员毕向东老师的示例图:

格式3:int[][] arr = {{1,2,5,6,},{6,2,3,5},{7,8,2,6},{2,3,6,9}};
下面看看毕老师的几个例题:

以上就是我通过毕向东老师的视频自己列出来的一些关于数组的简单应用和对数组的基本操作,算法。

其实这些并不难不过也要好好去学习。


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


详细请查看:www.itheima.com


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值