简单选择排序:
每一趟从待排序的数据元素中选出最小(最大)的元素,顺序放在待排序的数列最前,直到全部待排序的数据元素全部排完。
最差时间复杂度:O(n^2),最优时间复杂度:O(n^2),平均时间复杂度:O(n^2),所需辅助空间:O(1)。
package com.algorithm.sort;
import java.util.Scanner;
/**
* 简单选择排序
*/
public class SelectSort {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int[] a=new int[n];
int i=0;
while (i<n){
a[i++]=scanner.nextInt();
}
selectSort(a);
}
public static void selectSort(int[] array){
int[] newArray=new int[array.length];
int min;
for(int i=0;i<array.length;i++){
min=array[i];
int temp;
for (int j=i+1;j<array.length;j++){
if(array[j]<min){
min=array[j];
temp=array[j];
array[j]=array[i];
array[i]=temp;
}
}
newArray[i]=min;
}
for(int num:newArray){
System.out.println(" "+num);
}
}
}
堆排序:
堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。
堆排序是一种选择排序,整体主要由构建初始堆+交换堆顶元素和末尾元素并重建堆两部分组成。其中构建初始堆经推导复杂度为O(n),在交换并重建堆的过程中,需交换n-1次,而重建堆的过程中,根据完全二叉树的性质,[log2(n-1),log2(n-2)...1]逐步递减,近似为nlogn。所以堆排序时间复杂度一般认为就是O(nlogn)级。
堆排序Java实现:
package com.algorithm.sort;
/**
* 堆排序
*/
public class HeapSort {
public static void main(String[] args) {
int[] array={39,44,1,0,33,12,37,28,16};
HeapSort heapSort=new HeapSort();
heapSort.heapSort(array);
for(int i=0;i<array.length;i++){
System.out.println(array[i]);
}
}
public void heapSort(int[] a){
if (a==null||a.length<=1){
return;
}
//创建大堆
buildMaxHead(a);
for(int i=a.length-1;i>=1;i--){
//最大元素已经排在下表为0的位置
exchangeElements(a,0,i);//每交换一次沉淀一个最大元素
maxHeap(a,i,0);
}
}
private static void buildMaxHead(int[] a) {
int half=(a.length-1)/2;
for(int i=half;i>=0;i--){
//只需遍历长度的一半
maxHeap(a,a.length,i);
}
}
//length表示用于构造大堆的数组长度元素数量
private static void maxHeap(int[] a, int length, int i) {
int left=i*2+1;
int right=i*2+2;
int largest=i;
if(left<length&&a[left]>a[i]){
largest=left;
}
if(right<length&&a[right]>a[largest]){
largest=right;
}
if(i!=largest){
//进行数据交换
exchangeElements(a,i,largest);
maxHeap(a,length,largest);
}
}
//在数组a里面进行两个下表元素交换
private static void exchangeElements(int[] a,int i,int largest) {
int temp=a[i];
a[i]=a[largest];
a[largest]=temp;
}
}
输出: 0 1 12 16 28 33 37 39 44
代码执行:
思路:
a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。