基础排序算法总结 + 代码实现总结

目录

排序题解题注意:

排序算法总结

不稳定排序

快速排序

堆排序

选择排序

希尔排序

稳定排序

归并排序

直接插入排序

冒泡排序

桶排序

基数排序


排序题解题注意:

问清楚:

(1)排序使用场景:数字个数,数字范围

(2)约束条件,比如时间复杂度

排序算法总结

不稳定排序

快速排序的基本实现

快速排序算法

是一种基于交换的高效的排序算法,它采用了分治法的思想:

1、从数列中取出一个数作为基准数(枢轴,pivot)。 

2、将数组进行划分(partition),将比基准数大的元素都移至枢轴右边,将小于等于基准数的元素都移至枢轴左边。

3、再对左右的子区间重复第二步的划分操作,直至每个子区间只有一个元素。

快排最重要的一步就是划分了。划分的过程用通俗的语言讲就是“挖坑”和“填坑”。

快速排序时间复杂度

1.最优情况

在最优情况下,Partition每次都划分得很均匀,如果排序n个关键字,其递归树的深度就为 [log2n]+1( [x] 表示不大于 x 的最大整数),即仅需递归 log2n 次,需要时间为T(n)的话,第一次Partiation应该是需要对整个数组扫描一遍,做n次比较。然后,获得的枢轴将数组一分为二,那么各自还需要T(n/2)的时间(注意是最好情况,所以平分两半)。于是不断地划分下去,就有了下面的不等式推断:

这说明,在最优的情况下,快速排序算法的时间复杂度为O(nlogn)。

2.最糟糕情况

然后再来看最糟糕情况下的快排,当待排序的序列为正序或逆序排列时,且每次划分只得到一个比上一次划分少一个记录的子序列,注意另一个为空。如果递归树画出来,它就是一棵斜树。此时需要执行n‐1次递归调用,且第i次划分需要经过n‐i次关键字的比较才能找到第i个记录,也就是枢轴的位置,因此比较次数为 ,最终其时间复杂度为O(n^2)。

快速排序稳定性
快速排序是不稳定的算法,它不满足稳定算法的定义。
算法稳定性 -- 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!

总结
1. Quick Sort 更快
2. 而且是就地排序,空间复杂度为O(1)
3. 是递归算法,在不希望使用递归时,Quick Sort 又不是好的选择了。
4. Quick Sort并不是稳定的算法。原先的次序会被打乱

5. 虽然完全逆序的情况下,快速排序会降到选择排序的速度,不过从概率角度来说(参考信息学理论,和概率学),不对算法做编程上优化时,快速排序的平均速度比堆排序要快一些。

6.面试官还会问到同样的nlogn算法,你是会使用快速排序,还是使用Merge Sort:

一般来讲,Quick Sort的速度还是要快一点,而且Merge Sort 还会使用额外的空间。另外就是MergeSort是稳定的排序。而快速排序是不稳定的。

代码实现思路:(其实我觉得挺容易写错的)

图文参考这个博客,很清晰:快速排序---(面试碰到过好几次)_nrsc-CSDN博客_快速排序

int partition(int nums[],int l,int r){
    int pivot = nums[l];
    while(l < r){
        // 注意r > l的判断
        while(r > l && nums[r] >= pivot) r--;
        swap(nums[l],nums[r]);
        while(l < r && nums[l] <= pivot) l++;
        swap(nums[l],nums[r]);
    }
    // 上面while先判断r,所以这里与l交换,具体可以思考1,2,3,4这种情况
    nums[l] = pivot;
    return l;
}

void quick_sort(int nums[], int l,int r){
    if(l >= r) return;
    int mid = partition(nums,l,r);
    quick_sort(nums,l,mid-1);
    quick_sort(nums,mid+1,r);
}


// 注意1,2 这种情况
int main(){
    int nums[] = {9,5,3,7,2,1,10};
    quick_sort(nums,0,6);
    for(auto &i:nums) cout << i << endl;
}

