常用排序算法
目录
常用排序算法 1
1. 插入排序 1
2. 希尔排序 2
3. 冒泡排序 3
4. 快速排序 4
5. 选择排序 5
6. 归并排序 6
1. 插入排序
public class InsertSort {
/**
* @Title: insertSort
* @Description: 直接插入算法
* @param a void
* @author Young
* @date 2018年5月14日上午9:45:20
*/
public void insertSort(int [] a){
int len = a.length;
for(int i = 1;i < len; i++){//注意循环从第二个数开始
int temp = a[i];//用temp存储要插入的数
int j= i-1;//第二层循环从未排序的位置开始,即从第一层前一个数
while(j>=0&&temp<a[j]){//从后往前比较,将大于插入数的数向后移动
a[j+1] = a[j];//后移
j--;//循环条件变化
}
a[j+1] = temp;//插入
}
}
public static void main(String[] args) {
InsertSort is = new InsertSort();
int [] a = {13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10};
is.insertSort(a);
for(int e : a){
System.out.print(e+" ");
}
}
}
2. 希尔排序
public class ShellSort {
/**
* @Title: shellSort
* @Description: 希尔排序实现 /递减增量排序
*
* 希尔排序的排序效率和选择步长序列有直接关系,相关步长序列如下,目前最好的序列是 4、塞奇威克(Sedgewick) 的步长序列
*
* 1、希尔(Shell)原始步长序列:N / 2,N / 4,...,1(重复除以2);
* 2、希伯德(Hibbard)的步长序列:1,3,7,...,2 k - 1;
* 3、克努特(Knuth)的步长序列:1,4,13,...,(3 k - 1)/ 2;
* 4、塞奇威克(Sedgewick) 的步长序列:1,5,19,41,109,....
* 它是通过交织两个序列的元素获得的: 步长序列数组下标 n 从0开始
* n偶数用 :1,19,109,505,2161,...,9(4 k - 2 k)+ 1,k = 0,1,2,3,...
* n奇数用 :5,41,209,929,3905,...。k + 2(2 k + 2 - 3)+ 1,k = 0,1,2,3,...
*
* @param a void
* @author Young
* @date 2018年5月14日上午10:55:02
*/
public void shellSort(int [] a){
//此处选取步长序列为原始步长序列即n/2
int len = a.length;//获取数组长度
while(len != 0){
len = len/2;
for(int i = 0;i < len;i++){//分组,分组后的长度为len
for(int j = i+len;j< a.length;j+=len){//从第二个开始,每次递增len个单位,总长度依旧为未分组的长度
//下面是做插入排序,但是时刻要注意分组为len
int k = j-len;
int temp = a[j];//要插入的元素
while(k>=0&&a[k]>temp){//k的条件必须包含等于零,否则可能出现第一个元素漏排的情况
a[k+len] = a[k];//大于插入的数 则向右移动
k -= len;
}
a[k+len] = temp;//插入
}
}
}
}
public static void main(String[] args) {
ShellSort ss = new ShellSort();
int [] a = { 13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10};
ss.shellSort(a);
for(int e : a){
System.out.print(e+" ");
}
}
}
3. 冒泡排序
public class BubbleSort {
/**
* @Title: bubbleSort
* @Description: 冒泡排序实现
* @param a void
* @author Young
* @date 2018年5月14日下午6:00:08
*/
public void bubbleSort(int [] a ){
int len = a.length;
for(int i = 0; i<len;i++){
for(int j = 0;j <len-i-1;j++){//注意循环条件
if(a[j]>a[j+1]){
int m = a[j];
a[j] = a[j+1];
a[j+1] = m;
}
}
}
}
public static void main(String[] args) {
BubbleSort bs = new BubbleSort();
int [] a = { 13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10};
bs.bubbleSort(a);
for(int e : a){
System.out.print(e+" ");
}
}
}
4. 快速排序
public class QuickSort {
/**
* @Title: quickSort
* @Description: 递归实现快速排序
* @param a
* @param _left
* @param _right void
* @author Young
* @date 2018年5月15日上午9:39:34
*/
public void quickSort(int[] a,int _left,int _right){
int left = _left;
int right = _right;
int temp = 0;//存放基准值
if(left<=right){
temp = a[left];//选取left作为基准值
while(left!=right){//结束条件
while(right>left && a[right]>=temp){//从右往左找到第一个比基准值小的元素
right--;
}
a[left] = a[right];//将这个较小的元素与left元素交换位置
while(left<right && a[left]<=temp){//从左往右找到第一个比基准值大的元素
left++;
}
a[right] = a[left];//将这个较大的元素与right元素交换位置
}
a[right] = temp;//将基准值插入left与right相交的位置
quickSort(a, _left, left-1);//对基准值左边的元素继续进行快速排序
quickSort(a, right+1, _right);//对基准值右边的元素继续进行快速排序
}
}
public static void main(String[] args) {
QuickSort qs = new QuickSort();
int [] a = { 13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10};
qs.quickSort(a,0,a.length-1);
// for(int i = 0 ; i< a.length; i++){
// System.out.print(a[i]+" ");
// }
for(int e : a){
System.out.print(e+" ");
}
}
}
5. 选择排序
public class SelectSort {
public void selectSort(int [] a){
int len = a.length;
for(int i=0;i<len;i++){
int min = a[i];
int position = i;
for(int j = i+1;j<len;j++){
if(a[j]<min){
min = a[j];
position = j;
}
}
//int minNow = a[position];
a[position] = a[i];//将现在的最小值放到之前的最小值元素位置上
a[i] = min;//将原来最小值元素放到现在最小值位置上,以进行交换
}
}
public static void main(String[] args) {
SelectSort ss = new SelectSort();
int [] a = {13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10};
ss.selectSort(a);
for(int e : a){
System.out.print(e+" ");
}
}
}
6. 归并排序
public class MergerSort {
/**
* @Title: mergerSort
* @Description: 递归分解数列,最后合并数列
* @param a
* @param temp
* @param first
* @param last void
* @author Young
* @date 2018年5月15日下午4:19:19
*/
public void mergerSort(int []a,int []temp,int first,int last){
if(first<last){
int mid = (first+last)/2;
mergerSort(a,temp,first,mid);//左边有序
mergerSort(a,temp,mid+1,last);//右边有序
mergerArray(a, temp, first, mid, last);//再将二个有序数列合并
}
}
/**
* @Title: mergerArray
* @Description: 将有二个有序数列a[first...mid]和a[mid...last]合并。
* @param a
* @param temp
* @param first
* @param mid
* @param last void
* @author Young
* @date 2018年5月15日下午4:13:02
*/
public void mergerArray(int []a,int []temp,int first,int mid,int last){
//第一个数组a[first,mid+1]
int f = first;
int m1 = mid+1;
//第二个数组a[mid,last]
int l = last;
int m = mid;
//临时数组temp[k]
int k = 0;
while(f <= m && m1 <= l){
if(a[f]<a[m1])
temp[k++] = a[f++];
else
temp[k++] = a[m1++];
}
while(f <= m)
temp[k++] = a[f++];
while(m1 <= l)
temp[k++] = a[m1++];
for(int i = 0;i<k;i++){
a[first + i] = temp[i];
}
}
public static void main(String[] args) {
MergerSort ss = new MergerSort();
int [] a = {13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10};
int[] temp = new int[a.length];//初始化一个临时数组
ss.mergerSort(a, temp, 0, a.length-1);
for(int e : a){
System.out.print(e+" ");
}
}
}