排序算法
冒泡排序
冒泡排序
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
public class Sort {
/**
* @param numbers 需要排序的整型数组
*/
public static void bubbleSort(int[] numbers)
{
int size = numbers.length;
for(int i = 0 ; i < size-1; i ++) {
for(int j = 0 ;j < size-1 ; j++) {
if(numbers[j] > numbers[j+1]){ /*交换两数位置*/
int temp = numbers[j];
numbers[j] = numbers[j+1];
numbers[j+1] = temp;
}
}
}
}
public static void main(String[] args) {
int[] a = {10, 99, 20, 15, 0, 55, 6, 7, 2, 1, -5};
bubbleSort(a);
System.out.println(Arrays.toString(a));
}
}
插入排序
public class StraightInsertionSorting {
public static void insertSort(int [] a){
int len=a.length;//单独把数组长度拿出来,提高效率
int insertNum;//要插入的数
for(int i=1;i<len;i++){//因为第一次不用,所以从1开始
insertNum=a[i];
int j=i-1;//序列元素个数
while(j>=0&&a[j]>insertNum){//从后往前循环,将大于insertNum的数向后移动
a[j+1]=a[j];//元素向后移动
j--;
}
a[j+1]=insertNum;//找到位置,插入当前元素
}
}
public static void main(String[] args) {
int[] a = {2, 1, 7, 5, 8, 4, 0};
insertSort(a);
System.out.println(Arrays.toString(a));
}
}
快速排序
快速排序的基本思想就是从一个数组中任意挑选一个元素(通常来说会选择最左边的元素)作为中轴元素,将剩下的元素以中轴元素作为比较的标准,将小于等于中轴元素的放到中轴元素的左边,将大于中轴元素的放到中轴元素的右边,然后以当前中轴元素的位置为界,将左半部分子数组和右半部分子数组看成两个新的数组,重复上述操作,直到子数组的元素个数小于等于1(因为一个元素的数组必定是有序的)。
public class FastSort {
public static void main(String[] args) {
int[] a = {3, 2, 5, 9, 8, 1, 0, 4, 7, 6};
int start = 0;
int end = a.length - 1;
sort(a, start, end);
System.out.println(Arrays.toString(a));
}
public static void sort(int[] a, int low, int high) {
int start = low;
int end = high;
int key = a[low];
while (end > start) {
//从后往前比较
while (end > start && a[end] >= key) //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
end--;
if (a[end] <= key) {
int temp = a[end];
a[end] = a[start];
a[start] = temp;
}
//从前往后比较
while (end > start && a[start] <= key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
start++;
if (a[start] >= key) {
int temp = a[start];
a[start] = a[end];
a[end] = temp;
}
//此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用
}
//递归
if (start > low) sort(a, low, start - 1);//左边序列。第一个索引位置到关键值索引-1
if (end < high) sort(a, end + 1, high);//右边序列。从关键值索引+1到最后一个
}
}
归并排序
/**
* 归并排序
* @author stopper
* @create 2019-10-29
*/
public class MergeSort {
public static void main(String[] args) {
int[] a = {3, 2, 5, 9, 8, 1, 0, 4, 7, 6};
int start = 0;
int end = a.length - 1;
mergeSort(a, start, end);
System.out.println(Arrays.toString(a));
}
//两路归并算法,两个排好序的子序列合并为一个子序列
private static void merge(int []a,int left,int mid,int right){
int []tmp=new int[a.length];//辅助数组
int p1=left,p2=mid+1,k=left;//p1、p2是检测指针,k是存放指针
while(p1<=mid && p2<=right){
if(a[p1]<=a[p2])
tmp[k++]=a[p1++];
else
tmp[k++]=a[p2++];
}
while(p1<=mid) tmp[k++]=a[p1++];//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中
while(p2<=right) tmp[k++]=a[p2++];//同上
//复制回原素组
for (int i = left; i <=right; i++)
a[i]=tmp[i];
}
private static void mergeSort(int [] a,int start,int end){
if(start<end){//当子序列中只有一个元素时结束递归
int mid=(start+end)/2;//划分子序列
System.out.println("start : " + start + ", mid : " + mid + " , end : " + end);
mergeSort(a, start, mid);//对左侧子序列进行递归排序
mergeSort(a, mid+1, end);//对右侧子序列进行递归排序
merge(a, start, mid, end);//合并
}
}
}