非递归版本:

#include <algorithm>
#include <limits.h>
#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>
#include <queue>
#include <stack>
using namespace std;

int partition(vector<int>& nums,int l,int r){
    int pivot = nums[l];
    while(l < r){
        while(r >= 0 && nums[r] >= pivot) r--;
        swap(nums[r],nums[l]);
        while(l <= r && nums[l] <= pivot) l++;
        swap(nums[r],nums[l]);
    }
    nums[l] = pivot;
    return l;
}


vector<int> quickSort(vector<int>& nums) {
    if(nums.size() < 2) return nums;
    // 用于存储需要sort的下标
    stack<int> s;
    int l,r,mid;
    s.push(0);
    s.push(nums.size()-1);
    while(!s.empty()){
        r = s.top(); s.pop();
        l = s.top(); s.pop();
        mid = partition(nums,l,r);
        if(l < mid-1){
            s.push(l);
            s.push(mid-1);
        }
        if(r > mid+1){
            s.push(mid+1);
            s.push(r);
        }
    }
    return nums;
}

int main(){
    vector<int> nums = {4,4,4,6,7,4,2,5,3,9,4};
    vector<int> res = quickSort(nums);
    for(auto &n:nums) cout << n << endl;
}

链表快排

这题需要注意对是,无论用快排还是归并,都不要使用头插法之类,需要将链表节点取下来都写法,因为在递归都过程中,会引起节点都掉落,只去交换链表的值即可

我们只需要两个指针p和q,这两个指针均往next方向移动,移动的过程中保持p之前的key都小于选定的key,p和q之间的key都大于选定的key,那么当q走到末尾的时候便完成了一次支点的寻找。

class Solution {
public:
    ListNode* partition(ListNode* begin,ListNode* end){
        int key = begin->val;
        ListNode* p = begin,*q = begin;
        // 这里的patition,保证p之前小于等于key,p和q之间的大于key
        while(q != end){
            if(q->val < key){
                p = p->next;
                swap(p->val,q->val);
            }
            q = q->next;
        }
        swap(p->val,begin->val);
        return p;
    }
    
    ListNode* quickSort(ListNode* begin,ListNode* end){
        if(begin == end || begin->next == end) return begin;
        ListNode* pivot = partition(begin,end);
        ListNode* left = quickSort(begin,pivot);
        ListNode* right = quickSort(pivot->next,end);
        return left? left:pivot;
    }
    
    ListNode* sortList(ListNode* head) {
        if(!head) return head;
        return quickSort(head,NULL);
    }
};

Python(会超出leetcode时间限制)

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        return self.quickSort(head,None)
        
    def quickSort(self,begin,end):
        if begin == end or begin.next == end:
            return begin
        pivot = self.partition(begin,end)
        l = self.quickSort(begin,pivot)
        r = self.quickSort(pivot.next,end)
        if l:
            return l
        else:
            return pivot    

    def partition(self,begin,end):
        key = begin.val
        p,q = begin,begin
        while q != end:
            if q.val < key:
                p = p.next
                q.val,p.val = p.val,q.val
            q = q.next
        p.val,begin.val = begin.val,p.val  
        return p

堆排序

  堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:

同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子

该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是:

大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]  

小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]  

堆排序

基本思想:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了

堆排序是一种选择排序,整体主要由:

具体建堆图:【排序】堆排序,C++实现 - wanglei5205 - 博客园

(1)构建初始堆

(2)交换堆顶元素和末尾元素并重建堆两部分组成。

时间复杂度:

(1)构建初始堆经推导复杂度为O(n),在交换并重建堆的过程中,需交换n-1次

(2)重建堆的过程中,根据完全二叉树的性质,[log2(n-1),log2(n-2)...1]逐步递减,近似为nlogn。所以堆排序时间复杂度一般认为就是O(nlogn)级。

