一、选择排序
1、算法原理
每一趟从待排序的记录当中选出最小的元素,顺序放在已经排好序的序列的后面,直到全部记录排序完毕。
2、算法思想
首先找到所有数中最小值的下标;找到最小值的下标与第一个位置的数值交换位置,这样每一次找到的最小值固定在前面;循环操作直到遍历找到所有。
舞蹈之选择排序:http://v.youku.com/v_show/id_XMzMyODk5MDI0.html?from = s1.8-1-1.2
时间复杂度:O(n ^ 2),由于选择排序每一轮只交换一次,所以其实际性能要优于冒泡排序。
代码演示:
public static void selectSort(int[] arr){
for(int i=0;i<arr.length;i++){
int min=i;
int j=i+1;
for(;j<arr.length;j++){
if(arr[min] > arr[j]){//找出最小值的下标
min=j;
}
}
if(min>i) {//将最小值从头开始放
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
}
二、堆排序
堆排序是一种树形选择排序,是对直接选择排序的有效改进。
1、堆的概念
堆是一颗顺序存储的完全二叉树。完全二叉树中所有的非终端结点的值均不大于(均不小于)其左、右孩子结点的值。
小根堆:每个节点的值小于等于其左、右孩子结点的值。
大根堆:每个节点的值大于等于其左、右孩子结点的值。
2、算法思想
将待排序的序列构造成一个大根堆,此时,整个序列中的最大值就是堆顶的根节点,将其与末尾的元素进行交换,此时,末尾就是最大值,然后将剩余n-1个元素重新构造成一个堆,这样得到n个元素的次小值,如此反复进行执行,就能够得到一个有序的序列了。
时间复杂度:O(nlong2n) 空间复杂度:O(1)
3、算法步骤
步骤一:构建初始堆。将给定的无序的序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)
此时,我们就将无序数组构造成了一个大顶堆。
步骤二:将堆顶元素和末尾的元素进行交换,使得末尾的元素最大,然后继续调整堆,再将堆顶元素和末尾的元素进行交换,得到第二大元素。如此反复进行交换、重建、交换。
代码演示:
public static void adjust(int[] arr, int start, int end) {
int temp=arr[start];
for(int i=2*start+1;i<=end;i=2*i+1){
if(i+1<=end && arr[i]<arr[i+1]){
i++;//i保存左右结点的较大值的下标
}
if(temp<arr[i]){
arr[start]=arr[i];
start=i;
}else{
break;
}
}
arr[start]=temp;
}
public static void heapSort(int[] arr){
int i=0;
for(i=(arr.length-1-1)/2;i>=0;i--){//i代表要调整的根节点的下标
adjust(arr,i,arr.length-1);//建立最大堆
}
int temp=0;
for(i=0;i<arr.length;i++){
temp=arr[0];//根保存最大值
arr[0]=arr[arr.length-i-1];//arr[0]赋值为当前待排序的最后一个值
arr[arr.length-1-i]=temp;
adjust(arr,0,arr.length-1-i-1);
}
}
三、归并排序
1、算法原理
对于给定的一组记录,利用递归和分治技术将数据序列划分成为越来越小的半子表,再对半子表进行排序,最后再用递归的方法将排好序的半子表合并成为有序序列。
舞蹈之归并排序:http://v.youku.com/v_show/id_XMzMyODk5Njg4.html?from = s1.8-1-1.2
2、算法思想
将数据集合两分拆开;循环拆分至每组只剩一个为止;将拆分的数组进行排序组合;两两合并,直至合并成为一个数组。
具体的过程示意如下图:
代码演示:
public static void mergeSort(int[] arr,int low,int mid,int high) {
int i=low;
int j=mid+1;
int[] temp=new int[high-low+1];
int k=0;
while(i<=mid && j<=high){
if(arr[i]<arr[j]){
temp[k++]=arr[i++];
}else if(arr[i]>arr[j]){
temp[k++]=arr[j++];
}
}
while(i<=mid){
temp[k++]=arr[i++];
}
while(j<=high){
temp[k++]=arr[j++];
}
for(int k2=0;k2<temp.length;k2++){
arr[k2+low]=temp[k2];
}
}
public static void merge(int[] arr,int low,int high){
int mid=(low+high)/2;
if(low<high){
merge(arr,low,mid);
merge(arr,mid+1,high);
mergeSort(arr,low,mid,high);
}
}