排序(后续部分)

目录

1.基数排序

2.归并排序

3.堆排序 


写在前面:

 没写到的就直接sort吧(bushi),本人蒟蒻,大佬%%%%。

发文助手也太狠了吧,动不动。。。。


1.基数排序


#include<bits/stdc++.h>
using namespace std;
const int MAX=1e+6;
typedef long long ll;
ll a[MAX];
void scnf(int st,int n)
{
    for(int i=1; i<=n; i++)cin>>a[i];
}
void print(int st,int n)
{

    for(int i=st; i<=n; i++)cout<<a[i]<<" ";


}
int big(ll n)//寻找所给数据的最大位数
{
    ll maxx=-1;
    for(int i=1; i<=n; i++)maxx=max(maxx,a[i]);
    if(maxx==0)return 1;
    else
    {
        int ji=0;
        while(maxx)
        {
            maxx/=10;
            ji++;
        }
        return ji;


    }


}
int tmp[MAX],ji[10];
void jipai(int n)
{
    int d=big(n);
    int radix=1;
    while(d--)
    {
        for(int j=0; j<10; j++)ji[j]=0;
        for(int j=1; j<=n; j++)
        {
            int k=(a[j]/radix)%10;
            ji[k]++;//用名为ji的桶子来装某位是k的数字
        }
        for(int j=1; j<10; j++)ji[j]=ji[j-1]+ji[j];//将桶子连起来(即所谓1-n拼起来了,建议结合原理图)
        for(int j=n; j>0; j--)//将数据存入桶子时,最后入的是后面出现的数据,“--”操作也是后面数据先出现,所以从n开始
        {
            int k=(a[j]/radix)%10;
            tmp[ji[k]]=a[j];
            ji[k]--;
        }
        for(int j=1; j<=n; j++)a[j]=tmp[j];
        radix*=10;
    }

}
int main()
{
    int n;
    cin>>n;
    scnf(1,n);
    jipai(n);
    print(1,n);
}

2.归并排序


#include<bits/stdc++.h>
using namespace std;
const int MAX=1e+6;
typedef long long ll;
ll a[MAX];
int temp[MAX];
void scnf(int st,int n)
{

    for(int i=1; i<=n; i++)cin>>a[i];
}
void print(int st,int n)
{

    for(int i=st; i<=n; i++)cout<<a[i]<<" ";


}
void Merge(int l1,int r1,int l2,int r2)
{
    int i=l1,j=l2;
    int index=0;
    while(i<=r1&&j<=r2)
    {
        if(a[i]<=a[j])temp[index++]=a[i++];
        else temp[index++]=a[j++];
    }
    while(i<=r1)temp[index++]=a[i++];
    while(j<=r2)temp[index++]=a[j++];
    for(int i=0; i<index; i++)a[l1+i]=temp[i];

}
void MergeSort(int l,int r)
{
    if(l<r)
    {
        int mid=(l+r)/2;
        MergeSort(l,mid);
        MergeSort(mid+1,r);
        Merge(l,mid,mid+1,r);


    }

}

int main()
{
    int n;
    cin>>n;
    scnf(1,n);
    MergeSort(1,n);
    print(1,n);




}

3.堆排序 


#include<bits/stdc++.h>
using namespace std;
const int MAX=1e+6;
typedef long long ll;
ll a[MAX];
void scnf(int st,int n)
{

    for(int i=1; i<=n; i++)cin>>a[i];
}
void print(int st,int n)
{

    for(int i=st; i<=n; i++)cout<<a[i]<<" ";


}
void HeapAdjust(int s,int m)
{
    int jc=a[s];
    for(int j=2*s; j<=m; j*=2)
    {
        if(j<m&&a[j]<a[j+1])j++;
        if(jc>=a[j])break;
        a[s]=a[j];
        s=j;


    }
    a[s]=jc;


}
void heapsort(int n)
{
    int te;
    for(int i=n/2; i>0; i--)HeapAdjust(i,n);
    for(int i=n; i>1; i--)
    {
        te=a[i];
        a[i]=a[1];
        a[1]=te;
        HeapAdjust(1,i-1);


    }

}
int main()
{
    int n;
    cin>>n;
    scnf(1,n);
    heapsort(n);
    print(1,n);




}

 