堆怎样删除

堆插入元素

#include <algorithm>
#include <limits.h>
#include <iostream>
#include <vector>
using namespace std;

void adjust_heap(vector<int> &nums,int len,int idx){
    int left = 2*idx+1;
    int right = 2*idx+2;

    int maxidx = idx;
    if(left < len && nums[left] > nums[maxidx]) maxidx = left;
    if(right < len && nums[right] > nums[maxidx]) maxidx = right;

    // 如果已为最大,就不需向下递归调整,只有需要swap以后,才需要继续递归
    if(maxidx != idx){
        swap(nums[maxidx],nums[idx]);
        adjust_heap(nums,len,maxidx);
    }
}

void heap_sort(vector<int> &nums,int len){
    // build the heap
    for(int i = nums.size()/2-1;i >= 1;i--){
        adjust_heap(nums,len,i);
    }

    for(int i = nums.size()-1;i >= 1;i--){
        swap(nums[0],nums[i]);
        adjust_heap(nums,i,0);
    }
}

int main(){
    vector<int> nums{8,3,5,6,4};
    heap_sort(nums,nums.size());
    for(auto &n:nums) cout << n << endl;
}

选择排序

在剩余序列中选出最小(或最大)的关键字,和剩余序列的第一个关键字交换位置,依次选择下去,直至使整个序列有序。

时间复杂度:

算法中两层循环的执行次数和初始序列没有关系,第二层循环每一次都需要遍历剩余带排序序列,故时间复杂度为O(n2)

#include <algorithm>
#include <limits.h>
#include <iostream>
#include <vector>
using namespace std;

void select(vector<int> &nums,int start){
    int min_idx = start;
    for(int i = start;i < nums.size();++i){
        if(nums[i] < nums[min_idx]) min_idx = i;
    }
    swap(nums[start],nums[min_idx]);
}

void select_sort(vector<int> &nums){
    for(int i = 0;i < nums.size()-1;++i){
        select(nums,i);
    }
}

int main(){
    vector<int> nums{8,3,5,6,4};
    select_sort(nums);
    for(auto &n:nums) cout << n << endl;
}

希尔排序

示意图:

我们选择增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择我们可以用一个序列来表示,{n/2,(n/2)/2...1},称为增量序列希尔排序的增量序列的选择与证明是个数学难题,我们选择的这个增量序列是比较常用的,也是希尔建议的增量,称为希尔增量,但其实这个增量序列不是最优的。

每次在组内进行排序(这里使用直接插入排序),然后不断的扩大组,直到最后组为整个序列(即gap = 1)

该方法实质上是一种分组插入方法

稳定性:

由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

时间复杂度:

我们上面选择的增量序列{n/2,(n/2)/2...1}(希尔增量),其最坏时间复杂度依然为O(n2),一些经过优化的增量序列如Hibbard经过复杂证明可使得最坏时间复杂度为O(n3/2)

#include <algorithm>
#include <limits.h>
#include <iostream>
#include <vector>
using namespace std;

void shell_sort(vector<int> &nums){
    int len = nums.size();
    // gap为步长,每次减为原来的一半
    for(int gap = int(len)/2;gap > 0;gap /= 2){
        // 共gap个组,对每一组都执行直接插入排序
        for(int i = 0;i < gap;i++){
            for(int j = i+gap;j < len;j += gap){
                int k = j,key = nums[j];
                // 直接插入排序,注意这里是跟key比,不是直接nums[k] < nums[k-gap]
                while(key < nums[k-gap] && (k-gap >= 0)){
                    nums[k] = nums[k-gap];
                    k = k-gap;
                }
                nums[k] = key;
            }
        }
    }
}

int main(){
    vector<int> nums{8,3,5,14,6,4,10,0,4};
    shell_sort(nums);
    for(auto &n:nums) cout << n << endl;
}


稳定排序

归并排序

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

总结:

归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序一般性能都不会太差。java中Arrays.sort()采用了一种名为TimSort的排序算法,就是归并排序的优化版本。

时间复杂度

每次合并操作的平均时间复杂度为O(n),而完全二叉树的深度为|log2n|。总的平均时间复杂度为O(nlogn)。而且,归并排序的最好,最坏,平均时间复杂度均为O(nlogn)。

空间复杂度:O(n)

归并排序主要分为两部分:

1、划分子区间

2、合并子区间

现在以 9,6,7,22,20,33,16,20 为例讲解上面两个过程:

第一步,划分子区间:每次递归的从中间把数据划分为左区间和右区间。原始区间为[start,end],start=0,end=[length-1],减一是因为数组的下标从0开始,本例中length=8,end=7.现在从中间元素划分,划分之后的左右区间分别为 [start,(end-start+1)/2+start],右区间为[(end-start+1)/2+start+1,end],本例中把start和end带入可以得到[0,7],划分后的左右子区间为[0,4],[5,7],然后分别对[start,end]=[0,4]和[start,end]=[5,7]重复上一步过程,直到每个子区间只有一个或者两个元素。整个分解过程为:

子区间划分好以后,分别对左右子区间进行排序,排好序之后,在递归的把左右子区间进行合并,整个过程如下图所示:

void merge(int *nums,int left,int right,int *result){
    int left_end = (left+right)/2;
    int right_end = right;
    int res_idx = left;
    right = left_end+1;
    //对分别已经排好序的左区间和右区间进行合并,放入result中
    while(left <= left_end && right <= right_end){
        if(nums[left] <= nums[right]){
            result[res_idx++] = nums[left++];
        }else{
            result[res_idx++] = nums[right++];
        }
    }
    while(left <= left_end) result[res_idx++] = nums[left++];
    while(right <= right_end) result[res_idx++] = nums[right++];
}

void merge_sort(int *nums,int left,int right,int *result){
    if(left == right) return;
    if(left + 1 == right){
        if(nums[left] > nums[right]) swap(nums[left],nums[right]);
        return;
    }
    // 分治
    merge_sort(nums, left, (left+right)/2,result);
    merge_sort(nums, (left+right)/2+1,right,result);
    merge(nums,left,right,result);
    for(int i = left;i <= right;i++) nums[i] = result[i];
}


int main(){
    int nums[8] = {9,6,7,22,20,33,16,20};
    const auto length = 8;
    int result[length];
    merge_sort(nums,0,7,result);
    for(auto &i:nums) cout << i << endl;
}

在递归的把左右子区间进行合并,整个过程如下图所示:

单链表归并排序

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(!head || !head->next) return head;
        // 这种情况不可缺,不然等链表长度为2时会进死循环
        if(!head->next->next){
            if(head->val > head->next->val){
                int tmp = head->val;
                head->val = head->next->val;
                head->next->val = tmp;
            }
            return head;
        }
        
        ListNode* slow = head,*fast = head,*pre = head,*left,*right;
        ListNode* dummy_head = new ListNode(-1),*cur = dummy_head;
        
        // 找到终点
        while(fast && fast->next){
            pre = slow;
            slow = slow->next;
            fast = fast->next->next;
        }
        
        pre->next = NULL;
        left = sortList(head);
        right = sortList(slow);
        // 归并
        while(left && right){
            if(left->val <= right->val){
                cur->next = left;
                left = left->next;
            }else{
                cur->next = right;
                right = right->next;
            }
            cur = cur->next;
        }
        if(left) cur->next = left;
        if(right) cur->next = right;
        return dummy_head->next;
    }
};

