C语言中的自定义排序原则 1177: 按要求排序(指针专题)

问题描述

1177: 按要求排序(指针专题)
时间限制: 1 Sec 内存限制: 128 MB
提交: 4896 解决: 2286

输入n和n个整数,然后按要求排序,若输入1,请输出升序排序序列;若输入2,请输出降序排序序列,若输入3,请输出按绝对值升序排序序列。要求程序结构如下,请完善程序。

void sort(int a[], int n, int (*cmp)());
int CmpAsc(int x, int y); /按升序要求判断两元素是否逆序/
int CmpDec(int x, int y); /按降序要求判断两元素是否逆序/
int CmpAbsAsc(int x, int y); /按绝对值升序要求判断两元素是否逆序/
int main(void)
{
int a[10],i,n;
int slt;

/读入n和n个整数,存入数组a/

/*读入用户的选择,存入slt; */

switch(slt)

{
case 1: sort(a, n, CmpAsc); break;
case 2: sort(a, n, CmpDec); break;
case 3: sort(a, n, CmpAbsAsc);break;
}

/输出排序后的数组/

}

void sort(int a[], int n, int (*cmp)())
{
/对数组a排序,排序原则由cmp指定,若cmp为真,表示两元素逆序/

}

int CmpAsc(int x, int y)
{
//如果x>y返回1,否则返回0;

}

int CmpDec(int x, int y)
{
//如果x<y返回1,否则返回0;
}

int CmpAbsAsc(int x, int y)
{

//如果abs(x)>abs(y)返回1,否则返回0
}

输入
输入第一行是一个正整数n;

输入第二行是n个整数;

输入第三行是一个1~3的整数slt,表示用户的排序要求。

输出
输出n个整数。若用户的排序选择是1,则输出升序排序后的n个整数;若用户的排序选择是2,则输出降序排序后的n个整数;若用户的排序选择是3,则输出按绝对值升序排序后的n个整数;输出占一行,数据之间用空格隔开。

样例输入 Copy
5
2 -3 1 5 4
2
样例输出 Copy
5 4 2 1 -3
提示
请采用稳定的排序算法

代码&注释

#include <iostream>
#include <cmath> // 使用 abs 函数 或者 fabs函数(浮点数绝对值)

void sort(int a[], int n, int (*cmp)(int x, int y));
int CmpAsc(int x, int y); /*按升序要求判断两元素是否逆序*/
int CmpDec(int x, int y); /*按降序要求判断两元素是否逆序*/
int CmpAbsAsc(int x, int y);  /*按绝对值升序要求判断两元素是否逆序*/
int main(void)
{
    using namespace std;
    int * a, n;
    int slt;
    /*读入n和n个整数,存入数组a*/
    cin >> n;
    a = new int [n];
    for ( int i = 0; i < n; i++ ) {
        cin >> a[i];
    }
    /*读入用户的选择,存入slt; */
    cin >> slt;
// 若输入1,请输出升序排序序列;
// 若输入2,请输出降序排序序列,
// 若输入3,请输出按绝对值升序排序序列。要求程序结构如下,请完善程序。
    switch(slt)
    {
        case 1:   sort(a, n, CmpAsc); break;
        case 2:   sort(a, n, CmpDec); break;
        case 3:   sort(a, n, CmpAbsAsc);break;
    }
    /*输出排序后的数组*/
    for ( int i = 0; i < n - 1; i++ ) {
        cout << a[i] << " ";
    }
    cout << a[n - 1];
    // 释放内存
    delete [] a;
    return 0;
}

void sort(int a[], int n, int (*cmp)(int x, int y))
{
    /*对数组a排序,排序原则由cmp指定,若cmp为真,表示两元素逆序*/
    for (int i = 0; i < n - 1; i++) {           // 简单选择排序
        int k = i;
        for (int j = i + 1; j < n; j++) {
            if (cmp(a[k], a[j])) {
                k = j;
            }
        }
        int temp;
        temp = a[i]; a[i] = a[k]; a[k] = temp;
    }
}

int CmpAsc(int x, int y)
{
    //如果x>y返回1,否则返回0;
    if ( x > y ) return 1;
    return 0;
}

int CmpDec(int x, int y)
{
    //如果x<y返回1,否则返回0;
    if ( x < y ) return 1;
    return 0;
}

int CmpAbsAsc(int x, int y)
{
//如果abs(x)>abs(y)返回1,否则返回0
    if ( abs(x) > abs(y) ) return 1;    //abs头文件不是math.h而是stdlib.h 。 在C++中,只需要包括cmath即可。
    else if ( x + y == 0 && x > y) return 1; // 绝对值相同
    return 0;
}

补充 abs 函数知识

C语言中,
求整数的绝对值abs()labs()应该包含stdlib.h
求浮点数的绝对值fabs()应该包含math.h
在C++中,
只需要包括cmath即可。

C标准:

只在 stdlib.h 中有定义abs():
int abs (int n);

C++标准:

在stdlib.h中
     int abs (     int n);
long int abs (long int n);
在math.h中
     double abs (double x);
      float abs (float x);
long double abs (long double x);

参考网站:
=> C++参考网站

总结

忘了考虑绝对值相等的情况
本例中 int (* cmp)(int x, int y) 作为一个参数很特别。它有点像一个抽象函数?
这里它有一个整数返回值,通过这个值判断是否逆序(和期望的排序是否相同)。

备注

这里的 sort 是个人定义的。

void sort(int a[], int n, int (*cmp)(int x, int y))
{
    /*对数组a排序,排序原则由cmp指定,若cmp为真,表示两元素逆序*/
    for (int i = 0; i < n - 1; i++) {           // 简单选择排序
        int k = i;
        for (int j = i + 1; j < n; j++) {
            if (cmp(a[k], a[j])) {
                k = j;
            }
        }
        int temp;
        temp = a[i]; a[i] = a[k]; a[k] = temp;
    }
}

对比下列函数

void sort(int a[], int n, int (*cmp)(int x, int y));
int (*cmp)(int x, int y);
 // 上面的 cmp 函数和下面三个函数的传入参数,返回值类型 一模一样,
 // 不同的地方除了名字(>.<)外,就是 多了一颗 *
int CmpAsc(int x, int y); /*按升序要求判断两元素是否逆序*/
int CmpDec(int x, int y); /*按降序要求判断两元素是否逆序*/
int CmpAbsAsc(int x, int y);  /*按绝对值升序要求判断两元素是否逆序*/

而上面三个函数也有相同点,比如参数列标,返回值(类型)
不同点就是具体实现不一样,或者说比较的原则不一样:

int CmpAsc(int x, int y)
{
    //如果x>y返回1,否则返回0;
    if ( x > y ) return 1;
    return 0;
}

int CmpDec(int x, int y)
{
    //如果x<y返回1,否则返回0;
    if ( x < y ) return 1;
    return 0;
}

int CmpAbsAsc(int x, int y)
{
//如果abs(x)>abs(y)返回1,否则返回0
    if ( abs(x) > abs(y) ) return 1;    //abs头文件不是math.h而是stdlib.h 。 在C++中,只需要包括cmath即可。
    else if ( x + y == 0 && x > y) return 1; // 绝对值相同
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值