【C语言】一篇文章搞定主流排序—— 插入排序、选择排序、交换排序、归并排序

目录

一、排序介绍

二、排序分类

 三、插入排序

3.1 直接插入排序

3.2 希尔排序

四、选择排序

4.1 直接选择排序

4.2 堆排序

五、交换排序

5.1 冒泡排序

5.2 快速排序

5.2.1 挖坑法

非递归

5.2.3 左右指针法

5.2.4 前后指针法

六、归并排序

6.1 归并排序

非递归


一、排序介绍

排序是日常生活中频繁使用的功能,例如:淘宝的筛选功能,我们可以按照价格进行排序,销量进行排序,这样我们会更容易选择到优质的商品等。

二、排序分类

 三、插入排序

3.1 直接插入排序

思想 :把第一个值当作排好序的,然后把第一个值与下一个值进行比较。

时间复杂度:最好情况(有序)O(N)     最坏情况O(N^2)     平均O(N^2)

 后面的步骤也是一样的,一次一次调换位置,这里的end进入循环时,end位置前的值都是排序好的,插入排序一次只需要排好一个值,所以我们需要一个i来控制end的下一个位置。

#include<stdio.h>
void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void Insert_sort(int* arr,int sz)
{
    int i=0;
    //用来控制比较
    int end=0;
    //sz-1的原因是我们里面采用的是arr[end]和arr[end+1],如果<sz的话就越界了
    for(i=0;i<sz-1;i++)
    {
        end=i;
        int tmp=arr[end+1];
        while(end>=0)
        {
            if(arr[end]>tmp)
            {
                arr[end+1]=arr[end];
                end--;
            }
            //如果在中途找到小的时候也是arr[end+1]=tmp,和越界是一样的,所以我们break
            else
            {
                break;
            }
        }
        arr[end+1]=tmp;
    }
}
int main()
{
    int arr[]={5,4,1,6,3,2};
    Insert_sort(arr,6);
    print(arr,6);
    return 0;
}

3.2 希尔排序

思想:希尔排序是对插入排序的优化,插入排序在逆序的情况下表现是非常差的,我们要改进这一点就是尽量让它有序,我们可以设置一个间隔,在这个间隔内的让他有序,然后缩小间隔。

时间复杂度O(N*logN)

重点:gap=1的时候其实就是插入排序了,所以gap除以2,一直除到小于1就结束了

#include<stdio.h>
void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void Shell_sort(int* arr,int sz)
{
    int gap=sz/2;
    int i=0;
    //用来控制比较
    int end=0;
    //代码唯一最大的区别就在于gap,其他基本就是改一个值
    while(gap>=1)
    {
    //看第一张图片,指向2的位置,2的位置就是最后一个,因为2的位置+gap就已经是最后一个了
    for(i=0;i<sz-gap;i++)
    {
        end=i;
        int tmp=arr[end+gap];
        while(end>=0)
        {
            if(arr[end]>tmp)
            {
                arr[end+gap]=arr[end];
                end=end-gap;
            }
            //如果在中途找到小的时候也是arr[end+1]=tmp,和越界是一样的,所以我们break
            else
            {
                break;
            }
        }
        arr[end+gap]=tmp;
    }
    gap=gap/2;
    }
}
int main()
{
    int arr[]={8,4,1,9,3,2,6,0,7};
    Shell_sort(arr,9);
    print(arr,9);
    return 0;
}

四、选择排序

4.1 直接选择排序

思想:把第一个元素认为成是最小的,然后往下比较,有更小的,就把它的位置给min,找到最小的之后,和第一个元素进行交换,然后把第二个元素认为成最小的,继续比较...

时间复杂度:O(N^2)   这个排序是最差的排序,不推荐使用!

