【数组】(选择、冒泡)排序、折半查找、获取最值、二维数组

一、数组的定义和使用

1、概念:数组就是同一种类型数据的集合。数组其实就是一个容器。

2、数组的好处:可以自动给数组中的元素从0开始编号,方便操作这些元素。

3、数组定义的格式:

【格式一】:元素类型[]数组名 = new元素类型[元素个数或者数组长度];

   示例:

   int[] arr = new int[3];


【格式二】:元素类型[]数组名 = new元素类型[]{元素,元素,……};

   示例:

   int[] arr = new int[]{1,2,3,4,5};


【格式三 ---静态初始化】:元素类型[]数组名 = {元素,元素,......};

   示例:

   int[] arr = {1,2,3,4,5};

 

a. 元素类型:指的是声明数组元素的数据类型。

b. 数组名:是用来标识这组相同数据类型的元素的名称,命名规则和变量相同。

c. 数组长度:表示声明的数组里面可以存放元素的个数。

d. new:使编译器根据数组长度在堆内存中开辟一块内存空间供该数组使用。

 

注意:

     ①.Java中数组的使用必须经过声明分配内存空间两个步骤。

     ②.数组使用引用数据类型。引用数据类型其默认值是null,表示暂时还没有任何指向的堆内存空间。

     ③.Java中数组的初始化分为“动态初始化”和“静态初始化”。

动态初始化:先声明数组,然后再为数组中的每个元素赋值。

静态初始化:数组声明的同时就给每个元素赋值。

 

4、数组内存结构


5、Java的内存结构

栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。

堆内存

  •  数组和对象,通过new建立的实例都存放在堆内存中。
  •  每一个实体都有内存地址值
  •  实体中的变量都有默认初始化值
  •  实体不在被使用,会在不确定的时间内被垃圾回收器回收

方法区本地方法区寄存器

 

       注:在栈内存中保存的永远是数组的名称,只开辟了栈内存空间的数组是永远无法使用的,必须有指向的堆内存才可以使用,要想开辟新的堆内存则必须使用关键字new,然后只是将此堆内存空间的使用权交给了对应的栈内存空间。一个堆内存空间可以同时被多个栈内存空间所指向。

 

6、数组操作常见问题

①.数组脚标越界异常(ArrayIndexOutOfBoundsException)

int[] arr = new int[2];

System.out.println(arr[3]);

访问到了数组中的不存在的角标时发生。

 

②.空指针异常(NullPointerException)

int[] arr = null;

System.out.println(arr[0]);

arr引用没有指向实体,却在操作实体中的元素时。

 

③.示例:

int[] arr= {2,4,6,8,10,12};

System.out.println(arr);     //输出结果:[I@60e128

“[I@60e128”表示打印了arr这个数组实体的引用。其中“[”表示这是一个一维数组,“I”表示这时一个int类型的数组,而“@”右边的部分表示的是该数组的在内存中的地址(是用hash算法算出来的hash值,用16进制表示)。

 

数组知识点:

     ①.要访问数组中的元素,可以利用角标索引来完成。Java中数组索引编号由0开始。

     ②.在Java中获取数组长度可以通过“数组名.length”的方式。

 

二、数组中的常见操作

1、获取数组中的元素:通常会用到遍历(一般会用到for循环)。

示例:

int[] arr = {2,4,6,8,10,12};
System.out.println("数组长度="+arr.length);
for (int x=0; x<arr.length ; x++ )
{
	System.out.println("arr["+x+"]="+arr[x]+";");
}


2、获取最值(最大值、最小值)。

/*
       获取数组中的最大值。
       思路:
       1、获取最值需要进行比较。每一次比较都会有一个较大的值。因为该值不确定,通过一个变量进行临时存储。
       2、让数组中的每一个元素都和这个变量中的值进行比较。如果大于了变量中的值,就用该变量记录较大的值。
       3、当所有的元素都比较完成,那么该变量中存储的就是数组中的最大值。
 
       步骤:
       1、定义一个变量。初始化为数组中的任意一个元素即可。
       2、通过循环语句对数组进行遍历。
       3、在遍历过程中定义判断条件,如果遍历到的元素比变量中的元素大,赋值给改变量。
 
       需要定义一个功能来完成,以便提高复用性。
       1、明确结果,数组中的元素 int类型。
       2、位置内容:一个数组。int[]。
 */
       public static int getMax(int[] arr)
       {
              int max = arr[0];
              for(int x=1; x<arr.length; x++)
              {
                     if(arr[x]>max)
                            max= arr[x];
              }
              return max;
       }
 
/*
       获取最大值的另一种形式。
       可不可以将临时变量初始化为0呢?
       可以。这种方式,其实是在初始化为数组中的任意一个角标。
*/
       public static int getMax_2(int[] arr)
       {
              int max = 0;
              for(int x=1; x<arr.length; x++)
              {
                     if(arr[x]>arr[max])
                            max= x;
              }
              return arr[max];
       }

/*
       获取最小值。
*/
       public static int getMin(int[] arr)
       {
              int min = arr[0];
              for(int x=1; x<arr.length; x++)
              {
                     if(arr[x]<min)
                            min = arr[x];
              }
              return min;
       }


3、排序(选择排序、冒泡排序)

/*
	选择排序:将数组中的每一个元素分别和它后面的元素进行比较,如果符合判断条件就进行换位。
	内循环结束一次,最值出现在头角标位置上。
*/
	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++)
		{
			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;
				}
			}
		}
	}


 

