排序算法总结
来源:互联网 发布:手机扫描软件 - 百度 编辑:程序博客网 时间:2024/05/21 19:29
最近开始学习数据结构,看到一个博友的快速排序总结.感觉很全面并且从中学到了很多.
原地址:http://blog.csdn.net/qq_21688757/article/details/53749198
本人根据原文中的写法归纳了一遍,然后自己重新总结了一遍.
对比分析图
交换排序
-冒泡排序
冒泡排序的核心思想就是当前元素与下个元素进行比较,如果当前元素>下个元素则进行交换.直到数组有序为止.
冒泡排序对于几乎倒序的数组的时间复杂度最差,每次都要进行比较和交换.
当前冒泡排序的实现增加了如果当前趟没有产生交换直接退出循环的优化.
实现代码如下:
public class BubboSort
{
public static void sort (int [] array)
{
if (array == null || array.length == 0)
return;
//标记是否产生交换的flag
boolean flag = true ;
int n = array.length ;
for (int i = 0 ; i < n - 1 && flag; i++)
{
flag = false ;
//因为每趟循环都会把一个最大值放到最后面所以这里面可以-i
for (int j = 0 ; j < n - 1 - i ; j++)
{
if (array[j] > array[j+1])
{
Utils.swap(array,j,j+1);
flag = true ;
}
}
}
}
}
-快速排序
-快速排序的核心是找一个标志位i,然后将小于i放在i的左边,大于i的放在右边
然后在递归地分别将左右两部分进行排序
-如果标志位选取的数字在整体数组中过大或者过小,都容易导致左右两边数组
的大小不均匀从而降低效率
-所以采用一种三位取中法来获得这个索引,三位取中法顾名思义:选第一个,最后一个和中间的数
进行比较选择中间数值的索引最位标志位.
package Algorithm.SortSummary;
/**
* Created by Hammy on 2017/12/24.
*/
public class QuickSort
{
public static void sort (int [] array)
{
if (array == null || array.length == 0)
return;
quickSort(array,0,array.length - 1);
}
private static void quickSort (int [] array ,int left , int right)
{
//判断递归终止条件
if (left >= right)
return;
//获取标志位
int sign = partition(array,left,right);
quickSort(array,left,sign-1);
quickSort(array,sign+1,right);
}
private static int partition (int [] array,int left,int right)
{
//获取标志位
int sign = getMid(array,left,right);
int temp = array[sign];
while (left < right)
{
while (right > left && array[right] >= temp)
right--;
array[left] = array[right];
while (left < right && array[left] <= temp)
left++;
array[right] = array[left];
}
array[left] = temp ;
return left;
}
private static int getMid(int [] array, int left ,int right)
{
//采用三位取中法获得标志位
int mid = (left + right) >> 1 ;
if (array[left] > array[right])
Utils.swap(array,left,right);
if (array[mid] > array[right])
Utils.swap(array,mid,right);
if (array[mid] > array[left])
Utils.swap(array,left,mid);
return left ;
}
}
-选择排序
-选择排序的核心是每次循环找到最小的值然后与当前值进行交换
-堆排序
-堆是一种完全二叉树,这次排序构建的是最大堆.父节点永远大于子节点
堆排序的核心是通过headAdjust函数调整符合堆的规则,然后将根节点与最后一个节点交换
然后调整,然后在与倒数倒数第二个节点进行交换以此类推.
public class HeapSort
{
public static void sort (int [] array)
{
if (array == null || array.length == 0)
return;
int n = array.length;
//从最右的子节点开始调整
for (int i = (n - 1 - 1) >> 1; i >= 0 ; i--)
{
headAdjust(array,i,n);
}
for (int i = n - 1; i > 0 ; i--)
{
Utils.swap(array,0,i);
headAdjust(array,0,i);
}
}
private static void headAdjust (int [] array , int i , int n)
{
//与两个子节点比较然后进行插入,采用插入的规则进行交换
int temp = array[i];
for (int j = 2 * i + 1 ; j < n ; j = j * 2 + 1)
{
if (j + 1 < n && array[j+1] > array[j])
j++;
if (temp >= array[j])
break;
array[i] = array[j];
i = j ;
}
array[i] = temp ;
}
}
插入排序
-直接插入排序
public class InputSort
{
//插入排序
public static void sort (int [] array)
{
if (array == null || array.length == 0)
return;
int temp,j;
for (int i = 1 ; i < array.length ; i++)
{
temp = array[i];
for (j = i; j > 0 && array[j-1] > temp;j--)
{
array[j] = array[j-1];
}
if (array[j] != temp)
array[j] = temp ;
}
}
}
-希尔排序
public class ShellSort
{
public static void sort (int [] array)
{
if (array == null || array.length == 0)
return;
int n = array.length ;
int k ;
for (int gap = n / 2 ; gap > 0 ; gap = gap / 2 )
{
for (int i = gap ; i < n ; i++)
{
int temp = array[i];
for (k = i ; k >= gap && array[k-gap] > temp;k-=gap)
{
array[k] = array[k-gap];
}
array[k] =temp ;
}
}
}
}
-归并排序
public class MergeSort
{
public static void sort (int [] array)
{
if (array == null || array.length == 0)
return;
core(array,0,array.length - 1);
}
private static void core (int [] array,int left,int right)
{
if (left >= right)
return;
int mid = (left + right) / 2 ;
core(array,left,mid);
core(array,mid+1,right);
merge(array,left,mid,right);
}
private static void merge (int [] array , int left ,int mid ,int right)
{
int recordIndex = left ;
int copyIndex =left ;
int [] tempArray = new int[array.length];
int rightStart = mid + 1 ;
while (left <= mid && rightStart <= right)
{
if (array[left] <= array[rightStart])
tempArray[recordIndex++] = array[left++];
else
tempArray[recordIndex++] = array[rightStart++];
}
while (left <= mid)
tempArray[recordIndex++] = array[left++];
while (rightStart <= right)
tempArray[recordIndex++] = array[rightStart++];
while (copyIndex <= right)
array[copyIndex] = tempArray[copyIndex++];
}
}
阅读全文