#include<stdio.h>
void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void swap(int* p1,int *p2)
{
    int tmp=*p1;
    *p1=*p2;
    *p2=tmp;
}
void select_sort(int* arr,int sz)
{
    int i=0;
    int j=0;
    int min=0;
    for(i=0;i<sz-1;i++)
    {
        min=i;
        for(j=i+1;j<sz;j++)
        {
            //找出最小的值
            if(arr[min]>arr[j])
            {
                min=j;
            }
        }
        //如果最小的位置不是i,就交换
        if(min!=i)
        {
            swap(&arr[i],&arr[min]);
        }
    }
}
int main()
{
    int arr[]={8,4,1,9,3,2,6,0,7};
    select_sort(arr,9);
    print(arr,9);
    return 0;
}

选择排序可以优化一下,我们可以一次找两个值,一个最大,一个最小。

#include<stdio.h>
void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void swap(int* p1,int *p2)
{
    int tmp=*p1;
    *p1=*p2;
    *p2=tmp;
}
void select_sort_optimize(int* arr,int sz)
{
    int begin=0;
    int end=sz-1;
    //一次找2个,一个最大,一个最小
    int max=0;
    int min=0;
    while(begin<end)
    {
        max=begin;
        min=begin;
        for(int j=begin;j<=end;j++)
        {
            if(arr[min]>arr[j])
            {
                min=j;
            }
            if(arr[max]<arr[j])
            {
                max=j;
            }
        }
        swap(&arr[begin],&arr[min]);
        if(max==begin)
        {
            max=min;
        }
        swap(&arr[end],&arr[max]);
        begin++;
        end--;   
    }
}
int main()
{
    int arr[]={5,6,1,4,3,2,10,7,8};
    int sz=sizeof(arr)/sizeof(arr[0]);
    select_sort_optimize(arr,sz);
    print(arr,sz);
    return 0;
}

4.2 堆排序

思想:在逻辑结构上看成二叉树,所谓逻辑结构就是想象出来的,物理结构上是数组,这个排序较为复杂。

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

这里我会把堆排序的每一步逐一拆解,整个流程和我走一遍后,在回过头来看,就会明白其中的用意。

堆排序就是把数组变成一个完全二叉树,首先假设我们有一个数组:

 把3变成根节点,9、6是孩子节点,7、8是9的孩子节点,5、2是6的孩子节点,依此类推下去...

就形成了这样:

然后这里我们要了解一个概念

(1)大堆:每一个子树都满足双亲大于两个孩子 (2)小堆:每个子树都满足双亲小于孩子

了解这个概念后,问读者一个问题,这个是堆吗?明显不是,3下面的两个节点是大堆,但是整个二叉树并不是堆,因为3不大于9和6

所以我们需要进行一个操作,与下面的每一行进行比较,把最大的换过来,详细请看图:

 这样不就是大堆了吗?在此之前,我们还需要了解一个概念,左孩子=2*父节点+1,即leftchild=2*parent+1,右孩子=2*父节点+2,即rightchild=2*parent+2,知道这些概念后,实现起来就非常容易了,代码如下:

void heapify(int* tree,int n,int root)
{
    int parent=root;
    int leftchild=2*parent+1;
    int rightchild=2*parent+2;
    //完全二叉树没有左节点一定也没有右节点,所以我们用左节点去判断
    while(leftchild<n)
    {
        int max=parent;
        //比较大小
        if(leftchild<n&&tree[max]<tree[leftchild])
        {
            max=leftchild;
        }
        if(rightchild<n&&tree[rightchild]>tree[max])
        {
            max=rightchild;
        }
        //这里满足条件就交换
        if(max!=parent)
        {
        swap(&tree[parent],&tree[max]);
        parent=max;
        leftchild=2*parent+1;
        rightchild=2*parent+2;
        }
        //这里的意思是已经是大堆了,就直接退出了
        else
        {
            break;
        }
    }
}

这里的heapify就是变成堆,应该不难理解吧?但是有一个问题,就是我们如何让根节点下面的节点都是大堆呢?

方法很简单我们只需要从最后一个开始建堆就可以了,假设我们有这样一个数组(图以二叉树的形式表示):

 想解决这种问题,我们就要从最后一个(7)开始建堆,然后是0,不过这里我们并不需要从2,6,0,7,原因是他们没有孩子节点,所以我们需要从9开始建堆,如何找到9呢?

