刚开始学习Java,大家都会学习排序算法,但是只有理解了排序的方法,才能更好的将其转换为代码。刚开始学习我也为了理解算法绞尽脑汁,现在我将自己对排序算法的理解写下来,希望能够帮助到初入Java殿堂的朋友们。
一、选择排序
1.对选择排序的理解
排序的目的就是要将无序的数列转变为有序的数列。而有序的数列中每一个数字都对应着一个相应的位置。选择算法其实就是根据位置找到对应的数字。
假设我们有这样一组数列:
int[] arr = {5, 8, 3, 6, 1};
我们要将它按从小到大的顺序进行排序。那么第一个位置也就是arr[0]
应该对应的是最小的数字。将原来的arr[0]
与它后面的arr[1]
比较,将小的数留在arr[0]
,再用新的arr[0]
与arr[2]
进行比较,并将小的数留在arr[0]
,以此类推,最后就能确保arr[0]
上的数是最小的。接下来的工作就和上面一样,就是在去掉最小数字的情况下,让arr[1]
对应的是剩余数字中最小的数字。这样依次选定arr[i]
上的数字,一直到倒数第二个位置的数字确定,就完成了排序。
2.代码
`for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}`
因为只需要确定到倒数第二个就完成了排序,所以最外层循环的只需要执行arr.length - 1
次。因为每个位置的数字都需要与后面的所有数字进行比较,所以j
的值要从i + 1
取到arr.length
。
二、冒泡排序
1.对冒泡排序的理解
(图片来自张朵拉的涂鸦本子)
冒泡排序的“冒泡”两字非常的形象。鱼吐出的气泡比水轻,所以它会不断上升,并在上升的过程中将比自己重的水挤到下面。而冒泡排序中,位于后面的小数字会不断地往前移动,并把比自己大的数字挤到后面去。
同样是上面的数组:
int[] arr = {5, 8, 3, 6, 1};
我们将最后一个数字与前面的数字比较,如果小于前面的数字就将其挤到后面,这样较小的数字就升到了倒数第二的位置,然后再与前面倒数第三位置上的数进行比较小数字向前升,大数字被挤到后面,这样向前比较两两相邻的位置上的数字,最后最小的数字就会上升到最前面的位置。紧接着,再从最后一个数字开始向前比较,第二小的数就到了第二个位置。以此类推,确定下来倒数第二个位置上的数字,就完成了排序。
2.代码_1
` int[] arr = {5, 8, 3, 6, 1};
for (int i = 0; i < arr.length - 1; i++) {
for (int j = arr.length - 1; j > i; j--) {
if (arr[j] < arr[j - 1]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}`
因为确定下来倒数第二个位置上的数字,就完成了排序,所以最外层循环只需要进行arr.length - 1
次。因为每次都从最后一位比较到arr[i]
,所以里面循环的条件会是上面的样子。
3.代码_2
` int[] arr = {5, 8, 3, 6, 1};
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j > arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}`
如果代码_1里面循环的条件不好理解,可以看看代码_2。既然冒泡可以理解为气泡上升,当然也可以理解为水下降。重的水在下降的过程中不断将气泡挤到前面去,大的数字也就像水一样,将小的数字挤到了前面。
我们将第一个位置上的数字,与后面的数字进行比较,大的数向后下沉,小的数向前上升,最后最大的数就沉到了最后面。然后再从第一位开始将大数沉底,就能将第二大的数沉到倒数第二的位置。以此类推,这样操作arr.length - 1
次,就完成了排序。而每次需要交换的次数是arr.length - 1 - i
次。所以里层循环只需要执行arr.length - 1 - i
次。
三、结语
这就是我对选择排序和冒泡排序的理解,希望能帮助到你。我们再不知道什么时候的未来再见吧!