排序算法思想与理解笔记
1:快排思想:
通过基准数一趟排序将要排序的数据分割成独立的两个部分,以基准数为分割线,左部分都是小于基准数,右部分都是大于基准数,然后再按照前面思路对两部分数据进行快速排序,整个过程可以递归进行,以此达到整个数据变成有序序列。
代码实现:
public static void main(String[] args) {
int[] arr = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
quickSort(arr, 0, arr.length - 1);
for (int i : arr) {
System.out.println(i);
}
}
public static void quickSort(int[] arr, int low, int high) {
if (low >= high) {
return;
}
int i = low;
int j = high;
int index = arr[i];
while (i < j) {
while (i < j && arr[j] >= index) {
j--;
}
if (i < j) {
arr[i++] = arr[j];
}
while (i < j && arr[i] <= index) {
i++;
}
if (i < j) {
arr[j--] = arr[i];
}
}
arr[i] = index;
quickSort(arr, low, i - 1);
quickSort(arr, i+1, high);
}
代码举例说明:
1.假设待排序数组{6, 1, 2, 7, 9, 3, 4, 5, 10, 8}
2.首先每次都选出数组0索引下的元素作为准基数 即 num=6 , i 左端哨兵,j 右端哨兵
3.目的:快排的思想就是将数组以num为分割线,分成两个部分,左部分小于num,右部分大于num
4.始于数据右端( j )开始于num做比较,如果大于不管将 j - -,如果小于num,即需要将该(j)位置元素移动到(i)的位置上。此处有个占坑机制,原本(i)位置是准基数,已记录,所以可以直接替换,此时(j)索引下的元素为占位元素,然后再从数组左端开始比较,直到有大于准基数的数字后,在进行元素移动,如下图就是数组以6为准基数分成两部分的走势。
红色:表示占位元素,橙色:表示该轮与Num比较的元素 绿色:表示进行替换元素
最后将红色3换成6即得到的数组变为 {5,1,2,4,3,6,9,7,10,8}
至此达到了目的,左边都是小于6,右边都是大于6的一个数组,
同理将数组{5,1,2,4,3}和{9,7,10,8}当成两个数组做递归即可。
2:插入排序
插入排序思想 :直接插入排序。对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动
举例说明: 数组{5,6,4,2}
取6与5比较大于忽略 i++ 得到{5,6}有序序列
取4与6比较,小于,进入内循环 4与5比较小于即替换位置{4,6,5,2},取5与6比较小于替换位置{4,5,6,2}
取2余6比较,同理上最后得到{2,4,5,6}
代码实现:
private static void insertSort(int[] arr) {
int index, indexVal;
for (int i = 1; i < arr.length; i++) {
//比较基数
indexVal = arr[i];
//基数下标
index = i;
while (index > 0 && arr[index - 1] > indexVal) {
//如果前序元素元素>当前比较基数,则将前序元素后移。
arr[index] = arr[index - 1];
index--;
}
//替换基数元素。
arr[index] = indexVal;
}
}
3:希尔排序
1:算法思想:希尔排序算法是插入排序算法的一种更高效的改进版本,希尔排序是非稳定排序算法,希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
该算法正常情况下会比直接排序算法要快,但是某种条件下可能会导致性能过慢如:
{5,2,6,3} 如果这样的数组按照希尔排序,前面的分组置换操作属于无用。前后的元素并没有实际上的移动,
后面依旧插入排序。所以该中环境下会比插入排序多出无用的步骤。
正常情况下如下图,将原数组除以2后大于1后进行下面操作。
进行希尔前置排序后,在进行插入排序时,元素移动的步数是明显小于直接插入排序的。
2:代码实现:
public static void shellSort(int[] arr) {
int shell = arr.length / 2;
int j, temp;
while (shell > 0) {
for (int i = shell; i < arr.length; i++) {
temp = arr[i];
j = i - shell;
while (j >= 0&& temp < arr[j]) {
if (temp < arr[j]) {
arr[j + shell] = arr[j];
}
j = j - shell;
}
arr[j + shell] = temp;
}
shell = shell / 2;
}
}