父节点=(孩子节点-1)/2

找到9以后,我们下标-1,这样又回到了8去建堆,回到了最初的开始,理解以后代码实现起来就非常容易了,代码如下:

void build_heap(int* tree,int n)
{
    //最后一个孩子节点
    int child=n-1;
    //最后一个父节点
    int parent=(child-1)/2;
    int i=0;
    for(i=parent;i>=0;i--)
    {
        heapify(tree,n,i);
    }
}

这一步完成后,我们的二叉树就变成了这样:

 前面的步骤完成了,就差最后一步堆排序了,那么我们该如何实现这个过程呢?

步骤:头节点和最后一个节点进行交换,最后一个节点就是最大的了,然后砍掉最后一个,然后进行heapify(进行heapify的目的就是再把最大的放到头节点),再把头节点和最后一个交换,依此类推...步骤如下图:

 剩下的步骤就不写出来了,都是重复的步骤,我们直接看代码(这里把剩下的代码也放出来):

void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void swap(int* p1,int *p2)
{
    int tmp=*p1;
    *p1=*p2;
    *p2=tmp;
}
void heap_sort(int* tree,int n)
{
    build_heap(tree,n);
    int begin=0;
    int end=n-1;
    //end从最后一个走到第一个
    while(end>=0)
    {
        swap(&tree[begin],&tree[end]);
        heapify(tree,end,0);
        end--;
    }
}
int main()
{
    int tree[]={8,4,10,9,3,2,6,0,7};
    int n=sizeof(tree)/sizeof(tree[0]);
    heap_sort(tree,n);
    print(tree,n);
    return 0;
}

五、交换排序

5.1 冒泡排序

思想:从左到右,相邻的元素进行交换,每次比较一轮就会有一个最大或者最小的元素。

时间复杂度:最差情况 O(N^2) 最好情况 O(N)平均情况O(N^2)

 代码如下:

#include<stdio.h>
#include<stdlib.h>
void swap(int *p1,int* p2)
{
    int tmp=*p1;
    *p1=*p2;
    *p2=tmp;
}
void bubble_sort(int* arr,int sz)
{
    int flag=1;
    int i=0;
    int j=0;
    for(i=0;i<sz-1;i++)
    {
        for(j=0;j<sz-1-i;j++)
        {
            if(arr[j]>arr[j+1])
            {
                swap(&arr[j],&arr[j+1]);
                flag=0;
            }
        }
        //优化
        //如果第一次就是有序,直接退出,这样可以让最好情况在O(N)
        if(flag==1)
        {
            break;
        }
    }
}
void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
int main()
{
    int arr[]={1,2,3,4,5};
    int sz=sizeof(arr)/sizeof(arr[0]);
    bubble_sort(arr,sz);
    print(arr,sz);
    return 0;
}

5.2 快速排序

快速排序是所有排序中最常用的一种排序

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

5.2.1 挖坑法

有如下数组:

 把数组第一个元素的位置定义为坑,并且把5关键值(后续用来比较),然后分别定义end(数组后一个位置),begin数组第一个位置

 用arr[end]去和arr[key]比较大小,找到比arr[key]小的以后放到pviot的位置,然后再把pivot的位置换到end的位置上

 再用arr[begin]和arr[key]比较大小,找到比arr[key]大的以后放到pivot的位置,然后再把pivot的位置换到begin的位置上

  再用arr[end]去和arr[key]比较大小,找到比arr[key]小的以后放到pivot的位置,然后再把pivot的位置换到end的位置上

 再用arr[begin]和arr[key]比较大小,找到比arr[key]大的以后放到pviot的位置,不过这是begin和end相遇了,所以我们需要结束,然后把arr[key]的值赋给arr[pivot]

 这是我们发现5的左边都是小于5的元素,5的右边都是大于5的元素

总结:end去找小,begin去找大,找到了就放到pivot的位置,更新pivot的位置

这一步完成后,后面就是递归了,我们需要递归去拆解这个步骤。