/*
       折半查找。提高效率,但是必须要保证该数组是有序的数组。
*/
       public static int halfSearch(int[] arr,int key)
       {
              int min,max,mid;
              min = 0;
              max = arr.length-1;
              mid = (max+min)/2;
 
              while(arr[mid]!=key)
              {
                     if(key>arr[mid])
                            min = mid + 1;
                     else if(key<arr[mid])
                            max = mid - 1;
 
                     if(min>max)
                            return -1;
                     mid = (max + min) / 2;
              }
              return mid;
       }
      
/*
       折半的第二种方式。
*/
       public static int halfSearch_2(int[] arr,int key)
       {
              int min = 0,max = arr.length-1,mid;
 
              while(min<=max)
              {
                     mid = (max+min)>>1;
 
                     if(key>arr[mid])
                            min = mid + 1;
                     else if(key<arr[mid])
                            max = mid - 1;
                     else
                            return mid;
              }
              return -1;
       }


三、二维数组

1、二维数组:数组中的数组。(如果一维数组是数学几何中的线性图形,那么二维数组相当于是一个类似Excel表格一样的表格)

2、二维数组的声明格式:

元素类型[][]数组名 = new元素类型[二维数组的长度][一维数组的长度];

元素类型[][]数组名 = {{元素,元素,...},{元素,元素,...},{元素,元素,...},...};

示例1:

int[][] arr =new int[3][2];

  1.  定义了名称为arr的二维数组
  2.  该二维数组中有3个一维数组
  3.  每一个一维数组中有2个元素
  4.  一维数组的名称分别为arr[0], arr[1], arr[2]
  5.  给第一个一维数组1角标位赋值为78写法是:arr[0][1] = 78;


示例2:

int[][] arr =new int[3][];

  1.  二维数组中有3个一维数组
  2.  每个一维数组都是默认初始化值null
  3.  可以对这个三个一维数组分别进行初始化

    arr[0] = newint[3];

    arr[1] = new int[1];

    arr[2] = new int[2];


示例3:

int[][] arr ={{3,8,2},{2,7},{9,0,1,6}};

  1.  定义一个名称为arr的二维数组
  2.  二维数组中的有三个一维数组
  3.  每一个一维数组中具体元素也都已初始化
  4.  第一个一维数组 arr[0] = {3,8,2};
  5.  第二个一维数组 arr[1] = {2,7};
  6.  第三个一维数组 arr[2] = {9,0,1,6};
  7.  第三个一维数组的长度表示方式:arr[2].length;

 

     注意:一维数组如果要全部输出,需要使用一层循环;二维数组全部输出需要二层循环......以此类推,N维数组,则需要N层循环。

 


四、个人总结:

1、数组是一组相同类型的数据的集合。数组按存放元素的复杂程度可以分为一维数组、二维数组...多维数组。

2、Java中的数组使用必须要经过声明和开辟堆内存空间两个步骤。声明数组是在栈内存中开辟空间,可以通过new关键字开辟堆内存空间供数组使用。

3、Java中获取数组的长度可以利用“数组名称.length”这个属性来完成。

4、可以通过角标的方式访问数组中的元素。如果超过了角标的范围,就会出现“角标越界”的异常。

5、数组属于引用数据类型。对数组的引用实际上就是堆内存地址的传递。

6、数组中,多个栈内存空间可以同时指向同一个堆内存地址。

 



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值