排序专题

 

1,选择排序

#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,5,6,1,9,8,7};
//默认升序排序
void solve()
{
    for(int i=0;i<10;i++)
    {
        int index=i;
        for(int j=i+1;j<10;j++)
        {
            if(a[j]<a[index])
            {
                index=j;     //找到I位置以后的最小数字对应的下标
            }
        }
        if(i!=index)         //如果当前位置不满足要求,也就是说后面的数字中有比当前数字小的数字存在,就进行交换
        {
            int temp=a[i];
            a[i]=a[index];
            a[index]=temp;
        }
    }
}
int main()
{
    solve();
    for(int i=0;i<10;i++)
    {
        cout<<a[i]<<" ";
    }
    return 0;
}

2,插入排序

理解:执行第i次循环的时候,默认的是0~i-1这个区间内的数字已经有序,然后用第i个位置的数字去与这些区间内的数字进行比较。比较的过程类似于冒泡。

#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,5,6,1,9,8,7};
//默认升序排序
void solve()
{
    for(int i=0;i<10;i++)
    {
        for(int j=i-1;j>=0;j--)
        {
            if(a[j+1]<a[j])
                swap(a[j+1],a[j]);         //本质上就是用i位置的数字去跟0~i-1之间内数字进行比较,如果a[i]小,那就直接就换。
            else
                break;
        }
    }
}
int main()
{
    solve();
    for(int i=0;i<10;i++)
    {
        cout<<a[i]<<" ";
    }
    return 0;
}

3,冒泡排序

#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,5,6,1,9,8,7};
//默认升序排序
void solve()
{
    for(int i=0;i<10;i++)
    {
        for(int j=0;j<10-i-1;j++)
        {
            if(a[j]>a[j+1])
            {
                swap(a[j],a[j+1]);   //大的数字往后移动
            }
        }
    }
}
int main()
{
    solve();
    for(int i=0;i<10;i++)
    {
        cout<<a[i]<<" ";
    }
    return 0;
}

4,希尔排序

理解:通过对数组进行分组,对每一个分组进行插入排序,这样的算法复杂度有所提高。

#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,6,5,9,1,8,7};
int b[100];   //辅助数组,用来存储子数组
//默认升序排序
void solve()
{
    int len=10;
    int dis=10;
    do
    {
        dis=dis/3+1;     //设置的划分组数的大小
        for(int i=0;i<len;i++)
        {
            int index=0;
            for(int j=i;j<len;j+=dis)
            {
                b[index++]=a[j];
            }
            //使用插入排序对b[]进行排序
            for(int k=0;k<index;k++)
            {
                for(int j=k-1;j>=0;j--)
                {
                    if(b[j+1]<b[j])
                        swap(b[j+1],b[j]);
                    else
                        break;
                }
            }
            index=0;
            //将排好序的子数组复制到原数组当中
            for(int j=i;j<len;j+=dis)
            {
                a[j]=b[index++];
            }
        }

    }while(dis>1);  //当划分的组的大小为1的时候,排序结束。
}
int main()
{
    solve();
    for(int i=0;i<10;i++)
    {
        cout<<a[i]<<" ";
    }
    return 0;
}

5,归并排序

#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,6,5,9,1,8,7};
int b[100];//辅助数组
int len=10;
//默认升序排序
void mergsort(int l,int mid,int r)
{
    int i=l;
    int j=mid+1;
    int index=0;
    while(i<=mid&&j<=r)
    {
        if(a[i]<a[j])
            b[index++]=a[i++];
        else
            b[index++]=a[j++];
    }
    while(i<=mid)
    {
        b[index++]=a[i++];
    }
    while(j<=r)
    {
        b[index++]=a[j++];
    }
    index=0;
    for(int i=l;i<=r;i++)     //把排好序的子数组复制到原数组中
    {
        a[i]=b[index++];
    }
}
void solve(int l,int r)
{
    if(l<r)
    {
        solve(l,(l+r)>>1),       //划分左区间
        solve(((l+r)>>1)+1,r);   //划分右区间
        mergsort(l,(l+r)>>1,r);  //对左右区间进行排序
    }

}
int main()
{
    solve(0,9);
    for(int i=0;i<10;i++)
    {
        cout<<a[i]<<" ";
    }
    return 0;
}