左边第一次递归:

 这一次左递归是没有改变的,因为没有值比0更小,所以继续用左区间递归,不过这里有左区间了吗?已经没有了,所以左递归结束了,需要右递归,就是4,1,2,3这几个值

递归的详细过程省略直接得第二次递归的答案:

 

 这里需要继续左递归,即3,1,2:

直接得答案:

 继续左递归,即2,1(这里直接给答案了):

 然后我们需要右递归,发现右边是一个3,不需要递归,然后在右递归,发现右边是一个4,也不需要递归,最后返回去,我们整个的左递归就完成了,如下:

 5的左边递归回来了,就递归5的右边,这里不再展示,思路一样的,实现如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 100
void swap(int *p1,int* p2)
{
    int tmp=*p1;
    *p1=*p2;
    *p2=tmp;
}
void quicksort(int* arr,int left,int right)
{
    //递归结束条件,只剩下一个,或者left>right的时候停止
    if(left>=right)
    {
        return; 
    }
    int begin=left;
    int end=right;
    int key=arr[begin];
    int pivot=begin;
    //相遇就会停止
    while(begin<end)
    {
        //end找小,这里begin<end不可以少,可能中途就会相等
        //这里的等于号不要忘了,不然会造成死循环
        while(begin<end&&arr[end]>=key)
        {
            end--;
        }
        arr[pivot]=arr[end];
        pivot=end;
        //begin找大
        while(begin<end&&arr[begin]<=key)
        {
            begin++;
        }
        arr[pivot]=arr[begin];
        pivot=begin;
    }
    arr[pivot]=key;
    //区间[left,pivot-1]  pivot [pivot+1,right]
    quicksort(arr,left,pivot-1);
    quicksort(arr,pivot+1,right);
}
void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
int main()
{
    int arr[]={8,6,2,10,2,5,8,1,9,8,4,2};
    int sz=sizeof(arr)/sizeof(arr[0]);
    quicksort(arr,0,sz-1);
    print(arr,sz);
    return 0;
}

非递归

思想:利用栈的先进后出,可以做出和递归一样的效果。

//递归的缺陷:栈帧深度太深,栈空间不够用,可能会溢出
int partsort(int* arr,int left,int right)
{
    int begin=left;
    int end=right;
    int key=arr[begin];
    int pivot=begin;
    //相遇就会停止
    while(begin<end)
    {
        //end找小,这里begin<end不可以少,可能中途就会相等
        //这里的等于号不要忘了,不然会造成死循环
        while(begin<end&&arr[end]>=key)
        {
            end--;
        }
        arr[pivot]=arr[end];
        pivot=end;
        //begin找大
        while(begin<end&&arr[begin]<=key)
        {
            begin++;
        }
        arr[pivot]=arr[begin];
        pivot=begin;
    }
    arr[pivot]=key;
    return pivot;
}
void quicksortNonR(int* arr,int sz)
{
    ST s;
    StackInit(&s);
    StackPush(&s,sz-1);
    StackPush(&s,0);
    if(!StackEmpty(&s))
    {
        int left=StackTop(&s);
        StackPop(&s);
        int right=StackTop(&s);
        StackPop(&s);
        int Index=partsort(arr,left,right);
        //[left,Index-1]  Index [Index+1,right]
        if(Index+1<right)
        {
            StackPush(&s,right);
            StackPush(&s,Index+1);
        }
        if(left<Index-1)
        {
            StackPush(&s,Index-1);
            StackPush(&s,left);
        }
    }
}

5.2.3 左右指针法

思想:end找小,begin找大,找到时,两个互相交换,直begin和end相遇,左右指针发和挖坑法基本类似。

//左右指针
void quicksort(int* arr,int left,int right)
{
    if(left>=right)
    {
        return;
    }
    int begin=left;
    int end=right;
    int key=left;
    while(begin<end)
    {
        //end找小
        while(begin<end&&arr[end]>=arr[key])
        {
            end--;
        }
        //begin找大
        while(begin<end&&arr[begin]<=arr[key])
        {
            begin++;
        }
        //大和小进行交换
        swap(&arr[begin],&arr[end]);
    }
    swap(&arr[begin],&arr[key]);
    //[left,begin] begin [begin+1,right]
    quicksort(arr,left,begin-1);
    quicksort(arr,begin+1,right);
}