Python实现

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        p = head
        while p.next:
            p = p.next
        self.mergeSort(head,p)
        return head

    def mergeSort(self,begin,end):
        if begin == end:
            return
        if begin.next == end:
            if begin.val > end.val:
                begin.val,end.val = end.val,begin.val
            return
        slow,quick = begin,begin
        while quick != end and quick.next != end:
            slow = slow.next
            quick = quick.next.next
        self.mergeSort(begin,slow)
        self.mergeSort(slow.next,end)
        self.merge(begin,slow,end)

    def merge(self,begin,mid,end):
        p,q = begin,mid.next
        res = []
        while p != mid.next and q != end.next:
            if p.val <= q.val:
                res.append(p.val)
                p = p.next
            else:
                res.append(q.val)
                q = q.next
        while p != mid.next:
            res.append(p.val)
            p = p.next
        while q != end.next:
            res.append(q.val)
            q = q.next
        p = begin
        for num in res:
            p.val = num
            p = p.next
        

直接插入排序

将数组分为有序区和无序区,开始时第一个元素就是有序区,与第二个元素比较,第一二元素排好序后,再将第三个元素与前2个元素比较插入到合适的位置。后面依次操作。

参考下面动图:

时间复杂度:O(N*N)

#include <algorithm>
#include <limits.h>
#include <iostream>
#include <vector>
using namespace std;

void insert_sort(vector<int> &nums){
    for(int i = 1;i < nums.size();i++){
        int key = nums[i],j;
        for(j = i-1;j >= 0;j--){
            // 注意这步操作,直接赋值到后面
            if(nums[j] > key){
                nums[j+1] = nums[j];
            }
            else break;
        }
        // 这里是到循环外面赋值,否则会有问题
        nums[j+1] = key;
    }
}

int main(){
    vector<int> nums{8,3,5,6,4};
    insert_sort(nums);
    for(auto &n:nums) cout << n << endl;
}

冒泡排序

每次比较都会将最大(小)的元素移动到边缘

# 冒泡排序
def BubbleSort(nums):
    # 不断从前往后,将最大对数沉下去
    for end in range(len(nums)-1,0,-1):
        for i in range(1,end+1):
            if nums[i] < nums[i-1]:
                nums[i-1],nums[i] = nums[i],nums[i-1]
    return nums

桶排序

适用题目

n人参加0-100分的考试,确定排名n/2的人几分(桶排序)

原理:

桶排序(Bucket Sort)的原理很简单,它是将数组分到有限数量的桶子里。

假设待排序的数组a中共有N个整数,并且已知数组a中数据的范围[0, MAX)。

在桶排序时,创建容量为MAX的桶数组r,并将桶数组元素都初始化为0;

将容量为MAX的桶数组中的每一个单元都看作一个"桶"。

注意:若下限不是0,为了尽量节省空间,需要找到待排序数组中最大元素和最小元素,分别是2和9,该区间共有9 - 2 + 1 = 8种可能的值。

时间复杂度

当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。

#include <algorithm>
#include <limits.h>
#include <iostream>
#include <vector>
using namespace std;

void busket_sort(vector<int> &nums,int max_num){
    // 初始化为0
    int busket[max_num+1] = {0};
    // 计数
    for(auto &n:nums){
        busket[n]++;
    }
    // 排序
    for(int i = 0,j = 0;i <= max_num;i++){
        while((busket[i]--) > 0){
            nums[j++] = i;
        }
    }

}

int main(){
    vector<int> nums{8,3,5,6,4};
    busket_sort(nums,8);
    for(auto &n:nums) cout << n << endl;
}

基数排序

通过基数排序对数组{53, 3, 542, 748, 14, 214, 154, 63, 616},它的示意图如下:

在上图中,首先将所有待比较数统一为统一位数长度,接着从最低位开始,依次进行排序。
1. 按照个位数进行排序。
2. 按照十位数进行排序。
3. 按照百位数进行排序。
排序后,数列就变成了一个有序序列。

思路:

实现

#include <algorithm>
#include <limits.h>
#include <iostream>
#include <vector>
using namespace std;

int get_max(int nums[],int n){
    int max = nums[0];
    for(int i = 1;i < n;i++){
        if(max < nums[i]) max = nums[i];
    }
    return max;
}

