更新时间:2022-11-16 10:58:56 来源:极悦 浏览1087次
排序算法是一种将元素集合按特定顺序排列的算法。
例如:
您想将数字列表按升序排序或将名称列表按字典顺序排序。
关于排序算法的实现、数据结构的时间复杂度和算法面试,有很多关于排序算法的问题。在进行算法面试之前,了解所有排序算法的优缺点是非常重要的。
思想:第一个为一个有序数组,之后每一个都向该数组中插入,从后往前,大于待插入数字的后移。
复杂度:插入排序是稳定的。时间复杂度O(N^2),空间负责度O(1);
public static void sort(int[] x)
{
int n = x.length;
for( int i=1; i<n; i++)
{
//待插入元素
int tmp = x[i];
int j;
for(j=i-1; j>=0 && x[j]>tmp; j--)
x[j+1] = x[j];
x[j+1] = tmp;
}
思想:第一次选择一个最小的跟第一个元素交换,第二次选择剩下里面的最小的跟第二个交换,直到都比完。
复杂度:O(N^2),O(1)
public static void sort(int[] x)
{
//选择排序
int n = x.length;
for(int i=0; i<n; i++)
{
int min = i;//最小的
for(int j=i+1; j<n; j++)
if(x[min]>x[j])
min = j;//下标最小的
int tmp = x[i];
x[i] = x[min];
x[min] = tmp;
}
}
初始时,把要排序的数的序列看作是一颗顺序存储的二叉树,调整它们的顺序,使之成为一个大根堆,此时根节点的值最大,把根节点和最后一个元素交换,把前面n-1个数又重排,重复第一次的操作。直到最后剩下两个,交换它们的顺序就得到了有序数组。
时间复杂度O(nlogn)
这个过程分为两部分。一个是建堆,一个是堆顶与最后一个元素交换。
//堆排序
public static void maxHeap(int[] a, int start, int end)//start是开始的父亲,end是最后一个要排序的元素
{
//我们建的是大根堆,每次跟左右孩子里面最大的一个交换
int left = start*2+1;
int right = left+1;
int tmp = a[start];
int cur = start;
for(; left<=end; cur=left, left=cur*2+1, right=left+1)//左节点为上一次循环中用来交换的位置,所以本次循环中将检查left为父亲的节点树是否符合大根堆
{
if(left<end && a[left]<a[right])
left++;
if(tmp>=a[left])//tmp是需要调整的数,
break;
else //tmp<a[left],要换位置。tmp实际上就是a[cur]的位置
{
a[cur] = a[left];
a[left] = tmp;
}
}
}
public static void sort(int a[],int end)
{
int tmp;
for(int i=end/2-1; i>=0; i--)
maxHeap(a, i, end-1);//初始化大根堆
for(int i=end-1; i>=1; i--)
{
//交换根节点与最后一个节点
tmp = a[0];
a[0] = a[i];
a[i] = tmp;
maxHeap(a, 0, i-1);
}
}
每次都把最大的冒泡到最后面。可以加个判断,如果一趟中没有交换,说明该数组已经有序,就不需要再继续扫描了。
public static void Sort(int[] x)
{
if(x.length==0)
System.exit(0);
int n = x.length,max=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
if(x[i]<x[j])
{
int tmp = x[j];
x[j] = x[i];
x[i] = tmp;
}
}
}
public static void Sort(int[] x)
{
if(x.length==0)
System.exit(0);
boolean a=false;
int n = x.length,max=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
if(x[i]<x[j])
{
int tmp = x[j];
x[j] = x[i];
x[i] = tmp;
a = true;
}
if(!true)
System.exit(0);
}
}
借用图:选择一个基准(第一个或最后一个)每次比较之后判断放在基准的哪一边。
快速排序是不稳定的。复杂度O(nlog2n)
public static void quickSort(int[] nums, int left, int right){
if(left>=right)
return;
int i=left, j=right;
int temp = nums[left];
while(i<j) {
while(i<j && nums[j]>=temp)//必须是>=,否则相等的时候不会移动,会卡在这里
j--;
nums[i] = nums[j];
while(i<j && nums[i]<=temp)
i++;
nums[j] = nums[i];
}
nums[i] = temp;
System.out.println(Arrays.toString(nums));
quickSort(nums, left,i-1);
quickSort(nums,i+1,right);//i+1,不能是i,中间不能排
}
把两个或者两个以上元素排好序,再把两个有序段排序,以此类推,直到排完。
//归并排序
public static void Sort(int a[], int begin, int end)
{
int mid = (begin+end)/2;
if(begin<end)//少了这句会堆栈溢出
{
Sort(a, begin, mid);
Sort(a, mid+1, end);
Merge(a, begin, mid, end);
}
}
public static void Merge(int a[], int begin, int mid, int end)
{
int tmp[] = new int[end-begin+1];//新的数组
int l = begin, r = mid+1;//左右指针
int k = 0;//新数组的指针
while(l<=mid && r<=end)
{
if(a[l] > a[r])
tmp[k++] = a[r++];
else
tmp[k++] = a[l++];
}
while(l<=mid)
tmp[k++] = a[l++];
while(r<=end)
tmp[k++] = a[r++];
//把已合并的列入原数组
for(int i=0; i<end-begin+1; i++)
a[begin+i] = tmp[i];
}
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习