5.2.4 前后指针法

思想:(这里用升序思维讲解)利用当前指针和key(第一个元素)进行比较,如果他比key小,prev指针+1,然后和当前指针交换。

假设有这样一个数组:

然后我们定义成这样: 

 arr[cur]和arr[key]比较大小,如果比他小就++prev,然后arr[cur]和arr[prev]交换:

cur继续往下走,  arr[cur]和arr[key]比较大小,如果比他小就++prev,然后arr[cur]和arr[prev]交换:

cur继续往下走,  arr[cur]和arr[key]比较大小,这次大于key,所以不用++prev:

cur继续往下走,依然大于key,所以依旧不需要++prev:

 

cur继续往下走,这次比较大小,我们发现arr[cur]<key,我们需要++prev,然后交换arr[prev]和arr[cur]:

 

cur继续往下走, arr[cur]<key,++prev,交换arr[prev]和arr[cur]:

 cur继续往下走, arr[cur]<key,++prev,交换arr[prev]和arr[cur]:

cur继续走,走到10和8的时候,prev是不变的, 直到cur走出去,走出去后,我们只需要交换arr[prev]和key就可以了:

 代码如下:

#include<stdio.h>
void swap(int* p1,int* p2)
{
    int tmp=*p1;
    *p1=*p2;
    *p2=tmp;
}
void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void quicksort(int* arr,int left,int right)
{
    if(left>=right)
    {
        return;
    }
    int prev=left;
    int key=left;
    int cur=prev+1;
    while(cur<=right)
    {
        if(arr[cur]<arr[key])
        {
            ++prev;
            //如果cur==prev就不交换了,因为没有意义
            if(cur!=prev)
            {
                swap(&arr[cur],&arr[prev]);
            }
        }
        ++cur;
    }
    swap(&arr[prev],&arr[key]);
    //[left,prev-1] prev [prev+1,right]
    quicksort(arr,left,prev-1);
    quicksort(arr,prev+1,right);
}
int main()
{
    //5 1 2 3 4 6 9 7 10 8
    int arr[]={6,1,2,7,9,3,4,5,10,8};
    int sz=sizeof(arr)/sizeof(arr[0]);
    quicksort(arr,0,sz-1);
    print(arr,sz);
    return 0;
}

六、归并排序

6.1 归并排序

思想:归并排序的核心思想是分治,我们需要将一个完整的数组先进行拆分,随后合并,合并可以一层一层把逆序变成顺序,和快速排序的思想有点类似,快速排序是每一层进行排序,然后拆分,归并排序则是拆分在排序。

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

假设有这样一个数组: 

另外我们在动态内存开辟一个临时数组,用来交换(将在代码里展示),这几步做好以后,我们要需要求出中间的位置,mid=2(left=0,right=5)  

然后我们开始递归,left和mid递归,mid+1和right递归,继续求中间变量,直到只剩下一个为止(这里左区间先递归,所以只展示左区间):

 

左区间为[left,mid] 右区间为[mid+1,right], 继续递归,先递归左区间:

左区间为[left,mid],右区间为[mid+1,right],继续递归,这时发现left=right,左递归结束,右边也是left=right,右递归结束,这时我们需要用到临时数组了

 然后在把5,6放到原数组的位置去(不展示),还记得我们这里递归回去还差一个右区间吗?还剩下一个1,这个1也是单独的数字,所以递归结束,然后进行比较:

 在回到原数组:

 左边已经有序了,还差右边,继续递归,然后整个数组的左区间和右区间进行比较就可以了,思想是一样的(不再展示),代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 10
