黑马程序员_数组的理解

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

1、数组的静态初始化

数组:

 同一种数据类型的集合。也就是容器

多种定义格式:

Int[] arr=newint[]//标准格式,可以明确数组的数据类型,和数组名,但是不知道数组的长度

Int[] arr=newint[]{2,1,3,4,5,}//通过大括号可以标示出数组中的内容,此处最好别写长度,因为容易出错,因为即初始化实体,又初始化实体中的元素。

Int[]arr={2,1,3,4,5};//可以明确数组的数据类型,和数组名,也可以知道数组中的内容。

2、arr.length:方便获取数组中的元素个数的方式。

3、操作数组的最基础的思想以及核心思想:

a)        最基础的思想:就是遍历。什么是遍历。

Egint[] arr =new int[3];

       int[] arr ={4,8,9,2,6,9};//明确了数组的类型和长度,并明确了数组中元素的内容。

//     int[] arr1 = newint[]{4,8,9};

       //方便获取数组中的元素个数的方式,可以使用数组实体一个属性。length

       System.out.println("len:"+arr.length);  

       for(int x=0;x<arr.length; x++)

       {

              if(x%2==1)

                     System.out.println("arr["+x+"]="+arr[x]);//arr[0]= 4;

       }

 这就是遍历的思想,获取数组中的元素,通常会用到遍历。

b)核心思想:就是操作数组中元素的角标,角标即索引,因为存数据的最终目的就是取出数据使用,就是操作角标,操作动作:1、给数组角标上的元素赋值,2、获取角标上元素的值,存储都得用角标

 

4、数组中常见的操作:

a)        获取最值:

思路:

1、首先我们要定义一个功能完成获取数组中最大值的动作;

2、定义个函数来实现这一功能;明确结果,整数数组中的最大值,int,明确是否有未知内容参与运算,参数列表中有一个参数,数组类型int[],一定要注意这里是数组类型,不是int型;

3、如何实现功能细节呢?

1、对数组中的元素进行比较,将比较后比较大的值进行记录,并参与下一次比较,当数组中的元素都比较完成后,最大值就已经被记录下来了。

2、每次比较的较大的值不确定,定义一个变量进行记录,该变量如何初始化呢?只要初始化为数组中的一个元素即可。

3、应该让数组中的元素自动和该变量记录的元素进行比较,所以可以使用遍历,获取数组中的每一个元素。

4、当遍历到元素比变量中的记录的元素大,用该变量记录住更大的元素。

5、遍历结束后,变量存储就是数组中的最大值。

实现代码:eg

Public staticint getMax(int arr)

{

/.定变量记录较大的值;

Int max=arr[0];//初始化数组中的任意个元素;

//对数组进行遍历比较

For(int x=1;x<arr.length;x++)

{

If(arr[x]>max)

Max=arr[x];

}

Return max;

}

同样有另外一种方式获取最大值

Public staticint getMax(int[] arr)

{

Int maxIndex=0;//初始化为数组中一个元素的角标

For(int x=1;x<arr.length;x++)

{

If(arr[x]>arr[maxIndex])

maxIndex=x;

}

Return arr[maxIndex];

}

b)       排序:

1、选择排序:

首先通过数组中元素的比较方式来分析:

用数组中第一个角标的元素与数组中第二个角标的元素进行比较,发现96大,进行位置置换,此处应该定义一个三方变量,用来记录住置换过程的元素值,然后再用第一个角标的元素与下一个角标元素进行比较,按照全面的原则进行置换位置,如果前者小于后者,则不置换位置,一次比较,当第一轮结束之后第一个角标出能取的该数组中最小的元素的值,然后再用第一个角标的元素开始和下一个角标的元素进行比较,同理,当第二轮结束后,第二个角标处获取了该数组中的第二小的值。所以我们发现当依次这样比较下去,就可以对数组中的元素进行排序,当比较到arr.length-1元素时,发现只剩下这一个元素,没有其他元素和它进行比较了。

思路:

1、首先定义一个功能函数对数组进行排序,

2、明确结果,没有返回值,因为它只是对数组进行排序的一个动作,明确是否有未知内容参与运算,有,数组类型int[] arr

实现代码:

Public static void selectSort(int[] arr)

{

For(int x=0;x<arr.length-1;x++)

{

For(int y=x+1y<arr.length;y++)

{
              if(arr[x]>arr[y])

{

Int temp=arr[x];

Arr[x]=arr[y];

Arr[y]=temp;

}

}

}

}    

优化后的选择排序:

从上面的排序图中我们可以知道,对数组中元素进行置换位置的次数过多,也就是对堆内存的操作频繁,降低了性能,下面我们可以通过这种方式对性能优化。

思路:

在栈内存中我们定义两个变量,分别用来记录较小的元素的值和较小元素的角标,然后对其进行初始化,至于初始化的值只要是数组中的任意元素即可,然后拿数组中的元素与它进行比较,如果发现拿去比较的元素比变量中记录的数值要小,那么就进行位置置换,并记录下较小的元素的角标,依次把数组中的元素遍历完,就可以获取数组中的最小元素的值和角标,然后我们拿初始化的值和获取的最小的元素进行位置的置换,这样以来当我们获取了数组中的元素的最小的时候,堆内存中的只用操作一次位置即可,这样的就提高性能。

实现代码:

Public staticvoid selectSort_2int[] arr

{

For(int x=0;x<arr.length-1;x++)

{

Int num=arr[x];

Int index=x;

For(int y=x+1;y<arr.length;y++)

{

If(num>arr[y])

Num=arr[y];

Index=y;

}

If(index!=x)

{

       int temp = arr[x];

       arr[x] = arr[index];

       arr[index] = temp;

}

 

}

}

