数组概述+数组排序+数组查找-第5天

来源:互联网 发布:谷歌访问助手mac版 编辑:程序博客网 时间:2024/05/23 16:36

数组概述+数组排序+数组查找


1、数组(概述-内存结构)

同一种类型数据的集合,其实数组就是一个容器。

数组的好处:

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

格式1:

元素类型[] 数组名 = new 元素类型(元素个数或数组长度)

 

//需求:想定义一个可以存储3个整数的容器

int[] x = new int[3];//new用来在内存中产生一个容器实体,存储实体。x不是int类型,x是数组类型

 

int x=3;//在内存中开辟空间,数据使用完毕会自动释放。

对比:

int x= new int[3];//new在内存中开辟空间,new中元素[0]的地址0x0079赋给x

 

//打印数据角标为0的元素的值。

system.out.println(x[0]);//打印0

system.out.println(x[1]);打印0。没有初始元素x[1],那么int数据默认初始化值为0

 

x[0]=59;

x=null;//x变成垃圾,在不确定的时间内系统会清除它。

//java的垃圾回收机制:成长于c++,优化了c++中的内存部分。当内存中的实体不用,c++由程序员手动调用一个程序去完成垃圾回收这功能。

 

int[] x=new int[3];

int[] y=x;

y[1]=89;

x=null;//没有垃圾。因为y还有利用x所对应的元素。

system.out.println(y[1]);

对比:

int[] x=new int[3];

int[] y=new int[3];

y[1]=89;

system.out.println(x[1]);//打印0。x和y对应的new地址不同

x=null;//有垃圾。x的有无对y没有影响。

system.out.println(x[1]);

 

 

2、数组(静态初始化-常见问题)

int[] arr= new int[2];

对比

int arr[]=new int[2];

 

数组的第二种定义格式

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

对比简化后的式子:

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

system.out.println(arr[2]);//打印6

int[] arr=new int[5];

arr[0]=60;

 

int[] arr=new int[3];

system.out.println(arr[2]);//打印0

system.out.println(arr[3]);//编译通过,运行错误。arrayindexoutofboundsexception;编译时候没有错误提示,没有完全建立数组。运行的时候才会在堆内存中开辟空间[0]、[1]、[2]元素。

 

int[] arr=new int[3];

arr=null;

system.out.println(arr[1]);//编译通过,运行报错。空指针异常;当引用没有任何指向值null的情况,该引用还在用于操作实体。

 

 

3、数组(常见操作-遍历)

//数组的操作

//获取数组中的元素,通常会用到遍历(读取数组的每个元素)。然后通常会用到for循环。

int[] arr=new int[3];

system.out.println("arr["+0+"]="+arr[0]+";");//打印arr[0]=0;

system.out.println("arr["+0+"]="+arr[1]+";");//打印arr[1]=0;

system.out.println("arr["+0+"]="+arr[2]+";");//打印arr[2]=0;

转变为for语句:

int[] arr=new int[3];

for(int x=0;x<3;x++)

{

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

}

 

//数组中有一个属性可以直接获取到数值元素个数

使用方式:数组名称.length

int[] arr={3,6,5,1,8,9};

system.out.println("length:"+arr.length);//打印该数组的每个数

for(int x=0;x<6;x++)

{

system.out.println("arr["+x+"]="+arr[x]+";");

}//依次打印各个元素。

length:6

arr[0]=3;

arr[1]=6;

arr[2]=5;

arr[3]=1;

arr[4]=8;

arr[5]=9;

对比:

通过length实现功能:

int[] arr={3,6,5,1,8,9};

system.out.println("length:"+arr.length);//打印数字的个数

for(int x=0;x<arr.length;x++)//利用数组arr.length=6

{

system.out.println("arr["+x+"]="+arr[x]+";");

}//依次打印各个元素。

length:6

arr[0]=3;

arr[1]=6;

arr[2]=5;

arr[3]=1;

arr[4]=8;

arr[5]=9;

 

实现元素求和功能:

int[] arr={3,6,5,1,8,9};

system.out.println("length:"+arr.length);//打印数字的个数

int sum=0;

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

{

sum +=arr[x];

system.out.println("arr["+x+"]="+arr[x]+";");

}//依次打印各个元素。

length:6

arr[0]=3;

arr[1]=6;

arr[2]=5;

arr[3]=1;

arr[4]=8;

arr[5]=9;

 

//定义一个功能:用于打印数组中的元素,元素间用分号隔开。

class arraydemo

{

public static void main(sting[] args)

{

int[] arr={3,6,5,1,8,9};

printarray(arr);

}

pubic static void printarray(int[] arr)//用的数组的格式int[]

{

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

{

system.out.print(arr[x]+";");

}

}

}

//打印:

3;6;5;1;8;9;//发现结尾了个;不好看,怎么办?

 