void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void _mergesort(int* arr,int* tmp,int left,int right)
{
    if(left>=right)
    {
        return;
    }
    int mid=(left+right)/2;
    //分解
    //[left,mid] [mid+1,right]
    _mergesort(arr,tmp,left,mid);
    _mergesort(arr,tmp,mid+1,right);
    int i=left;
    int begin1=left;
    int end1=mid;
    int begin2=mid+1;
    int end2=right;
    while(begin1<=end1&&begin2<=end2)
    {
        if(arr[begin1]<arr[begin2])
        {
            tmp[i++]=arr[begin1++];
        }
        else
        {
            tmp[i++]=arr[begin2++];
        }
    }
    //把剩下饿数组也放到tmp数里
    while(begin1<=end1)
    {
        tmp[i++]=arr[begin1++];
    }
    while(begin2<=end2)
    {
        tmp[i++]=arr[begin2++];
    }
    //放到原数组
    for(i=left;i<=right;i++)
    {
        arr[i]=tmp[i];
    }
}
void merge_sort(int* arr,int sz)
{
    //动态内存分配
    int* tmp=(int*)malloc(sizeof(int)*sz);
    _mergesort(arr,tmp,0,sz-1);
    free(tmp);
    tmp=NULL;
}
int main()
{
    srand((unsigned)time(NULL));
    // int arr[]={5,6,1,3,8,9};
    // int sz=sizeof(arr)/sizeof(arr[0]);
    // merge_sort(arr,sz);
    // print(arr,sz);
    int arr1[MAX];
    for(int i=0;i<MAX;i++)
    {
        arr1[i]=rand()%100;
    }
    print(arr1,MAX);
    merge_sort(arr1,MAX);
    print(arr1,MAX);
    return 0;
}

非递归

思想:利用循环从1个和1个比,到2个和2个比,然后到4个和4个比,就是递归的逆推过程,递归是一直分到最后一个开始比较,而循环则是一上来就从1个开始比较。

非递归的精髓在于:定义的gap以及退出的条件,下面是代码:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 10
void swap(int* p1,int* p2)
{
    int tmp=*p1;
    *p1=*p2;
    *p2=tmp;
}
void print(int* arr,int sz)
{
    int i=0;
    for(i=0;i<sz;i++)
    {
        printf("%d ",arr[i]);
    }
    printf("\n");
}
void merge_sort(int* arr,int sz)
{
    int* tmp=(int*)malloc(sizeof(int)*sz);
    int gap=1;
    int i=0;
    int begin1=0;
    int end2=0;
    while(gap<sz)
    {
    for(i=0;i<sz;i+=gap*2)
    {
        //[i,i+gap-1] [i+gap,i+2*gap-1]
        begin1=i;
        int end1=i+gap-1;
        int begin2=i+gap;
        end2=i+2*gap-1;
        //记录tmp下次开始的位置
        int j=begin1;
        //右半区间不存在
        if(begin2>sz)
        {
            break;
        }
        //右半区间不全,需要修正
        if(end2>sz)
        {
            end2=sz-1;
        }
        while(begin1<=end1&&begin2<=end2)
        {
            if(arr[begin1]>arr[begin2])
            {
                tmp[j++]=arr[begin2++];
            }
            else
            {
                tmp[j++]=arr[begin1++];
            }
        }
        while(begin1<=end1)
        {
            tmp[j++]=arr[begin1++];
        }
        while(begin2<=end2)
        {
            tmp[j++]=arr[begin2++];
        }
        for(int k=i;k<=end2;k++)
        {
        arr[k]=tmp[k];
        }
    }
    gap*=2;
    }
}
int main()
{
    srand((unsigned)time(NULL));
    int arr1[MAX];
    for(int i=0;i<MAX;i++)
    {
        arr1[i]=rand()%100;
    }
    print(arr1,MAX);
    merge_sort(arr1,MAX);
    print(arr1,MAX);
    //5 1 2 3 4 6 9 7 10 8
    // int arr[]={6,1,2,7,9,3,4,5,10,8};
    // int sz=sizeof(arr)/sizeof(arr[0]);
    // merge_sort(arr,sz);
    // print(arr,sz);
    return 0;
}

如有不对希望读者指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值