注意:复习的时候添加注释

 

2、冒泡排序:

首先通过排序方式来分析其步骤:

通过排序方式,可以知道是用数组中的元素挨个比较,如果前面的元素的值比它下一个角标的元素大,则进行位置置换,然后再用第二个角标的元素与下一个角标的元素进行比较,同样如果下一个角标的元素比它小,则进行位置置换,这样当比较到arr.length-1个元素时已经没有和它进行的比较的元素了,当第一轮比较结束后,我们可以知道最后一个角标的元素为该数组中的最大值,按照同样的原理进行下一次比较,依次获取了比较大的元素的值。

实现代码:

Public static void bubbleSort(int[] arr)

{

For(int x=0;x<arr.length-1;x++)

{

For(int y=0;y<arr.length-1-x;y++)//-1的目的是因为遍历到最后避免角标越界,-x是因为随着x的递增,参与比较的元素递减,      

{

If(arr[y]>arr[y+1])

{

//位置置换

}

}

}

}

 

a)        折半查找:

首先分析数组元素的查找方式:

首先要明确数组时有序的。

首先定义三个变量minmidmax分来用来记录最小角标、中间角标、最大角标,中间角标的获取为(min+max)/2;获取中间角标之后,就可以获取中间角标对应的元素arr[mid];用我们所需要查找的key与中间角标运算进行比较,如果key>arr[mid];那么此时min的位置就是mid的下一个角标,min=mid+1;然后再次获取中间角标的元素,mid=(min+max)/2,同时也获取了中间角标对应的数组元素,arr[mid],然后同理,拿key与中间角标的元素进行比较.同样的原则,依次比较,直到key==arr[mid]的时候获取key.如果当出现了min>max或者时候则说明我们要查找的key在该数组中布存在,return-1

实现代码:

Public static void binarySearch(int[] arr int key)

{

Int min,mid,max;

Min=0;

Max=arr.length-1;

Mid=(min+max)>>1//相当于/2,右移的效率比它要高

While(arr[mid]!=key)

{

If(key>arr[mid])

Min=mid+1;

Else ifkey<arr[mid]

Min=mid-1;

If(max<min)

Return -1;

Mid=(max+min)>>1;

}

Return mid;

}

注意:复习的添加代码注释

总结:折半查找也称二分查找,这种查找可以提高效率,但是被查找的数组的额元素必须是有序的。不能对无序的数组进行排序后再用折半查找,因为这时候数组中元素的角标已经发生变化了。

 

5、查表法思想:

a)        什么时候使用查表法?

当元素很多,而且这些元素与数组有对应关系,而且这些数字都有角标的规律的时候。

扩展:什么时候使用数组?

当同一类型的元素较多时,就使用数组这个容器对数据进行存储。

b)       查表法思想的代码体现:

0  1  2 3  4  5  6  7  8   9  10 11  12  13 14  15

'0', '1', '2',  '3','4','5',  '6',' 7',  '8', '9','A','  B',  'C' ,'D', 'E' ,'F'

我们发现十六进制中一共有16个元素,而且每通过&15获取的数字都再15之内,都有对应的十六进制元素,而且元素对应的数字正好有规律,而且符合了数组这种容器的特点角标,那么可以将十六进制的元素都存储到数组中,将每次&15的结果作为角标去查这个数组,就可以获取到十六进制的对应的元素。这就是查表思想。

代码体现:

Public static void searchList(int num)

{     //定义一个十六进制的元素表

Char[] arr={'0', '1', '2', '3', '4','5',  '6',' 7',  '8', '9','A','  B',  'C' ,'D', 'E' ,'F'};

//定义一个char类型元素的数组,用于存储每次获取到的十六进制值。

Char[] chs=new char[8];

Int pos=chs.length;

While(num!=0)

{

Int temp=num&15;

Chs[--pos]=arr[temp];

Num=num>>>4;

}

For(int x=pos;x<chs.length;x++)

{

//打印数组;

}

}

注意:复习时添加代码注释;

 通过上面我们可以知道那么是否可以定义这样的一个功能函数呢?用来对十进制、二进制、八进制、十六进制进行转换?

思路:

1、明确结果,没有返回值,只是对给定的数据转换的功能。

2、明确是否有未知内容参与运算,有,是什么?求的数值num,十六进制是&15,八进制是&7,二进制是&1,那么&的这个是不确定的,我们定义为变量 base,当这个数值通过&上这些数据后,要取出后面的数值,我们通过右移来实现,但是各个进制的不一样右移的位置数也是不一样的,十六进制是无条件右移四位,八进制是无条件右移三位,二进制是无条件右移1位,所以这个数也是不确定的,定义变量 offset

实现代码:

//十进制--二进制

public staticvoid toBin(int num)

{

       trans(num,1,1);

       }

//十进制--八进制

public staticvoid toOctal(int num)

{

       trans(num,7,3);

}

//十进制--十六进制

       publicstatic void toHex(int num)

       {

       trans(num,15,4);

}

Public staticvoid trans(int num,int base,int offset)

{

If(num==0)

{

Sop(0);;

Return;

}

//定义一个十六进制的元素表

Char[] arr={0', '1', '2', '3', '4',  '5',  '6',  '7',  '8', '9',  'A','  B', 'C' ,' D',  'E' ,'F'};

Char[] chs=new char[32];

Int pos=chs.length;

While(num!=0)

{

Int temp=num&base;

Chs[--pos]=arr[temp];

Num=num>>>offset;

}

For(ingt x=pos;x<chs.length;x++)

{

System.outr.println(chs[x]);

}

}

 

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

详细请查看:http://edu.csdn.net/heima

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值