void count_sort(int nums[],int n,int exp){
    int buskets[10] = {0};
    int output[n];

    // 第一遍统计每个桶个数
    for(int i = 0;i < n;i++){
        int idx = (nums[i]/exp)%10;
        buskets[idx]++;
    }

    // 第二遍记录桶内元素在output中应该放置的下标(注意这里下面使用时要-1)
    for(int i = 1;i < 10;i++){
        buskets[i] += buskets[i-1];
    }

    for(int i = n-1;i >= 0;i--){
        // 注意这里的-1,桶里是个数,这里需要下标
        output[buskets[(nums[i]/exp)%10]-1] = nums[i];
        buskets[(nums[i]/exp)%10]--;
    }

    for(int i = 0;i < n;i++) nums[i] = output[i];
}

void radix_sort(int nums[],int n){
    int len = get_max(nums,n);
    for(int exp = 1;len/exp > 0;exp *= 10){
        count_sort(nums,n,exp);
        for(int i = 0;i < n;i++) cout << nums[i] << ' ';
        cout  << endl;
    }
}

int main(){
    int nums[] = {9,5,3,72,2,1,10,66,500,233};
    radix_sort(nums,10);
    for(auto &i:nums) cout << i << endl;
}

Python Sort实现

# 直接插入
def InsertSort(nums):
    for i in range(1,len(nums)):
        key,j = nums[i],i-1
        while j >= 0 and nums[j] > key:
            nums[j+1] = nums[j]
            j -= 1
        j += 1
        nums[j] = key
    return nums

# 希尔
def ShellSort(nums):
    for gap in range(len(nums)//2,0,-1):
        for begin in range(0,gap):
            for i in range(begin+gap,len(nums),gap):
                key,j = nums[i],i-gap
                while j >= 0 and nums[j] > key:
                    nums[j+gap] = nums[j]
                    j -= gap
                j += gap
                nums[j] = key
    return nums

# 归并
def MergeSort(nums):
    mergeSort(nums,0,len(nums)-1)
    return nums

def mergeSort(nums,begin,end):
    if begin == end:
        return
    if begin+1==end:
        if nums[begin] > nums[end]:
            nums[begin],nums[end] = nums[end],nums[begin]
        return
    mergeSort(nums,begin,(begin+end)//2)
    mergeSort(nums,(begin+end)//2+1,end)
    return merge(nums,begin,end)

def merge(nums,begin,end):
    lb,le,rb,re = begin,(begin+end)//2,(begin+end)//2+1,end
    res = []
    i,j = lb,rb
    while i <= le and j <= re:
        if nums[i] <= nums[j]:
            res.append(nums[i])
            i += 1
        else:
            res.append(nums[j])
            j += 1
    while i <= le:
        res.append(nums[i])
        i += 1
    while j <= re:
        res.append(nums[j])
        j += 1
    i = begin
    for num in res:
        nums[i] = num
        i += 1

# 基数排序
def RedixSort(nums):
    maxNum,exp = max(nums),1
    while exp <= maxNum:
        redixSort(nums,exp)
        exp *= 10
    return nums

# 逐个篮子走,个十百位排列下去,就可以有序了
def redixSort(nums,exp):
    baskets =[[] for i in range(10)]
    for num in nums:
        idx = (num//exp)%10
        baskets[idx].append(num)
    i = 0
    for basket in baskets:
        for num in basket:
            nums[i] = num
            i += 1

# 冒泡排序
def BubbleSort(nums):
    # 不断从前往后,将最大对数沉下去
    for end in range(len(nums)-1,0,-1):
        for i in range(1,end+1):
            if nums[i] < nums[i-1]:
                nums[i-1],nums[i] = nums[i],nums[i-1]
    return nums

nums = [4,2,6,5,8,11,7]
print(BubbleSort(nums))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值