时间复杂度为O(n^2)的:
插入、选择(不稳定)、冒泡
时间复杂度为O(nlogn)的:
堆(不稳定),快速(不稳定),归并
一、插入排序
将数组中的所有元素依次跟前面已经排好的元素相比较,如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过为止。
public static void 插入排序(int[] arr)
{
for(int i=0;i<arr.length-1;i++)
{
for(int j=i+1;j>0;j--)
{
if(arr[j-1]>arr[j])
{
swap(arr,j-1,j);
}
}
}
System.out.println(Arrays.toString(arr));
}
O(n^2) 稳定
二、选择排序
每次都在剩余的数组中找到最小值,把找到的最小值和头节点值交换,重复arr.length轮
public static void 选择排序(int[] arr)
{
for(int i=0;i<arr.length-1;i++)
{
int minIndex=i;
for(int j=i+1;j<arr.length;j++)
{
if(arr[j]<arr[minIndex])
{
minIndex=j;
}
}
if(minIndex != i)
{
swap(arr,minIndex,i);
}
}
System.out.println(Arrays.toString(arr));
}
O(n^2), 不稳定
序列5 8 5 2 9, 这个在执行选择排序的时候,第一遍,肯定会将array[0]=5,交换到2所在的位置,也就是 2 8 5 5 9,那么很显然,之后的排序我们就会发现,array[2]中的5会出现在原先的array[0]之前,所以选择排序不是一个稳定的排序
三、冒泡排序
不解释,你学的第一个算法
public static void 冒泡排序(int[] arr)
{
for(int i=arr.length-1;i>0;i--) //每次需要排序的长度
{
for(int j=0;j<i;j++)
{
if(arr[j]>arr[j+1])
swap(arr,j,j+1);
}
}
System.out.println(Arrays.toString(arr));
}
O(n^2) , 稳定
四、快速排序
递归的思想,每次选择一个元素,左边的数组都小于选定元素,右边的数组都大于选定元素;
public static void 快速排序(int[] arr,int low,int high)
{
if(arr.length<=0) return;
if(low>=high) return;
int left = low;
int right = high;
int temp = arr[low];
while(left<right)
{
while(left<right && arr[right]>temp)
right--;
while(left<right && arr[left]<=temp)
left++;
swap(arr,left,right);
}
swap(arr,left,low);
System.out.println("Sorting:" + Arrays.toString(arr));
快速排序(arr,low,left-1);
快速排序(arr,left+1,high);
}

https://www.youtube.com/watch?v=T258-Umoz9A
O(nlogn) 不稳定
五、归并排序
递归版本:
public static void mergeSort1(int[] arr,int l, int r)
{
if(l<r)
{
int m=l+(r-l)/2;
mergeSort1(arr,l,m);
mergeSort1(arr,m+1,r);
merge(arr,l,m,r);
}
}
public static void merge(int[] arr,int l,int m,int r)
{
int n1 = m-l+1; //左子数组的长度
int n2=r-m; //右子数组的长度
int[] L=new int[n1];
int[] R=new int[n2];
for(int i=0;i<n1;i++)
L[i] = arr[l+i];
for(int j=0;j<n2;j++)
R[j] = arr[m+1+j];
int i=0,j=0,k=l;
while(i<n1 && j<n2)
{
if(L[i]<=R[j])
{
arr[k] = L[i];
i++;
}else{
arr[k]=R[j];
j++;
}
k++;
}
while(i<n1)
{
arr[k] = L[i]; k++; i++;
}
while(j<n2)
{
arr[k] = R[j];k++; j++;
}
}
O(nlogn) 稳定
六、堆排序
public static void heapify(int[] arr,int n,int i)
{
int largest = i;
int l=2*i+1;//左子树的位置
int r=2*i+2;//右子树的位置
if(l<n && arr[l]>arr[largest])
largest=l;
if(r<n && arr[r]>arr[largest])
largest=r;
if(largest != i)
{
swap(arr,i,largest);
heapify(arr,n,largest);
}
}
public static void 堆排序(int[] arr)
{
int n=arr.length;
for(int i=n/2-1;i>=0;i--)
heapify(arr,n,i);
for(int i=n-1;i>=0;i--)
{
swap(arr,0,i);
heapify(arr,i,0);
}
}
O(nlogn) 不稳定
https://blog.youkuaiyun.com/u013309870/article/details/68578011
本文深入讲解了常见的排序算法,包括插入、选择、冒泡、快速、归并和堆排序等,详细介绍了每种算法的工作原理、时间复杂度及稳定性,并提供了具体的Java实现代码。

被折叠的 条评论
为什么被折叠?