6,快速排序

理解:快排没排序一次,就确定了一个数字最终的位置。

 

#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,6,5,9,1,8,7};
int b[100];
int len=10;
int mergesort(int l,int r)
{
    int i=l;
    int j=r;
    int val=a[l];
    while(i<j)
    {
        while(a[j]>=val&&j>i)    //从后往前找到一个比a[l]小的数字
            j--;
        a[i]=a[j];
        while(a[i]<=val&&i<j)    //从前往收找到一个比a[l]大的数字
            i++;
        a[j]=a[i];              //交换
    }
    a[i]=val;
    return i;
}
void solve(int l,int r)
{
    if(l<r)
    {
        int pos=mergesort(l,r);
        //cout<<pos<<endl;
        solve(l,pos-1);             //对于快排来说,每排序一次,就确定了一个数字最终的位置
        solve(pos+1,r);
    }
}
int main()
{
    solve(0,9);
    for(int i=0;i<10;i++)
    {
        cout<<a[i]<<" ";
    }
    return 0;
}


7,堆排序

理解:大顶堆对应着升序,反之小顶堆对应着降序。

#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,6,5,9,1,8,7};
int b[100];
int len=10;
void res(int x,int length)
{
    int temp=a[x];
    for(int k=x*2+1;k<length;k=k*2+1)     //此处的k=k*2+1解析:有人会有疑问:就是在程序中如果右节点比左节点大的话,那么k就++,然后此处有k=k*2+1,那么左子树下的节点就不管了吗?答案是肯定的,你可以从最初构造大顶堆的过程中看,他是从下往上构造的,这个性质就决定了如果当前左子树节点比右子树节点小的话,就没有必要遍历左子树下的节点了。你可以画一下就知道了。
    {
        if(a[k]<a[k+1]&&(k+1)<length)     //如果右孩子比左孩子大,由于是大顶堆所以是右节点
            k++;                          
        if(a[k]>temp)
        {
            a[x]=a[k];
            x=k;
        }
        else
            break;                      //如果两个孩子都没有父亲节节点大的话,就没有必要在进行遍历左右子树了。因为构造是从下往上构造的。
    }
    a[x]=temp;
}
void out()
{
    for(int i=0;i<10;i++)
    {
        cout<<a[i]<<" ";
    }
}
void solve(int l,int r)
{
    for(int i=len/2-1;i>=0;i--)
        res(i,len);            //调整堆,使其最终成为大顶堆
    //out();
    //cout<<"****"<<endl;
    for(int i=len-1;i>0;i--)
    {
        swap(a[0],a[i]);     //每交换一次都要进行堆调整
        //out();
        //cout<<endl;
        res(0,i);
        //out();
        //cout<<endl;
    }
}
int main()
{
    solve(0,9);
    out();
    return 0;
}


8,计数排序

计数排序的基本思想为一组数在排序之前先统计这组数中其他数小于这个数的个数,则可以确定这个数的位置。例如要排序的数为 7 4 2 1 5 3 1 5;则比7小的有7个数,所有7应该在排序好的数列的第八位,同理3在第四位,对于重复的数字,1在1位和2位(暂且认为第一个1比第二个1小),5和1一样位于6位和7位。

