您的位置:首页 > 编程语言 > Java开发

Java排序算法实现及优劣分析

2017-06-07 17:32 573 查看
1.冒泡排序

/**
* 算法思想:
* 冒泡排序:重复的走访要排序的数列,每次比较两个元素,如果顺序错误就交换过来
* 走访的数列的工作重复直到没有可以交换的元素停下来
* 算法因为较小的元素会慢慢"浮"到顶端而得名
*
* @author LRD
*
*/
public class BubbleSort {

/**
*按从小到大排列,算法操作如下:
*比较相邻的两个元素,如果第一个大于第二个,交换位置
*对每一对相邻的元素作相同的工作,从第一队到最后一对,这样最后一个就是最大的元素了
*针对除了最后一个元素之外剩下的元素,继续进行如上操作
*持续对剩下的越来越少的元素重复如上操作
*
* 算法优劣分析:
*  时间复杂度分析:
*     最好情况O(n),平均情况O(n的平方),最差情况O(n的平方)
*  空间复杂度分析:
*      辅助存储:O(1)
*  稳定性:
*      稳定
*
* @param nums 待排序数组
*/
public void bubbleSort(int[] nums){

int temp=0;
int size = nums.length;

for(int i=0;i<size;i++)
{
for(int j=0;j<size-(i+1);j++)
{
if(nums[j] > nums[j+1])
{
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}

}

public static void main(String[] args)
{
BubbleSort bs = new BubbleSort();
int[] array = {12,45,31,34,97,46,67};
bs.bubbleSort(array);
System.out.println("Bubble Sort result is:");
for(int i=0;i<array.length;i++)
{
System.out.print(array[i]+" ");
}
}
}

运行结果:
Bubble Sort result is:
12 31 34 45 46 67 97


2.快速排序:

/**
* 算法思想:
* 通过一趟排序将待排序的数列分割为独立的两部分,其中一部分记录的关键字均比另外一部分的小,
* 然后分别对两个部分继续进行快速排序,直到整个序列有序
*
* @author LRD
*
*/
public class QuickSort {

/**
* 按照从小到大排序,算法实现:
* 首先将数组中的第0号位置的元素设置为中轴,与数组中末尾的元素比较,
* 如果大于,则交换,如果小于,就不换,继续与倒数第二个比较,如果大于则交换
* 交换以后,与比他小的那端,刚刚交换之后的后一个进行再进行比较,如此往复,
* 一趟排序完成之后,左边就是小于中轴的,右边就是大于中轴的,
* 然后再用分治法对左右两个数组进行排序
*
*算法优劣分析:
* 时间复杂度
*  最好情况:O(n*log n)   最坏情况:O(n的平方)  平均情况:O(n*log n)
* 空间复杂度
*  O(n*log n)
* 稳定性
*  不稳定
*
* 在初始序列按照关键码有序或者基本有序时,蜕化为冒泡排序
*/

/**
* 首先获取中轴位置
*
* @param nums  待排序数组
* @param low   数组左边起始位
* @param high  数组右边末尾
* @return      中轴位置
*/
public int getMiddle(int[] nums,int low,int high)
{
int temp = nums[low];
while(low < high)
{
while(low < high && nums[high] > temp)
{
high--;
}
nums[low] = nums[high]; //大于中轴的移到左边

while(low < high && nums[low] < temp)
{
low++;
}
nums[high] = nums[low];//小于中轴的移到右边
}
nums[low] = temp;
return low;
}

public void quickSort(int[] nums,int low,int high)
{
if(low < high)
{
int middle = getMiddle(nums,low,high);  //将待排序数组一分为二
quickSort(nums,low,middle-1);  //对左边数组进行递归排序
quickSort(nums,middle+1,high); //对右边数组进行递归排序
}
}

public static void main(String[] args)
{
int[] array = {12,45,31,34,97,46,67};
QuickSort qs = new QuickSort();

if(array.length-1 > 0)
qs.quickSort(array, 0, array.length-1);

System.out.println("Quick Sort result is:");
for(int i=0;i<array.length;i++)
{
System.out.print(" "+array[i]);
}
}
}

运行结果:
Quick Sort result is:
12 31 34 45 46 67 97


3.选择排序

/**
* 算法思想:
* 选择待排序数组中最小的一个,然后和第一个位置的元素交换,
* 然后在剩下的数组元素中选择最小的,与第二个交换,一直循环到最后一个位置
*
*
* 算法优劣分析:
*  时间复杂度:
*      最好情况:O(n的平方) 最坏情况:O(n的平方) 平均情况:O(n的平方)
*  空间复杂度:
*      O(1)
*  稳定性:
*      不稳定
*
* @author LRD
*
*/
public class SelectSort {

/**
*
* 按照从小到大排列
* @param nums

edd2
*/
public void selectSort(int[] nums)
{
int size = nums.length;

int temp=0;
for(int j=0;j<size;j++)
{
int smallest = j;
for(int i = j+1;i < size;i++)
{
if(nums[smallest] > nums[i])
smallest = i;
}

if(smallest != j)
{
temp = nums[smallest];
nums[smallest] = nums[j];
nums[j] = temp;
}

}

}

public static void main(String[] args)
{
int[] array = {12,45,31,34,97,46,67};
SelectSort ss = new SelectSort();
ss.selectSort(array);
System.out.println("Selkect Sort result is:");
for(int i=0;i<array.length;i++)
{
System.out.print(array[i]+" ");
}
}

}

运行结果:
Selkect Sort result is:
12 31 34 45 46 67 97


4.插入排序

/**
* 算法思想:
* 每步将一个待排序的记录,按照其顺序码的大小插入到前面已排好序的字序列的合适位置
* 从后向前寻找到合适的位置,直到全部的插入排序完成
*
*
*
* @author LRD
*
*/
public class InsertSort {

/**
* 算法实现:
* 从第一个元素开始,将第一个元素视为已经排序好了
* 取出下一个元素,在已经排序的元素序列中从后向前扫描
* 如果该元素(已排序)大于新元素,将该元素向后移一位
* 重复以上步骤,直到找到小于等于新元素的已排序的元素
* 将新元素插入到该位置中
* 然后重复以上步骤
*
* 算法优劣分析:
*  时间复杂度:
*      最好情况:O(n)   最差情况:O(n的平方)    平均情况:O(n的平方)
*  空间复杂度:
*      辅助存储:O(1)
*  稳定性:
*      稳定
*
* @param nums
*/
public void insertSort(int[] nums)
{
int temp = 0;
int j=0;
for(int i=0;i<nums.length;i++)
{
temp = nums[i];

for(j=i;j > 0 && temp < nums[j-1];j--)
{
nums[j] = nums[j-1];
}
nums[j] = temp;

}
}

public static void main(String[] args)
{
int[] array = {12,45,31,34,97,46,67};
InsertSort is = new InsertSort();
is.insertSort(array);
System.out.println("Insert Sort result is:");
for(int i=0;i<array.length;i++)
{
System.out.print(array[i]+" ");
}

}

}

运行结果:
Insert Sort result is:
12 31 34 45 46 67 97


5.希尔排序

/**
* 算法思想:
* 先将整个待排序的记录序列分割为若干个子序列
* 对这些子序列分别进行插入排序
* 待整个序列基本有序时,再对全体记录进行一次插入排序
*
* 算法优劣分析:
*  时间复杂度:
*      最好情况:   O(n)    最坏情况:O(n的平方)        平均情况:O(n的1.5次方)
*  空间复杂度:
*      辅助存储:O(1)
*  稳定性:
*      不稳定
* @author LRD
*
*/
public class ShellSort {

public static void shellSort(int[] nums)
{
int temp=0;
int j=0;
for(int increment = nums.length/2;increment > 0;increment /= 2)
{
for(int i=increment;i < nums.length;i++)
{
temp = nums[i];
for(j=i;j>=increment;j -= increment)
{
if(temp < nums[j-increment])
nums[j] = nums[j-increment];
else
break;
}
nums[j] = temp;
}
}
}

public static void main(String[] args)
{
int[] array = {12,45,31,34,97,46,67};

ShellSort.shellSort(array);

System.out.println("Shell Sort result is:");
for(int i=0;i<array.length;i++)
System.out.print(array[i]+" ");
}

}
运行结果:
Shell Sort result is:
12 31 34 45 46 67 97


6.归并排序

/**
*
* 算法思想:
* 归并的意思就是把两个(或两个以上)的有序表合并成一个新的有序表
* 即把待排序序列分为若干个子序列,每个子序列都是有序的。
* 然后再把有序子序列合并为整体有序序列
*
*
* 算法优劣:
*  时间复杂度:
*      最好情况:O(n*log n)         最差情况:O(n*log n)         平均情况:O(n*log n)
*  空间复杂度:
*      辅助存储:O(1)
*  稳定性:
*      稳定
* @author LRD
*
*/
public class MergeSort {

public static int[] sort(int[] nums,int low,int high)
{
int middle = (low+high)/2;
if(low < high)
{
sort(nums,low,middle);
sort(nums,middle+1,high);
merge(nums,low,middle,high);
}
return nums;
}

/**
*
*
* @param nums 待排序数组
* @param low 子序列开始位置
* @param middle 子序列中间位置
* @param high 子序列末尾位置
*/
public static void merge(int[] nums,int low,int middle,int high)
{
int[] temp = new int[high-low+1];

int i=low;
int j=middle+1;
int k=0;

//将左右两个子序列比较大小后分别存入 局部变量数组内
while(i <= middle && j <= high)
{
if(nums[i] < nums[j])
temp[k++] = nums[i++];
else
temp[k++] = nums[j++];
}

//将左子序列剩余的元素写入数组
while(i <= middle)
{
temp[k++] = nums[i++];
}

//将右子序列剩余的元素写入数组
while(j <= high)
{
temp[k++] = nums[j++];
}

//将局部变量数组内容写入返回变量数组里面
for(int k2=0;k2 < temp.length;k2++)
{
nums[k2+low] = temp[k2];
}

}

public static void main(String[] args)
{
int[] array = {12,45,31,34,97,46,67};
int[] array1 = new int[array.length-1];
array1 = sort(array,0,(array.length-1));

System.out.println("Merge Sort result is:");
for(int i=0;i<array1.length;i++)
{
System.out.print(array1[i]+" ");
}
}

}


7.堆排序算法

/**
*
* 知识补充:
* **堆排序是一种树形选择排序,对直接选择排序的有效优化。
* **堆的定义如下:具有n个元素的序列(h1,h2,h3...,hn),当且仅当满足
* **(hi >= h2i,hi >= h2i+1)或(hi <= h2i,hi <= h2i+1)时称之为堆(前者叫大顶堆后者叫小顶堆)。
* **完全二叉树可以很直观的表示堆的结构。堆顶为根,其他为左子树和右子树
*
* 算法思想:
* 初始时把待排序的数的序列看作是一颗顺序存储的二叉树,从最后一个节点的父节点开始调整排序,
* 如果子节点大于父节点,则交换,以此类推,调整完成后使之成为一个符合要求的大顶堆。此时根节点为最大值,将它存起来
* 然后
*
*
*
* @author LRD
*
*/
public class HeapSort {

public static void main(String[] args)
{
int[] array = {12,45,31,34,97,46,67};
for(int i=0;i<array.length-1;i++)
{
//建堆
buildMaxHeap(array,(array.length-1-i));

//交换堆顶和最后一个元素
swap(array,0,array.length-1-i);
System.out.println(Arrays.toString(array));

}

}

public static void buildMaxHeap(int[] data,int lastIndex)
{
//从lastIndex节点的父节点开始
for(int i = (lastIndex-1)/2;i >= 0;i--)
{
int k = i;

//如果当前节点k的左子节点存在
while(k*2+1 <= lastIndex)
{
//获取到当前节点k的左子节点
int biggerIndex = k*2 + 1;

if(biggerIndex < lastIndex)
{
//如果左子节点得值小于右子节点,那么biggerIndex就赋值为右子节点
if(data[biggerIndex] < data[biggerIndex+1])
biggerIndex++;

}

//如果较大的子节点大于父节点,那么就交换位置
if(data[biggerIndex] > data[k])
{

//调用交换函数
swap(data,k,biggerIndex);

//值移到子节点
k = biggerIndex;
}
else
break;
}
}
}

public static void swap(int[] data,int son,int father)
{
int temp = data[son];
data[son] = data[father];
data[father] = temp;
}

}

运行结果:
[31, 45, 67, 34, 12, 46, 97]
[31, 45, 46, 34, 12, 67, 97]
[12, 45, 31, 34, 46, 67, 97]
[12, 34, 31, 45, 46, 67, 97]
[31, 12, 34, 45, 46, 67, 97]
[12, 31, 34, 45, 46, 67, 97]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息