public class SortTest {
public static void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
//插入排序,时间复杂度最差,平均O(n^2);最好O(n),空间复杂度1
public static void InsertSort(int[] nums){
InsertSort(nums, 0, nums.length);
}
private static void InsertSort(int[] nums, int start, int end){
int s1=0,s2=0,k =0;
for(s1 = start+1; s1 < end; s1 ++){
//为nums[i]在前面的nums[0...i-1]有序区间中找一个合适的位置
for (s2 = s1 - 1; s2 >= 0; s2--)
if (nums[s2] < nums[s1])
break;
//如找到了一个合适的位置
if (s2 != s1 - 1)
{
//将比nums[i]大的数据向后移
int temp = nums[s1];
for (k = s1 - 1; k > s2; k--)
nums[k + 1] = nums[k];
//将nums[i]放到正确位置上
nums[k + 1] = temp;
}
}
}
//快排,时间复杂度平均O(nlogn),最坏O(n^2),空间复杂度O(logn),时间复杂度体现在递归栈上
public static void QuickSort(int[] nums){
QuickSort(nums,0,nums.length);
}
private static void QuickSort(int[] nums, int start, int end){
int i = start;
int j = end-1;
//start为描点数据
while(i<j){
while(i<j && nums[i] <= nums[j])j--;
if(i<j){
swap(nums,i,j);
}
while(i<j && nums[i] <= nums[j])i++;
if(i<j){
swap(nums,i,j);
}
}//分割数组,迭代排序
if(i-start > 1){
if(i-start < 10){//当数据量较小时,使用插入排序效率更高
InsertSort(nums, start, i);
}
else
QuickSort(nums, start, i-1);
}
if(end-i > 1){
if(end-i < 10){
InsertSort(nums, i+1, end);
}
else
QuickSort(nums, i+1, end);
}
}
//归并排序,时间复杂度 最差,平均O,最好O(nlogn),空间复杂度 O(n)
public static void MergeSort(int[] nums){
MergeSort(nums,0,nums.length);
}
private static void MergeSort(int[] nums, int start, int end){
if(start+10<end){
int mid = (start+end)/2;
MergeSort(nums, start, mid);
MergeSort(nums, mid, end);
//合并归并项
int i = start, j = mid;
int[] arrayTemp = new int[end-start];//额外申请空间
int k = 0;
while(i < mid && j < end){
if(nums[i] > nums[j]){
arrayTemp[k++] = nums[j++];
}
else{
arrayTemp[k++] = nums[i++];
}
}
if(i<mid){
for(j = i; j < mid; j ++)arrayTemp[k++]=nums[j];
}
if(j<end){
for(i = j; i < end; i ++)arrayTemp[k++] = nums[i];
}
System.arraycopy(arrayTemp, 0, nums, start, arrayTemp.length);//复制数组
}
else{
InsertSort(nums, start, end);
}
}
//堆排序,时间复杂度最差,平均O(n),最好O(nlogn),空间复杂度 1
public static void HeapSort(int[] nums){
for (int i = nums.length / 2 - 1; i >= 0; i--)
HeapSortFixup(nums, i, nums.length);//生成最大堆
for (int i = nums.length - 1; i >= 1; i--){
swap(nums, i, 0); //每次将最大数nums[0]放在最后,遍历可使得数组从下到大有序
HeapSortFixup(nums, 0, i);
}
}
private static void HeapSortFixup(int a[], int i, int n) //从下向上整理堆
{
int j, temp;
temp = a[i];
j = 2 * i + 1;
while (j < n)
{
if (j + 1 < n && a[j + 1] > a[j]) //在左右孩子中找最小的
j++;
if (a[j] <= temp)
break;
a[i] = a[j]; //把较小的子结点往上移动,替换它的父结点
i = j;
j = 2 * i + 1;
}
a[i] = temp;
}
//计数排序,时间复杂度复杂度为Ο(n+k)(其中k是整数的范围),空间复杂度O(n)
public static void CountSort(int[] nums){
CountSort(nums, 0, nums.length, 10);
}
private static void CountSort(int[] nums, int start, int end, int count){//count是nums数组的值域
int[] c = new int[count];//c[i]=值域范围内nums数组值为i的个数
int[] b = new int[end-start];//额外空间,用于数组值的复制
for(int i=0; i < count; i ++)
c[i]=0;
for(int j=start; j < end; j ++)//计算相应元素的个数
c[nums[j]] = c[nums[j]]+1;
for(int i=1; i < count; i ++)//计算元素的顺序
c[i]=c[i]+c[i-1];
for(int j=end-1; j >= start; j --){//从后向前,将数组元素插入相应位置
b[c[nums[j]]-1] = nums[j];
c[nums[j]] -= 1;
}
System.arraycopy(b, 0, nums, start, b.length);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] nums = {1,3,4,5,2,7,6,9};
//QuickSort(nums);
//InsertSort(nums);
//MergeSort(nums);
//HeapSort(nums);
//CountSort(nums);
for(int i = 0; i < nums.length; i ++){
System.out.print(nums[i]+" ");
}
}
}
常用排序算法——插入排序,快速排序,归并排序,堆排序,计数排序
最新推荐文章于 2022-08-25 17:51:05 发布