前言:
排序算法是《数据结构与算法》中最基本的算法之一。
排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。
这个排序算法很多,初学者需要学习掌握冒泡排序、选择排序、插入排序这三种,简单易懂,容易学习。下面就以数组为例,说一下冒泡排序、选择排序、插入排序。
1、冒泡排序
思路:
取出数组中相邻两个数比较,按照升序或者降序调整两个数的位置,不断地重复这个动作,直到所有的数的位置是升序或者降序为止。
步骤(升序):
1、取出数组中相邻的两个数比较大小,如果第一个数比第二个数大,就交换两个数的位置,这样整个数组中的较大的元素都在数组的后面移动;
2、从数组的第一个元素开始是重复上面操作 ,直到最后一个,此时最后一个元素必定为数组中最大的那个元素;
3、对数组中的所有元素重复上面的操作,除了最后一个(因为最后一个元素已经是最大的元素);
4、不断重复上面操作,每次从后面减少一个元素(原因和上面一样);
动画演示
代码如下:
public static void main(String[] args) {
int[] a = {8, 4, 7, 6, 3, 2, 5, 1};
int temp = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(a));
}
结果如下:
[1, 2, 3, 4, 5, 6, 7, 8]
Process finished with exit code 0
外层for循环是控制对整个数组操作的次数;
内层for循环是控制对数组每一次操作的次数;
if判断控制的是对相邻两数位置的调整;
整个代码是比较容易理解的,所以就不多叙述了,当然,这也只是一种实现方法,重要的是要理解冒泡排序的思路。
2、选择排序
思路:
不断从数组中找到最小的元素,从数组第一个或者最后一个开始排列,最终达到升序或者降序。
步骤(升序):
1、从数组中找到最小的元素,然后和数组第一个元素交换位置;
2、在数组剩下的元素中找到最小的元素,和第二个元素交换位置;
3、重复上面的操作,直到整个数组达到升序或者降序;
动画演示
代码如下:
public static void main(String[] args) {
int[] a = {8, 4, 7, 6, 3, 2, 5, 1};
int temp=0;
for (int i = 0; i < a.length-1; i++) {
int minindex=i;
for (int j = i+1; j < a.length; j++) {
if (a[minindex] >a[j]) {
minindex=j;
}
}
if (a[i] !=a[minindex] ) {
temp=a[minindex];
a[minindex]=a[i];
a[i]=temp;
}
}
System.out.println(Arrays.toString(a));
}
结果如下:
[1, 2, 3, 4, 5, 6, 7, 8]
Process finished with exit code 0
外层for循环是控制对整个数组操作的次数;
内层for循环是控制对数组每一次操作的次数;
第一个if判断控制在循环过程中的不断拿到数组中最小元素的索引;
第二个fif判断控制的是在每一次对数组操作完后,将每次的最小值移到前面对应的位置上。
整个代码是比较容易理解的,所以就不多叙述了,当然,这也只是一种实现方法,重要的是要理解选择排序的思路。
3、插入排序
思路:
就是不断从数组中拿出一个数,按元素顺序插入数组前一部分已经排好顺序的元素中,就类似于打扑克,整理牌的过程。
步骤:
1、将数组中的第一个元素看做一个已将排好序的;
2、然后从后面取一个元素,和已经排好序的元素们从后向前挨个比较,并按大小调整位置;
3、重复上面的操作,直到排完所有元素;
动画演示
代码如下:
public static void main(String[] args) {
int[] a = {8, 4, 7, 6, 3, 2, 5, 1};
int temp = 0;
for (int i = 1; i < a.length; i++) {
for (int j = i; j > 0; j--) {
if (a[j] < a[j - 1]) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
System.out.println(Arrays.toString(a));
}
结果如下:
[1, 2, 3, 4, 5, 6, 7, 8]
Process finished with exit code 0
外层for循环是控制在数组中取出元素的次数;
内层for循环是控制取出元素在数组中与前面已排好序的元素的对比次数;
if判断控制在循环过程中的取出元素和前面元素的位置调整;
整个代码是比较容易理解的,所以就不多叙述了,当然,这也只是一种实现方法,重要的是要理解插入排序的思路,和冒泡排序的思路有点像。