class arraydemo

{

public static void main(sting[] args)

{

int[] arr={3,6,5,1,8,9};

printarray(arr);

printarray(arr);

}

pubic static void printarray(int[] arr)

{

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

{

if(x!=arr.length-1)

system.out.print(arr[x]+";");

else

system.out.println(arr[x]); //当打印最后一个元素的时候,不打印";"

}

}

}

//打印:

3;6;5;1;8;9

3;6;5;1;8;9

 

修改版(美化版):

class arraydemo

{

public static void main(sting[] args)

{

int[] arr={3,6,5,1,8,9};

printarray(arr);

}

pubic 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]+"]");

}

}

}

//打印:

[3;6;5;1;8;9]

 

 

4、数组(常见操作-获取最值)

//获取一个数组中的最大值

{5,1,6,4,2,8,9}

思路:

1、获取最值需要进行比较,每一次比较都会有一个较大的值,因为该值不确定,通过一个变量进行临时存储。

2、让数组中的每一个元素都和这个变量中的值进行比较

如果大于了变量中的值,就用该变量记录较大的值

3、当所以的元素都比较完成,那么该变量中存储的就是数组中的最大值了\\

 

步骤:

1、定义变量,初始化为数组中任意一个元素即可。

2、通过循环语句对数组进行遍历

3、在变量过程中定义判断条件,如果遍历到的元素比变量中的元素大,就赋值给该变量。

 

需要定义一个功能来完成,以便提高复用性。

1、明确结果,数组中的最大元素 int

2、未知内容:一个数组。int[]

public static int getmax(int[] arr)

{

int max=arr[0];//初始化arr[0]的值时,放在函数的内部更好,阅读和理解性更强。

for(int x=1;x<arr.length;x++)//这样x从1开始就可以了。

{

if(arr[x]>max)

max=arr[x];

}

return max;

}

public static void main(sting[] args)

{

int[] arr={5,1,6,4,2,8,9};

int max=getmax(arr);//定义函数

system.out.println("max="+max);

}//打印max=9;验证功能实现。

 

获取最大值的另外一种方法。

可不可以将临时变量初始化为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 void main(sting[] args)

{

int[] arr={5,1,6,4,2,8,9};

int max=getmax_2(arr);

system.out.println("max="+max);

}//打印max=9;验证功能实现。

 

//需求:获取最小值。恰好相反。由>变<

public static int getmin(int[] arr)

{

int min=0;

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

{

if(arr[x]<arr[min])

min=x;

}

return arr[min];

}

public static void main(sting[] args)

{

int[] arr={5,1,6,4,2,8,9};

int min=getmin(arr);

system.out.println("min="+min);

}//打印min=1;验证功能实现。

 

//需求:获取duoble类型数组的最大值。因为功能一致,所以定义相同函数名称。以重载形式存在。

public static double getmax(duoble[] arr)

{

.............内容同上面的相似。

 

 

5、数组(排序-选择排序)

{5,1,6,2,8,9}

//给数组的元素从小到大进行排序。

步骤:

可以看出比较的次数:依次减少。

*****嵌套循环。

****

***

**

*

 

class arraytest

{

public static void selectsort(int[] arr)

{

for(int x=0;x<arr.length-1;x++)//没必要遍历到最后一个角标,当x=5,y=6,超出范围。

{

for(int y=x+1;y<arr.lenght;y++)//尖朝下,改变初始条件

{

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

{int temp= arr[x];

arr[x]=arr[y];

arr[y]=temp;

}

}

}

public static void main(sting[] args)

{

int[] arr={5,1,6,2,8,9};

//在排序前打印;

printarray(arr);

selectsort(arr);

//在排序后打印;

printarray(arr);

}

//定义一个打印数组功能的函数

pubic 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]+"]");

}

}

//打印

[5, 1, 6, 2, 8, 9]

[1, 2, 5, 6, 8, 9]

 

//给数组的元素从大到小进行排序。同理把>变成<即可

class arraytest

{

public static void selectsort(int[] arr)

{

for(int x=0;x<arr.length-1;x++)//没必要遍历到最后一个角标

{

for(int y=x+1;y<arr.lenght;y++)

{

if(arr[x]<arr[y])

{int temp= arr[x];

arr[x]=arr[y];

arr[y]=temp;

}

}

}

public static void main(sting[] args)

{

int[] arr={5,1,6,2,8,9};

//在排序前打印;

printarray(arr);

selectsort(arr);

//在排序后打印;

printarray(arr);

}

 

pubic 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]+"]");

}

}

//打印

[5, 1, 6, 2, 8, 9]

[9, 8, 6, 5, 2, 1]

 

//总结:选择排序:

内循环结束一次,值出现角标位置。

 

 

6、数组排序-冒泡排序

