算法学习day4---排序

tech2023-02-19  90

排序算法和其时间复杂度

插入排序 堆排序 归并排序 快速排序 是最重要的 稳定不稳定就是指值相同的元素,拍完序之后的相对位置是否会改变(谁在谁的左边)

基本的排序算法

冒泡排序:每次把最大的移到最后面。最好的情况On (但是这个时候需要一个标记,标记元素是否发生改变),最坏的情况On^2 ==>n+n-1+n-2+…+1选择排序:每次找到第n的元素,并与第n-1个元素进行互换。最好的情况On^2(即使是有序的,每次都需要找最小的元素去交换),最坏的情况 On^2(和最好的情况时间复杂度是一样的,只不过多个了交换)。空间复杂度O1 (只需要个常量 temp)稳定性:不稳定插入排序:将第m+1个数插入到前m个已经排好序的元素中,递归。最好的情况On,最坏的情况On^2,空间复杂度O1 稳定性:稳定 二分插入排序:在将第m+1个数插入到前m个已经排好序的元素中去时,采用二分查找的方式查找元素应该插入的位置

常考的排序算法

归并排序 最好的情况==最坏的情况==Onlogn 空间复杂度 On 稳定快速排序 选一个pivot(一般选最右侧元素)有左指针和右指针,当左指针指向一个大于pivot的数,右指针指向一个小于pivot的数,交换。当 l==r 时,当前元素大于pivot,则交换,否则 l+1元素与pivot交换,(保证pivot左侧都小于,右侧都大于)对剩余没有排序的俩个区间进行相同的操作(选pivot…) 这是一个递归的过程最好的情况是 Onlogn , 最坏的情况是n^2 空间复杂度是 Ologn 不稳定 拓扑排序

其他排序算法

堆排序桶排序

选择排序

每次找出第i小的元素的下标,并与第i位交换 public void sort(int[] nums){ for (int i = 0; i < nums.length-1; i++) { int t=i; for (int j = i; j <nums.length ; j++) { if(nums[j]<nums[t]) t=j; } int temp=nums[t]; nums[t]=nums[i]; nums[i]=temp; } }

插入排序

从第二个元素开始,已插入的方式,插入到该在的位置,其他元素左移或者右移 public void sort(int[] nums){ for (int i = 1; i < nums.length; i++) { int temp=nums[i],j=i;//从j开始往前枚举 while (j>0 && temp<nums[j-1]){ //移动 nums[j]=nums[j-1]; j--; } nums[j]=temp; //移动后插入 } }

希尔排序

希尔排序是一种高效的插入排序希尔增量gap = length/2 步骤: 希尔排序是先对 数组分成gap组,第i个和第gap+i个进行插入排序之后 数组被分成gap/2组,第i个和第i+gap/2和第gap+i个进行插入排序直到gap/2/2==1,这个 时候做个总的插入排序,时间要快很多

时间复杂度:最好的情况Onlogn , 最坏的情况 On(logn)^2 空间复杂度:O(1) 稳定性:不稳定 因为希尔排序 分组插入,所以不稳定

堆排序

基本思路:先把数组构建成一个大顶堆,然后将堆顶和数组的最后一个元素互换,这样就把最大值移到了最后方,再把数组的n-1重新构建大顶堆,再将堆顶和倒数第二个元素互换。依次类推,直至数组排序完成。 堆重建就是将不满足顶堆规则的元素进行交换

对于一个堆来说: 是一个完全二叉树 (从左致右依次增加)所有父节点的值都要大于(或小于)子节点的值 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序中用于升序排序小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序中用于降序排序 时间复杂度: 最好的情况:Onlogn == 最坏的情况 Onlogn 空间复杂度:O1 稳定性:不稳定 因为得排成二叉树,且存在交换,所以无法确定相同元素的先后顺序

计数排序

基本思路:将数组从头到尾遍历一遍,找到其中的最小值和最大值。并把最小值到最大值中间所有的整数都列举出来,并把所有数字之间出现的次数相加起来。 然后就无需管原数组,将数组按最小到最大以及出现次数 写出就好 用在重复数很多的情况下更好 时间复杂度:最好的情况:O(n+k)==最坏的情况O(n+k) 空间复杂度:O(k) 稳定性:稳定

桶排序

一个进阶版的计数排序(因为计数排序相当于每个桶长度为1的桶排序) 基本思路:分桶,对各个元素放入到相应的桶中,对桶中元素进行排序,然后按桶一次输出 时间复杂度:最好的情况:O(n+k)(k是桶的个数)最坏的情况:O(n^2)(最坏的情况是所有元素都在一个桶里,这样就相当于一个简单的排序) 空间复杂度:O(n+k) 稳定性:稳定(其实稳不稳定,主要看桶内的排序算法,所以不一定是稳定的)

基数排序

基数排序像是一个特殊版本的桶排序,单个桶为0~9,存入按当前位数的数字存。(依次按位进行存入) 基本思路:先按各位存入0~9号桶中(当前位 ==桶号),之后将上次存入好后的顺序的按十位进行存入,依次反复,直到位数结束,就得到了排好序的数组 时间复杂度:最好的情况下:O(nk) ==最坏的情况下:O(nk)(k为最大数的位数) 空间复杂度:O(n+k) 稳定性:稳定
最新回复(0)