一、冒泡排序
冒泡排序法的运行机制是通过循环遍历元素并调整相邻元素顺序来实现的一种简单排序方法。
产生历程:
以升序为例,冒泡排序的主要原理就是逐个比较大小,将最大元素排到最后,循环多次直到所有元素升序排列。于是可以写出如下代码:
public class Test {
public static void main(String[] args) {
int [] scores= {3,1024,66,9,11};
for (int i = 0; i < scores.length - 1; i++) {
int current = scores[i];
int next = scores[i + 1];
if (current > next) {
scores[i + 1] = current;
scores[i] = next;
}
}
for (int i = 0; i < scores.length - 1; i++) {
int current = scores[i];
int next = scores[i + 1];
if (current > next) {
scores[i + 1] = current;
scores[i] = next;
}
}
for (int i = 0; i < scores.length - 1; i++) {
int current = scores[i];
int next = scores[i + 1];
if (current > next) {
scores[i + 1] = current;
scores[i] = next;
}
}
for (int i = 0; i < scores.length - 1; i++) {
int current = scores[i];
int next = scores[i + 1];
if (current > next) {
scores[i + 1] = current;
scores[i] = next;
}
}
for (int i : scores) {
System.out.println(i);
}
}
}
从上面代码可总结出,如果数组里有五个元素,那么就需要循环“找最大值”这一操作四遍,即循环次数为数组长度减一。那么代码可以优化为如下形式:
public class Test {
public static void main(String[] args) {
int [] scores= {3,1024,66,9,11};
for(int time = 1;time <= scores.length - 1;time++){
for (int i = 0; i < scores.length - 1; i++) {
int current = scores[i];
int next = scores[i + 1];
if (current > next) {
scores[i + 1] = current;
scores[i] = next;
}
}
}
for (int i : scores) {
System.out.println(i);
}
}
}
但是上面这种方法仍然不够高效,是因为每次排序都会与已经排在合适位置的最大值进行比较,而这是无用的,因此可以考虑每次排序仅比较到上次排序所得最大值位置就结束即可:
public class Test {
public static void main(String[] args) {
int [] scores= {3,1024,66,9,11};
for(int time = 1;time <= scores.length - 1;time++){
for (int i = 0; i < scores.length - time; i++) {
int current = scores[i];
int next = scores[i + 1];
if (current > next) {
scores[i + 1] = current;
scores[i] = next;
}
}
}
for (int i : scores) {
System.out.println(i);
}
}
}
这样就实现了冒泡排序!
二、插入排序
每循环一次都将一个待排序的元素所对应的数据按其顺序大小插入到前面已经排序的序列的合适位置,直到全部插入排序完为止。
插入排序的实质:将数组分为有序区和无序区,定义一个标记无序区第一个元素的定位变量,将该元素与前面的有序区内元素遍历比较,找到该元素应该插入位置,然后将应插入位置到待插入元素所在位置之间的元素后移一位,最后再将待插入元素插入到应插入的位置,有序区扩增一位,无序区减少一位,定位变量再次后移,锁定后面无序区第一位元素位置。
产生历程:
要探究插入排序产生历程,我们先以插入一个元素为例,例如现有一数组{1,2,4,5,3},要实现将3插入到合适的位置实现数组的升序排列,那么此时就需要:1、先找到应该插入的位置。2、移动插入位置之后的元素。3、插入元素。具体操作如下例:
public class Test {
public static void main(String[] args) {
int scores [] = {1,2,4,5,3};
int i = 4;//确定需要插入的元素
int data = scores[i];
int j = 0;
for (; j < i; j++) {
if (scores[j] > data) {//找到第一个比插入元素大的元素,它的位置就是将被插入的位置
break;
}
}
for (int k = i; k > j; k--) {//将插入位置后的元素后移
scores[k] = scores[k - 1];
}
scores[j] = data;//插入元素
for (int score : scores) {
System.out.println(score);
}
}
}
通过上面例子,我们可以做如下推广,对于一个随机的无序数组{1,3,2,9,4,7},对于它的排序可以理解为第二个元素插入到前一个元素中,这样前两个元素就是升序了;接下来将第三个元素插入到前两个元素中,这样前三个元素就是升序了;以此类推,直到第六个元素插入前五个元素中,这样六个元素都为升序了。而要实现这种过程,仅需将上面基础插入排序方法重复几次即可,如下例:
public class Test {
public static void main(String[] args) {
int scores [] = {1,3,2,9,4,7};
for (int i = 1; i < scores.length; i++) {
int data = scores[i];//插入元素为序号为i的元素(从第二个到最后一个)
int j = 0;
for (; j < i; j++) {
if (scores[j] > data) {
break;
}
}
for (int k = i; k > j; k--) {
scores[k] = scores[k - 1];
}
scores[j] = data;
}
for (int score : scores) {
System.out.println(score);
}
}
}
这样就实现了插入排序!