常见排序及其改进方案
快速排序
思想:
找到一个基准,通常来说选取左边第一个元素
定义中间变量temp接收基准值
两个哨兵i,j分别从数组左端、右端进行扫描
-
(a)先从右端开始扫描:哨兵j先从右端开始扫描,确保右端元素>基准值,当发现元素<基准值则对该值进行交换(当前元素赋值给哨兵i所在位置元素),此时哨兵j停止扫描
-
(b)当哨兵j停止扫描后:哨兵i从左端开始扫描,确保左端元素<基准值,当发现元素>基准值则对该值进行交换(当前元素赋值给哨兵j所在位置元素),此时哨兵i停止扫描
此后哨兵i,j继续从当前位置向左、向右继续扫描,继续执行以上(a)(b)操作,直到哨兵i,j相遇,然后将基准值赋值给哨兵i,j所在元素的位置(基准归位),则执行完一趟扫描。以此类推,即可完成排序。
快速排序:
public static void quickSort(int[] array,int _left,int _right){
int left = _left;
int right = _right;
int temp = 0;
if(left <= right){
temp = array[left];
while (left != right){
while (left < right && array[right] >= temp){
right--;
}
array[left] = array[right];
while (left < right && array[left] <= temp){
left ++;
}
array[right] = array[left];
}
//基准归位
array[right] = temp;
quickSort(array,_left,left - 1);
quickSort(array,right + 1,_right);
}
}
示例:
public class QuickSort {
public static void main(String[] args) {
quickSort(Swap.array,0,Swap.array.length - 1);
Swap.print(Swap.array);
}
/**
* 快速排序
* 两个哨兵i,j分别从数组左端、右端进行扫描
*
* (a)先从右端开始扫描:哨兵j先从右端开始扫描,确保右端元素>基准值,当发现元素<基准值则对该值进行交换(当前元素赋值给哨兵i所在位置元素),此时哨兵j停止扫描
* (b)当哨兵j停止扫描后:哨兵i从左端开始扫描,确保左端元素<基准值,当发现元素>基准值则对该值进行交换(当前元素赋值给哨兵j所在位置元素),此时哨兵i停止扫描
*
* 此后哨兵i,j继续从当前位置向左、向右继续扫描,继续执行以上(a)(b)操作,直到哨兵i,j相遇,然后将基准值赋值给哨兵i,j所在元素的位置(基准归位),则执行完一趟扫描。以此类推,即可完成排序。
* @param array
*/
public static void quickSort(int[] array,int _left,int _right){
int left = _left;
int right = _right;
int temp = 0;
if(left <= right){
temp = array[left];
while (left != right){
while (left < right && array[right] >= temp){
right--;
}
array[left] = array[right];
while (left < right && array[left] <= temp){
left ++;
}
array[right] = array[left];
}
//基准归位
array[right] = temp;
quickSort(array,_left,left - 1);
quickSort(array,right + 1,_right);
}
}
}
工具:
public class Swap {
/**
* 数组
*/
static int[] array = {8,2,5,9,1,3,10,22,5,87,100,7,94,4};
/**
* 交换
* @param array 数组
* @param x 交换元素下标
* @param y 交换元素下标
*/
public static void swap(int[] array,int x,int y){
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
/**
* 打印数组元素 遍历
* @param array
*/
public static void print(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.print(" " + array[i]);
}
}
}
算法集合gitee项目:算法集合
目录:src/main/java/com/torlesse/leetcode/algorithm/common/QuickSort.java
选择排序以及改进
思想:比较选出最小的元素进行替换,每一次遍历最小元素归位
选择排序:
/**
* 选择排序
* 思想:每次排序选出最小值 然后进行交换
* @param array
*/
public static void selectSort(int[] array){
for (int i = 0; i < array.length - 1; i++) {
//记录最小元素位置 pos
int pos = i;
for (int j = i; j < array.length - 1; j++) {
if(array[pos] > array[j]){
pos = j;
}
}
Swap.swap(array,i,pos);
}
}
改进:
/**
* 改进
* 每一次最小 最大元素归位
* @param array
*/
public static void selectSort2(int[] array){
int len = array.length - 1;
for (int i = 0; i <= len; i++) {
//记录最小元素位置 minPos
int minPos = i;
//记录最大元素位置 maxPos
int maxPos = i;
for (int j = i; j <= len; j++) {
if(array[minPos] > array[j]){
minPos = j;
}
if(array[maxPos] < array[j]){
maxPos = j;
}
}
//最小元素归位
Swap.swap(array,i,minPos);
//最大元素归位
Swap.swap(array,len,maxPos);
len --;
}
}
示例:
public class SelectSort {
public static void main(String[] args) {
// selectSort(Swap.array);
selectSort2(Swap.array);
Swap.print(Swap.array);
}
/**
* 选择排序
* 思想:每次排序选出最小值 然后进行交换
* @param array
*/
public static void selectSort(int[] array){
for (int i = 0; i < array.length - 1; i++) {
//记录最小元素位置 pos
int pos = i;
for (int j = i; j < array.length - 1; j++) {
if(array[pos] > array[j]){
pos = j;
}
}
Swap.swap(array,i,pos);
}
}
/**
* 改进
* 每一次最小 最大元素归位
* @param array
*/
public static void selectSort2(int[] array){
int len = array.length - 1;
for (int i = 0; i <= len; i++) {
//记录最小元素位置 minPos
int minPos = i;
//记录最大元素位置 maxPos
int maxPos = i;
for (int j = i; j <= len; j++) {
if(array[minPos] > array[j]){
minPos = j;
}
if(array[maxPos] < array[j]){
maxPos = j;
}
}
//最小元素归位
Swap.swap(array,i,minPos);
//最大元素归位
Swap.swap(array,len,maxPos);
len --;
}
}
}
工具:
public class Swap {
/**
* 数组
*/
static int[] array = {8,2,5,9,1,3,10,22,5,87,100,7,94,4};
/**
* 交换
* @param array 数组
* @param x 交换元素下标
* @param y 交换元素下标
*/
public static void swap(int[] array,int x,int y){
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
/**
* 打印数组元素 遍历
* @param array
*/
public static void print(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.print(" " + array[i]);
}
}
}
算法集合gitee项目:算法集合
目录:src/main/java/com/torlesse/leetcode/algorithm/common/SelectSort.java
插入排序
思想:用后一项元素与当前项进行比较,如果后一项<当前项,交换位置,保证每一次遍历最小元素归位
插入排序:
/**
* 插入排序
* 用后一项元素与当前项进行比较,如果后一项<当前项,交换位置,保证每一次遍历最小元素归位
* 此处:从小到大排序
* @param array
*/
public static void insertSort(int[] array){
for (int i = 0; i < array.length - 1; i++) {
//后一项元素 j = i +1;
for (int j = i + 1; j > 0 ; j--) {
//后一项与当前项比较
if(array[j] < array[j - 1]){
Swap.swap(array,j,j-1);
}
}
}
}
改进:
/**
* 改进
* 第一次遍历时直接从i=1开始,默认第0项已经归位
* @param array
*/
public static void insertSort2(int[] array){
//i=1 : 默认第0项已经归位
for (int i = 1; i < array.length; i++) {
int j = 0;
int current = array[i];
// i-1 当前项的上一项,上一项与当前项比较满足: array[j] > current
for (j = i - 1; j >= 0 && array[j] > current ; j--) {
array[j + 1] = array[j];
}
array[j + 1] = current;
}
}
示例:
public class InsertSort {
public static void main(String[] args) {
// insertSort(Swap.array);
insertSort2(Swap.array);
Swap.print(Swap.array);
}
/**
* 插入排序
* 用后一项元素与当前项进行比较,如果后一项<当前项,交换位置,保证每一次遍历最小元素归位
* 此处:从小到大排序
* @param array
*/
public static void insertSort(int[] array){
for (int i = 0; i < array.length - 1; i++) {
//后一项元素 j = i +1;
for (int j = i + 1; j > 0 ; j--) {
//后一项与当前项比较
if(array[j] < array[j - 1]){
Swap.swap(array,j,j-1);
}
}
}
}
/**
* 改进
* 第一次遍历时直接从i=1开始,默认第0项已经归位
* @param array
*/
public static void insertSort2(int[] array){
//i=1 : 默认第0项已经归位
for (int i = 1; i < array.length; i++) {
int j = 0;
int current = array[i];
// i-1 当前项的上一项,上一项与当前项比较满足: array[j] > current
for (j = i - 1; j >= 0 && array[j] > current ; j--) {
array[j + 1] = array[j];
}
array[j + 1] = current;
}
}
}
工具:
public class Swap {
/**
* 数组
*/
static int[] array = {8,2,5,9,3,10,22,1,87};
/**
* 交换
* @param array 数组
* @param x 交换元素下标
* @param y 交换元素下标
*/
public static void swap(int[] array,int x,int y){
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
/**
* 打印数组元素 遍历
* @param array
*/
public static void print(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.print(" " + array[i]);
}
}
}
算法集合gitee项目:算法集合
目录:src/main/java/com/torlesse/leetcode/algorithm/common/InsertSort.java
冒泡排序
相信大学学习算法的时候都会先学习冒泡算法,时间复杂度是O(n²)
思想:遍历比较进行交换
冒泡排序
/**
* 冒泡算法
*/
public static void bubbleSort(int[] array){
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1; j++) {
//从小到大排序,最大元素先归位
if(array[j] > array[j + 1]){
Swap.swap(array,j,j+1);
}
}
}
}
改进1:
/**
* 冒泡算法改进
* @param array
*/
public static void bubbleSort2(int[] array){
for (int i = 0; i < array.length - 1; i++) {
// 改进地方, j < array.length - 1 - i 因为最大元素已经归位了
for (int j = 0; j < array.length - 1 - i; j++) {
//从小到大排序,最大元素先归位
if(array[j] > array[j + 1]){
Swap.swap(array,j,j+1);
}
}
}
}
改进2:
/**
* bubbleSort2 基础上进一步改进
* 指针的思想解决问题,上述例子是左边元素归位,现在是两头同时归位
* @param array
*/
public static void bubbleSort3(int[] array){
int left = 0;
int right = array.length - 1;
while(left < right){
//最大元素归位
for (int i = left; i < right; i++){
if(array[i] > array[i + 1]){
Swap.swap(array,i+1,i);
}
}
right --;
//最小元素归位
for (int i = right; i > left; i--) {
if(array[i] < array[i - 1]){
Swap.swap(array,i,i-1);
}
}
left ++;
}
}
示例:
public class BubbleSort {
public static void main(String[] args) {
// bubbleSort(Swap.array);
// bubbleSort2(Swap.array);
bubbleSort3(Swap.array);
Swap.print(Swap.array);
}
/**
* 冒泡算法
*/
public static void bubbleSort(int[] array){
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1; j++) {
//从小到大排序,最大元素先归位
if(array[j] > array[j + 1]){
Swap.swap(array,j,j+1);
}
}
}
}
/**
* 冒泡算法改进
* @param array
*/
public static void bubbleSort2(int[] array){
for (int i = 0; i < array.length - 1; i++) {
// 改进地方, j < array.length - 1 - i 因为最大元素已经归位了
for (int j = 0; j < array.length - 1 - i; j++) {
//从小到大排序,最大元素先归位
if(array[j] > array[j + 1]){
Swap.swap(array,j,j+1);
}
}
}
}
/**
* bubbleSort2 基础上进一步改进
* 指针的思想解决问题,上述例子是左边元素归位,现在是两头同时归位
* @param array
*/
public static void bubbleSort3(int[] array){
int left = 0;
int right = array.length - 1;
while(left < right){
//最大元素归位
for (int i = left; i < right; i++){
if(array[i] > array[i + 1]){
Swap.swap(array,i+1,i);
}
}
right --;
//最小元素归位
for (int i = right; i > left; i--) {
if(array[i] < array[i - 1]){
Swap.swap(array,i,i-1);
}
}
left ++;
}
}
}
工具:
public class Swap {
/**
* 数组
*/
static int[] array = {8,2,5,9,3,10,22,1,87};
/**
* 交换
* @param array 数组
* @param x 交换元素下标
* @param y 交换元素下标
*/
public static void swap(int[] array,int x,int y){
int temp = array[x];
array[x] = array[y];
array[y] = temp;
}
/**
* 打印数组元素 遍历
* @param array
*/
public static void print(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.print(" " + array[i]);
}
}
}
算法集合gitee项目:算法集合
目录:src/main/java/com/torlesse/leetcode/algorithm/common/BubbleSort.java