简单排序
直接选择排序
示例数据:25 , 89 , 72 , 15 , 32 , 10 , 8 , 64
先中找到最小数(或最大数),即8将与数据第一位交换形成一个新的顺序数据 8,89,72,15,32,10,25,64,这时数据8已经是排好的数据了,不在下一趟选择最小数据的范围内,下一趟从89,72,15,32,10,25,64中选择最小数据,如此循环,顺序变换如下:
[ 25 , 89 , 72 , 15 , 32 , 10 , 8 , 64 ]
8 , [ 89 , 72 , 15 , 32 , 10 , 25 , 64 ]
8 , 10 , [ 72 , 15 , 32 , 89 , 25 , 64 ]
8 , 10 , 15 , [ 72 , 32 , 89 , 25 , 64 ]
8 , 10 , 15 , 25 , [ 32 , 89 , 72 , 64 ]
8 , 10 , 15 , 25 , 32 , [ 89 , 72 , 64 ]
8 , 10 , 15 , 25 , 32 , 64 , [ 72 , 89 ]
8 , 10 , 15 , 25 , 32 , 64 , 72 , [ 89 ]
代码示例:
/**
* 简单选择排序
*
* @param arr
*/
public static void selectSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int min = i;//每一趟循环比较时,min用于存放较小元素的数组下标,这样当前批次比较完毕最终存放的就是此趟内最小的元素的下标,避免每次遇到较小元素都要进行交换。
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
//进行交换,如果min发生变化,则进行交换
if (min != i) {
swap(arr,min,i);
}
}
}
public void swap(int arr[],int min,int i){
int tmp = arr[min];
arr[min] = arr[i];
arr[i] = tmp;
}
冒泡排序
算法分析:
- 平均时间复杂度:o(N^2),嵌套双循环
- 最好时间复杂度:o(N),若已经有序,那么第一趟就排好了
- 最坏时间复杂度:o(N^2)
- 空间复杂度:o(1)
- 稳定性:稳定的
冒泡排序的基本思想是,对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序
代码示例:
/**
* 冒泡排序
*
* @param arr
*/
public static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
boolean flag = true;//设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已然完成。
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr,j,j+1);
flag = false;
}
}
if (flag) {
break;
}
}
}
直接插入排序
直接插入排序基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。
代码示例:
/**
* 插入排序
*
* @param arr
*/
public static void insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int j = i;
while (j > 0 && arr[j] < arr[j - 1]) {
swap(arr,j,j-1);
j--;
}
}
}
快速排序法
用数组的第一个数作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序,这样一趟过后数据变成大、小两个区间,在再分别对两个区间进行快速排序。值得注意的是,快速排序是不稳定的排序算法,也就是说多个相同的值的相对位置也许会在算法结束时产生变动。
public class FastSort {
private boolean direction = true;
public FastSort(int[] arr) {
sort(arr,0,arr.length-1);
}
public void sort(int[] arr,int low,int high){
int start = low;
int end = high;
while(start < end){
if(arr[start] > arr[end]){
change(arr,start,end);
direction = !direction;
}
if(direction){
end--;
}else{
start++;
}
}
//递归,注意要减去已经排好的位置,否则StackOverflowError(栈溢出错误)
if(low < start){
sort(arr,low,start-1); //start - 1
}
if(end < high){
sort(arr,end+1,high); //end + 1
}
}
public void change(int[] arr,int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}