再谈数组
在这一篇中我们来讲一下关于数组的排序和查找的方法。
排序
说到数组的排序,就不得不说冒泡这种经典的方法。
1.冒泡排序
冒泡排序的基本思想是比较两个相邻元素的值,如果满足条件就交换元素的值(如果是升序,就将较大的值放在索引大的引用内,较小的值放在索引小的引用内;降序的话反之),这样一次循环后最大或最小的值就会转移到数组的最后的位置,经过多次循环后数组就会按要求排好。
具体算法如下(以升序为例):
publicstaticvoid swap(int[] array)
{
boolean a = false;
for(int i = 0 ; i <array.length-1;i++)
{
for(int j= 0 ;j<array.length - i-1;j++)
{
if(array[j]>array[j+1])
{
int t= array[j];
array[j]= array[j+1];
array[j+1]= t;
a =true;
}
}
if(!a)
{
return;
}
}
}
在这个方法中我们一共用了两层循环,内层循环是用来使最大的一个数移到数组的最后的位置,第二次把大二大的数移到数组倒数第二的位置,第一次循环是用来决定第二层循环一共需要循环多少次,外层循环每循环一次,内层循环就会少个需要比较的元素,这个元素就是我们上一次内层循环放到后面的数组元素值。
在这个方法中我还定义了一个布尔类型的变量,主要是用来提高程序的效率,如果某次内层循环一次交换也没有,说明当前数组的顺序已经满足要求了,没有必要进行后面的循环了,跳出即可。
冒泡排序我们就将这么多,我们来介绍另一种排序方式。
2.交换排序
这种排序是将每一个元素都与第一个元素进行比较,只要比第一个元素小就交换,最后就会将最小的元素放到第一个位置。在将后面的元素与第二个元素进行比较交换,同理第二小的元素就会放到第二个位置。以此类推,将数组元素顺序排好。具体算法如下(以升序为例):
publicstaticvoidswapOne(int[] array)
{
for(int i= 0 ; i <array.length-1;i++)
{
for(int j = i+1 ;j<array.length;j++)
{
if(array[i]>array[j])
{
int t = array[j];
array[j] = array[i];
array[i] = t;
}
}
}
}
在这种方法中也是用到了两层循环,内层循环是将要比较的元素与后面的元素依次进行比较,不符合条件就交换,实现最小的或最大的放到最前面。外层循环的次数是和数组元素的个数减一一样,因为有几个元素就需要把几个元素减一放到前面。这个描述起来可能不太好理解,大家可以根据程序来理解一下。
3.选择排序
选择排序的思想是将所有的数先就行比较,但不进行交换,只是将最大的进行标记,比较完后,将被标记的元素放到最后,然后进行下一次寻找,最后将数组元素的顺序排好。具体算法如下(以升序为例):
publicstaticvoidswapTwo(int[] array)
{
int k ;
for(int i = 0;i<array.length;i++)
{
k =0;
for(int j= 0; j<array.length-i;j++)
{
if(array[j]>array[k])
{
k =j;
}
}
int t= array[array.length - i-1];
array[array.length - i-1] = array[k];
array[k]= t;
}
}
这个方法的思路还是比较清晰的,需要注意的是用来标记的变量需要在每次外循环开始的时候清零,别的我就不多说了,下面来说说查找。
查找
最简单的查找一个数组中是否有某个元素的方法就是一个一个元素的与目标值进行比较,实现方法非常的简单,而且会大量浪费程序运行的时间,所以我们并不推荐使用。下面我来讲一下我们最常用的查找方法:二分法。
二分法
要想使用二分法是有一个前提条件的,就是数组必须是有序的。这与他的实现思路有关,他是这样实现的,先讲数组的最中间的元素的值与目标值进行比较,相等返回索引,大于目标值就将前半段的中间元素的值与目标元素进行比较,大、小于目标值就将后半段的中间元素的值与目标元素进行比较。以此类推,如果直到最后都没有,则就是没有找到目标值。具体算法如下:
publicstaticintcompare(int[] array,int i)
{
int low = 0;
int high = array.length;
int j = (low+high)/2;
while(low<=high)
{
if(array[j]== i)
{
return j;
}
else if(array[j]>i)
{
high = j-1;
j = (high+low)/2;
}
else
{
low = j+1;
j = (high + low)/2;
}
}
return -1;
}
在这个方法中变量low表示是还未进行比较的部分的最小的索引值,同理high表示最大的索引值,每一次循环都会改变low或high的值来进行下一次比较,直到找到该元素,或low>high。这个方法还是比较好理解的,我就说这么多吧。