好的,下面我来为您**详细讲解这段代码中排序边长的逻辑**,也就是 `sort_sides` 函数部分。这部分代码用于将输入的三个整数 `a`, `b`, `c` 排序为 `a <= b <= c`,以便后续用于判断三角形类型(如直角、锐角、钝角)时能正确比较最大边与其余两边的关系。 --- ### 🧩 原始代码中的排序逻辑分析 ```c int a,b,c,m1,m2,max; if(a>b){ if(a>c){ max=a; m1=b; m2=c; }else{ max=c; m1=a; m2=b; } }else if(b>c){ max=b; m1=a; m2=c; }else{ max=c; m1=b; m2=a; } ``` 这段逻辑的目的是找出三条边中最大的一个(`max`),并将剩下的两个边分别赋值给 `m1` 和 `m2`。但这种方式: - **不够直观**,容易出错; - **不便于后续使用**,比如判断等腰或等边三角形时还需重新比较; - **逻辑复杂**,嵌套条件判断容易漏掉某些情况。 --- ### ✅ 改进后的排序函数 `sort_sides` 详解 ```c // 辅助函数:交换两个整数的值 void swap(int *x, int *y) { int temp = *x; *x = *y; *y = temp; } // 排序边长 void sort_sides(int *a, int *b, int *c) { if (*a > *b) swap(a, b); if (*b > *c) swap(b, c); if (*a > *b) swap(a, b); } ``` #### 1. 函数目的: 将三个边从小到大排序,使得最终 `*a <= *b <= *c`。 #### 2. 工作流程: - **第一次比较 `a` 和 `b`**:如果 `a > b`,交换它们,确保 `a <= b`。 - **第二次比较 `b` 和 `c`**:如果 `b > c`,交换它们,确保 `b <= c`。 - **第三次比较 `a` 和 `b`**:由于上一步可能改变了 `b` 的值,再次检查是否 `a > b`,如果成立,再次交换。 这个过程相当于**冒泡排序**,将三个数排好序。 #### 3. 示例说明: 假设输入为:`a = 3`, `b = 1`, `c = 2` - 第一次:`a > b` → 交换 → `a=1, b=3, c=2` - 第二次:`b > c` → 交换 → `a=1, b=2, c=3` - 第三次:`a <= b` → 不交换 最终:`a=1, b=2, c=3` --- ### 🧠 总结排序函数的优点 | 原方法(手动比较) | 新方法(排序函数) | |------------------|------------------| | 逻辑复杂,易出错 | 逻辑清晰,结构化 | | 无法复用 | 可封装成函数,复用性强 | | 难以维护 | 易于调试和维护 | | 不利于后续判断 | 有利于判断三角形类型、等腰、等边等 | --- ### 🔍 应用场景举例 排序后可以很方便地: - 判断是否是直角三角形:只需判断 `a² + b² == c²` - 判断是否是锐角三角形:`a² + b² > c²` - 判断是否是钝角三角形:`a² + b² < c²` - 判断是否是等腰三角形:只需判断 `a == b || b == c` - 判断是否是等边三角形:`a == b == c` --- ### 📌 总结知识点 1. **冒泡排序思想** 使用三次两两比较和交换,实现对三个数的排序。 2. **指针操作** 使用指针 `int *x` 作为函数参数,可以直接修改主函数中的变量值。 3. **交换函数设计** 使用 `swap` 函数封装交换逻辑,提升代码复用性和可读性。 --- 如您有更多关于排序逻辑或其他代码部分的疑问,欢迎继续提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值