排序算法

Posted gshao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排序算法相关的知识,希望对你有一定的参考价值。

参考:https://blog.csdn.net/weixin_40205234/article/details/86699088

https://blog.csdn.net/adusts/article/details/80882649

从执行效率:冒泡排序<选择排序<插入排序<快速排序。

从稳点性: 快速排序,选择排序 不稳定;   冒泡排序,插入排序 稳定。

1. 冒泡排序

以升序为例,两个相邻的数比较大小,如果前面的数比后面的数大,那么交换位置。双重for循环,外层循环控制轮数,内层循环控制每轮比较的次数,每轮比较会将该轮最大数交换到最后面。

代码:

public class BubbleSort {
	public static void main(String[] args) {
		 int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
		 BubbleSort(arr);
		 System.out.println(Arrays.toString(arr));
	}
	public static void BubbleSort(int []arr) {
		//外层循环控制轮数
		for(int i=1;i<=arr.length-1;i++) {
			//内层循环控制每轮比较的次数
			for(int j=1;j<=arr.length-i;j++) {
				if(arr[j-1]>arr[j]) {
					//借助中间变量交换两个位置上的值
					int temp = arr[j-1];
					arr[j-1]= arr[j];
					arr[j]=temp;
				}
			}
		}	
	}
}

  动态演示:

技术图片

 

2. 选择排序

以升序为例,在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 

代码:

public class SelectionSort {
	private void mian() {
		int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
		SelectionSort(arr);
		 System.out.println(Arrays.toString(arr));
	}

	private void SelectionSort(int[] arr) {
		for(int i =0;i<arr.length-1;i++) {
			int minIndex = i;
			for(int j=i;j<arr.length-1;j++) {
				if(arr[minIndex]>arr[j]) {
					minIndex = j; //记下目前找到的最小值所在的位置
				}
			}
			//在内层循环结束,也就是找到本轮循环的最小的数以后,再进行交换
			if (minIndex != i){
				int temp = arr[i];
				arr[i] = arr[minIndex];
				arr[minIndex] = temp;
			}
		}
	}
}

  

动态演示;

技术图片

 

 

3. 插入排序

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤2~5。

代码:

public class InsertSort {
	public static void main(String[] args) {
		int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
		insertionSort(arr);
		 System.out.println(Arrays.toString(arr));
	}
	private static void insertionSort(int []arr){
	    for(int i=1; i<arr.length; i++){
	        int preIndex = i-1;
	        int current = arr[i];
	        while(preIndex>=0 && arr[preIndex]>current){
	            arr[preIndex+1]=arr[preIndex];
	            preIndex--;
	        }
	        arr[preIndex+1]=current;
	    }
	}
}

  

动态演示:

技术图片

 

4. 快速排序:

 

步骤为:

  1. 从数列中挑出一个元素,称为"基准"(pivot),
  2. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

代码:

public class QuickSort {
	public static void main(String[] args) {
		int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
		quickSort(arr,0,arr.length-1);
		System.out.println(Arrays.toString(arr));
	}
	private static void quickSort(int[] arr, int low, int high) {

        if (low < high) {
            // 找寻基准数据的正确索引
            int index = getIndex(arr, low, high);

            // 进行迭代对index之前和之后的数组进行相同的操作使整个数组变成有序
            quickSort(arr, 0, index - 1);
            quickSort(arr, index + 1, high);
        }

    }

    private static int getIndex(int[] arr, int low, int high) {
        // 基准数据
        int tmp = arr[low];
        while (low < high) {
            // 当队尾的元素大于等于基准数据时,向前挪动high指针
            while (low < high && arr[high] >= tmp) {
                high--;
            }
            // 如果队尾元素小于tmp了,需要将其赋值给low
            arr[low] = arr[high];
            // 当队首元素小于等于tmp时,向前挪动low指针
            while (low < high && arr[low] <= tmp) {
                low++;
            }
            // 当队首元素大于tmp时,需要将其赋值给high
            arr[high] = arr[low];

        }
        // 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
        // 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low]
        arr[low] = tmp;
        return low; // 返回tmp的正确位置
    }

}

  

 

动态演示:

技术图片

技术图片

借用下啊哈算法的图:

技术图片

i和j分别为左哨兵和右哨兵,这里枢纽元定为6,然后分别从左往右(i++)和右往左(j--)开始遍历

左哨兵查找比6大的元素,右哨兵查找比6小的元素

第一次交换结果

技术图片

技术图片

 

第二次交换结果

技术图片

技术图片

 

技术图片

相遇后直接与枢纽元交换

技术图片

技术图片

然后再递归排序就行

技术图片

技术图片

 

 

技术图片

以上是关于排序算法的主要内容,如果未能解决你的问题,请参考以下文章

算法排序之堆排序

快速排序-递归实现

从搜索文档中查找最小片段的算法?

在第6731次释放指针后双重免费或损坏

TimSort算法分析

以下代码片段的算法复杂度