所谓冒泡:就是经过排序后,越大的数会慢慢浮到数组的顶端。像气泡一样,越大越往上

大的数往后面移。

冒泡排序:相邻的两个元素进行比较,如果符合条件换位。最后位得出一个最值数,第二次比较就少了一个元素;以此类推,次数越多,需要比较的元素越少。

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是让每一次比较的元素随着x减少,比如:第2次比较时,就少了x=1个元素;-1,避免角标越界,For循环中y+1会超出范围。

{

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

{

int temp=arr[y];

arr[y]=arr[y+1];

arr[y+1]=temp;

}

}

}

}

//冒泡排序:最值出现在最后面。

 

 

7、数组排序-位置置换功能抽取

//发现无论什么排序,都需要对满足条件的元素进行位置置换。

所以可以把这部分相同的代码提取出来,单独封装成一个函数。

public static void swap(int[] arr,int a,int b)//这里要定义三个变量,是因为需要把数组传递

{

int temp =arr[a];

arr[a]=arr[b];

arr[b]=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])

{

swap(arr,y,y+1);//函数的精髓。函数嵌套。

}

}

}

}

顺序排序的代码变成如下:(从小到大排序)

public static void selectsort(int[] arr)

{

for(int x=0;x<arr.length-1;x++)//没必要遍历到最后一个角标,下面的for中有x+1,会超出范围

{

for(int y=x+1;y<arr.lenght;y++)//这里y=x可以吗?可以是可以但是这样会增加运算量。

{

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

{

swap(arr,x,y);

}

}

}

 

 

8、数组(折半查找)

数组的查找操作。

class arraytest4

{

public stativ void main(sting[] args)

{

int[] arr={2,4,5,7,19,32,45};

int index=getindex(arr,19);

system.out.println("index="+index);//打印角标4

}

普通查找法:

//定义功能:获取key第一次出现在数组中的位置。如果返回-1代表key在该数组中不存在。

public static int getindex(int[] arr,intkey)

{

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

{

if(arr[x]==key)

return x;

}

return -1;//-1代表这个数组的角标不存在,是惯例。

}

}

 

折半查找:提高效率,但是必需要保证该数组是有序的数组。

class arraytest4

{

public stativ void main(sting[] args)

{

int[] arr={2,4,5,7,19,32,45};//数组有序,可以采样折半查找

int index= halfsearch(arr,32);

system.out.println("index="+index);//打印下标5

}

public static int halfsearch(int[] arr,intkey)

{//定义边界

int min,max,mid;

min=0;//最小的数组元素下标0

max=arr.length-1;//最大的数组元素下标

mid=(max+min)/2;//中间数组元素的下标

while(arr[mid]!=key)

{//与mid中间下标做比较

if(arr[mid]<key)//目标元素key>mid,

min=mid+1;//范围缩小到右半边

else if(arr[mid]>key)

max=mid-1;

if(min>max)//?????当目标不属于该数组时这种思路比较巧,可以通过数字3来验证。

return -1;  

mid=(max+min)/2;

 

}

return mid;

}

}

方法2:

class arraytest4

{

public static void main(sting[] args)

{

int[] arr={2,4,5,7,19,32,45};

int index= halfsearch(arr,5);

system.out.println("index="+index);//打印下标2

}

public static int halfsearch(int[] arr,intkey)

{

int min=0,max=arr.length-1,mid;

while(min<=max)//?????当数是属于该数组的时候

{

mid=(min+max)>>1;//把除2运算转变成,位运算右移1位。

if(key>arr[mid])

min=mid+1;

else if(key<arr[mid])

max=mid-1;

else

return mid;

}

return -1;

}

 

//有一个有序的数组,想要将一个元素插入到该数组中,

还有保证该数组是有序的。

如何获取该元素在数组中的位置。??比如:元素8

class arraytest

{

public static void main(sting[] args)

{

int[] arr={2,4,5,7,19,32,45};

int index= halfsearch(arr,8);//输入元素8

system.out.println("index="+index);//打印下标4

}

public static int halfsearch(int[] arr,intkey)

{

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需要插入位置的下标。

}

参考下面的注释:

2       4       5       7       19     32     45数组元素

0       1       2       3       4       5       6(数组的下标)

min=0;max=6;mid=6>>1=3;

key=8>7(mid);min=mid+1=4;mid=(4+6)/2=5;

2       4       5       7       19     32     45数组元素

0       1       2       3       4       5       6(数组的下标)

                                min mid

 

8<32(mid);max=mid-1=4;mid=(4+4)/2=4;

2       4       5       7       19     32     45数组元素

0       1       2       3       4       5       6(数组的下标)

                                min

                                     mid

8<19(mid);max=mid-1=3;//此时max<min,结束while循环

 

0 0
原创粉丝点击