五种常用排序算法
public class Sort {
public static void main(String[] args) {
int[] nums = {45,32,67,12,90,54,21,103,47,27,96};
// bubbleSort(nums);
// selectSort(nums);
// insertSort(nums);
// quickSort(nums,0,nums.length-1);
mergeSort(nums,0,nums.length-1);
for(int i=0; i<nums.length; i++){
System.out.println(nums[i]);
}
}
/**
* 冒泡排序:比较相邻的元素,将小的放到前面,(每一轮找出数组中最大的放在后面,后面排好序的数组元素不参与下轮排序)
* 时间复杂度
* @param arr
*/
public static void bubbleSort(int[] arr){
int len = arr.length;
for(int i=0; i<len-1; i++){ //外层循环控制排序趟数
for(int j=0; j<len-i-1; j++){ //内层循环进行比较、交换
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
/**
* 选择排序:将数组中每个元素与第一个元素比较,如果这个元素小于第一个元素,则交换这两个元素
* @param arr
*/
public static void selectSort(int[] arr){
int len = arr.length;
for(int i=0; i<len; i++){//循环次数
int value = arr[i];
int position = i;
for(int j=i+1;j<len;j++){//找到最小的值和位置
if(arr[j]<value){
value=arr[j];
position=j;
}
}
arr[position]=arr[i];//进行交换
arr[i]=value;
}
}
/**
* 插入排序:将数组分为两部分, 将后部分的第一个逐一与前部分每一个元素比较,在合理位置插入
* 平均来说插入排序算法复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,
* 例如,量级小于千;或者若已知输入元素大致上按照顺序排列,那么插入排序还是一个不错的选择。效率要高于选择排序和冒泡排序
* @param arr
*/
public static void insertSort(int[] arr){
int len = arr.length;
int insertNum;
for(int i=1; i<len; i++){
insertNum = arr[i]; //后半部分无序数组的第一个数
int j = i-1;//前半部分有序数组的最后一个数
while(j>=0 && arr[j]>insertNum){
arr[j+1] = arr[j];
j--;
}
arr[j+1]=insertNum;
}
}
/**
* 快速排序:先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个
* 待处理的序列的长度为1, 处理结束。
* 在平均状况下,排序n个项目要O(nlogn)次比较。在最坏状况下则需要O(n^2)次比较,但这种状况并不常见。通常明显比其他算法更快
* @param arr
*/
public static void quickSort(int[] arr, int head, int tail){
if (head >= tail || arr == null || arr.length <= 1) {
return;
}
int i = head, j = tail, pivot = arr[(head + tail) / 2];
while (i <= j) {
while (arr[i] < pivot) {
++i;
}
while (arr[j] > pivot) {
--j;
}
if (i < j) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
++i;
--j;
} else if (i == j) {
++i;
}
}
quickSort(arr, head, j);
quickSort(arr, i, tail);
}
/**
* 归并排序:从下到上将相临的子数组合并成一个大的有序数组
* 时间复杂度:O(nlogn)
* @param arr
* @param low
* @param high
*/
public static void mergeSort(int[] arr, int low,int high){
int mid = (low+high)/2;
if(low<high){
mergeSort(arr, low, mid);
mergeSort(arr, mid+1, high);
//左右归并
merge(arr, low, mid, high);
}
}
/**
* 归并方法
* @param arr
* @param low
* @param mid
* @param high
*/
public static void merge(int[] arr,int low, int mid, int high){
int[] temp = new int[high-low+1];
int i = low;
int j = mid+1;
int k=0;
//将较小的数移到新数组
while(i<=mid && j<=high){
if(arr[i]<arr[j]){
temp[k++] = arr[i++];
}else{
temp[k++] = arr[j++];
}
}
//把左边剩余的数移入新数组
while(i<=mid){
temp[k++] = arr[i++];
}
//把右边剩余的数移入新数组
while(j<=high){
temp[k++] = arr[j++];
}
//把新数组中的数覆盖nums数组
for(int x=0; x<temp.length; x++){
arr[x+low] = temp[x];
}
}
}