#include <bits/stdc++.h>
using namespace std;
int a[10]= {0,3,2,4,6,5,9,1,8,7};
int sum[100];
int len=10;
void out()
{
    for(int i=0; i<10; i++)
    {
        cout<<a[i]<<" ";
    }
}
void solve()
{
    int c[100];
    int maxn=-1;
    for(int i=0; i<len; i++)
    {
        maxn=max(a[i],maxn);     //找到最大值,目的为了开辟b数组的空间
    }
    //cout<<maxn<<endl;
    int b[maxn*2];
    memset(b,0,sizeof(b));
    for(int i=0; i<len; i++)
    {
        b[a[i]]++;              //统计每个数字的次数
    }
    for(int i=0; i<maxn+1; i++)
    {
        if(i==0) continue;
        b[i]=b[i]+b[i-1];       //统计数组中的数字比其小的数字的个数。
    }

    for(int i=0;i<len;i++)
    {
        b[a[i]]--;               //下标从0开始所以要 -1
        c[b[a[i]]]=a[i];         //c数组是个辅助数组。
    }
    for(int i=0;i<len;i++)
        a[i]=c[i];
}
int main()
{
    solve();
    out();
    return 0;
}



 

9,桶排序

后续更新。

10,基数排序

理解:就是把数组中的数字按个位,十位...最高位,每次按位去比较数组中的数字。

#include <bits/stdc++.h>
using namespace std;
void printArray(int array[],int length)
{

    for (int i = 0; i < length; ++i)
    {
        cout << array[i] << " ";
    }
    cout << endl;
}
int maxbit(int data[], int n)
{
    int d = 1;
    int p = 10;
    for(int i = 0; i < n; ++i)
    {
        while(data[i] >= p)
        {
            p *= 10;
            ++d;
        }
    }
    return d;
}
void radixsort(int data[], int n)
{
    int d = maxbit(data, n);
    int tmp[n];
    int count[10];
    int i, j, k;
    int radix = 1;
    for(i = 1; i <= d; i++)
    {
        for(j = 0; j < 10; j++)
            count[j] = 0;
        for(j = 0; j < n; j++)
        {
            k = (data[j] / radix) % 10;
            count[k]++;
        }
        for(j = 1; j < 10; j++)
            count[j] = count[j - 1] + count[j]; 
        for(j = n - 1; j >= 0; j--) 
        {
            k = (data[j] / radix) % 10;
            tmp[count[k] - 1] = data[j];
            count[k]--;
        }
        for(j = 0; j < n; j++) 
            data[j] = tmp[j];
        radix = radix * 10;
    }
}
int main()
{
    int array[10] = {0,2,3,6,9,1,4,5,7,8};
    radixsort(array,10);
    printArray(array,10);
    return 0;
}


 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,结构体排序练习通常涉及到如何使用标准库中的算法对包含自定义数据类型的结构体数组或容器进行排序。这里我们可以举一个简单的例子,假设有一个名为`Student`的结构体,包含`name`和`age`两个成员: ```cpp struct Student { std::string name; int age; }; ``` 你可以用以下几种方法对`Student`结构体数组进行排序: 1. **直接排序:**如果年龄是排序的主要依据,你可以定义一个比较函数(`compare`),然后使用`std::sort`函数: ```cpp bool compareStudents(const Student& s1, const Student& s2) { return s1.age < s2.age; } int main() { Student students[] = {{"Alice", 20}, {"Bob", 18}, {"Charlie", 22}}; std::sort(students, students + sizeof(students) / sizeof(students), compareStudents); // 现在students数组按年龄升序排列 } ``` 2. **使用STL算法:**如果你的结构体已经实现了`<`运算符,那么可以直接使用`std::stable_sort`: ```cpp bool studentLess(const Student& s1, const Student& s2) { return s1.age < s2.age; } int main() { std::vector<Student> students = {{"Alice", 20}, {"Bob", 18}, {"Charlie", 22}}; std::stable_sort(students.begin(), students.end(), studentLess); } ``` 3. **自定义比较器(C++11及以上):**也可以使用lambda表达式来创建一个可传递的比较器: ```cpp int main() { std::vector<Student> students = {{"Alice", 20}, {"Bob", 18}, {"Charlie", 22}}; std::sort(students.begin(), students.end(), [](const Student& s1, const Student& s2) { return s1.age < s2.age; }); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值