前面说过二分法是需要在有序数组上来做的,现在就来看看数组排序的三种简单方式。
1 冒泡排序
冒泡排序这个比较最简单了,也是最直接的一种排序方式。通常对于数据较少的情况下还是可以拿来使用的,对于数据较多冒泡排序效率就比较低了。冒泡排序的思路就是在每次通过相邻比较后得到一个最大的数放在数组末端(升序)。直接看代码:
public void bubbleSort ()
{
int out, in;
for (out=nElems-1 ; out>1 ; out--)
for (in=0 ; in<out; in++)
if ( a[in] > a[in+1 ] )
swap(in, in+1 );
}
private void swap (int one, int two)
{
long temp = a[one];
a[one] = a[two];
a[two] = temp;
}
冒泡程序主要是内外两层循环来实现的,通过比较,如果前面一个数大于后面一个数就要交换。
2 选择排序
选择排序则是在冒泡排序的基础上改进的,减少了交换次数,但是比较次数还是一样的。但是这个结果是有意义的,因为交换在内存中使用比较频繁,减少内存操作。
选择排序:它的工作原理是每一次从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
void sort(int list[], int n)
{
int i, j, min, temp;
for (i = 0 ; i <nElems-1 ; i++){
min = i;
for (j = i + 1 ; j <nElems-1 ; j++)
if (list[j] < list[min])
min = j;
SWAP(list[i], list[min]);
}
}
上面的代码两层循环,外层循环控制的是数据交换,内层循环控制的是数据找到一个最小的数再与外层数据进行交换。这样实现选择排序。
3 插入排序
插入排序是大多数情况下使用的一种,也是效率较好的一种。通常要比冒泡排序快一倍,比选择排序还要快一点。并不复杂,通常用在比较复杂的排序算法最后阶段。
理解插入排序首先要理解局部有序。局部有序就是指在数组标记数据之前都是有序的,已经排好序的,这就是局部有序。当我们让这个标记的队员动起来以后就是实现插入排序的过程了。被标记数组成员就要通过左移插入有序局部数组中,局部有序数组中的一些数组成员就要后移,看以下demo代码。
public void insertSort()
{
int in ,out ;
for (out =1 ;out <a.length;out ++)
{
int temp=a[out ];
in =out ;
while (in >0 && (a[in -1 ]>=temp))
{
a[in ]=a[in -1 ];
--in ;
}
a[in ]=temp;
}
}
以上程序的注释解释了插入排序的实现过程。插入排序具有不变形,每次都会是局部有序,一直到整体有序。
三种简单排序的效率比较:
冒泡排序比较次数为:N*(N-1)/2 交换次数与N平方成正比。
选择排序:交换次数O(N)这一点已经在冒泡的基础上改进了,但是比较次数还是O(N*N)。
插入排序: 运行时间O(N),一般来说插入排序比冒泡排序效率高,也比选择排序有优势。
java对象排序
有时候排序不仅仅是针对纯数字进行排序,还需要对字符串等进行排序。例如对人名进行排序可能就是对单词进行排序。单词排序就是采用java compareTo()方法。
String s1,s2;
s1.compareTo(s2);
上面的就是对字符字典顺序进行比较,结果返回一个数字。s1
String s1 = "abcd" ;
String s2 = "abce" ;
String s3 = "Abc" ;
String s4 = "abcdefg" ;
System.out.println(s1.compareTo(s2));
System.out.println(s1.compareTo(s3));
System.out.println(s4.compareTo(s1));
System.out.println(s4.compareTo(s2));
输出结果:-1 32 3 -1 。第一个不相同就计算字典减法。当两个字符串与另外一个字符串的一部分完全相同时就只用计算较长字符串多的那部分字符个数。
以上都是在数组排序中遇到的简单排序方法。由于数组当数据数量增多时在查找、排序、删除等方面效率都不是很高,还有数据一旦建立就不能随便修改大小了。除了数组还有其它的数据结构,在使用中更灵活、实用。