C语言数字金字塔实训

前言

无套路,均已上机通过,求个关注求个赞,提供答疑解惑服务。

功能

编写程序,输入一个正整数n,构造一个正整数的数字金字塔。例如对n=6,数字金字塔如下:

1
2 3 5
4 6

数字金字塔构造规则如下:

  • 1在最上方第0层
  • 如果x大于y并且x除以y 的余数为О(即 x>y && x%y = = 0),x要放在y下方一层(即若y在第i层,x应在i+1层);
  • 每个数应尽可能放在更下方,即如果可以放在第i层,就不能放在i-1层;
  • 相同层上的数从左向右从小到大排列。每个数按照它在塔中的位置从上到下从左到右从1开始编号,例如数5的序号为4。

运行截图

在这里插入图片描述

所有代码

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

/**
 * 链表结点
 */
typedef struct Node {
    int data;
    struct Node *next;
} *Node;

/**
 * 获取插入数据的所在层数
 * 在获取层次时,从金字塔的最高层开始比较,如果找不到就递归到上一层查找,这样可以保证每个数插入到最大层
 * @param pyramid 数字金字塔
 * @param level 当前最大层级
 * @param data 插入的数据
 * @return 返回插入数据的所在层数
 */
int getLevel(Node pyramid[], int level, int data) {
    for (Node node = pyramid[level - 1]; node != NULL; node = node->next) {
        if (data > node->data && data % node->data == 0) {
            return level + 1;
        }
    }
    return getLevel(pyramid, level - 1, data);
}

/**
 * 插入数据
 * @param pyramid 数字金字塔
 * @param level 插入数据所在层数
 * @param data 插入数据
 */
void insertData(Node pyramid[], int level, int data) {
    Node node = malloc(sizeof(struct Node));
    node->data = data;
    node->next = NULL;
    //如果所在层次为空则直接插入,否则就寻找插入的位置,这个过程保证链表有序
    if (pyramid[level - 1] == NULL) {
        pyramid[level - 1] = node;
    } else {
        for (Node temp = pyramid[level - 1]; temp != NULL; temp = temp->next) {
            if (data > temp->data && (temp->next == NULL || temp->next->data > data)) {
                node->next = temp->next;
                temp->next = node;
                break;
            }
        }
    }
}

/**
 * 金字塔构造函数
 * @param pyramid 数字金字塔
 * @param n 输入n
 * @return 金字塔的最大层数
 */
int constructPyramid(Node pyramid[], int n) {
    int level = 1;
    //从1-n依次寻找每一个数的插入层次并插入
    for (int data = 1; data <= n; ++data) {
        //如果是1就直接插入到第一层,某则就先获取待插入数据所在的层次,然后再进行插入
        if (data == 1) {
            Node node = malloc(sizeof(struct Node));
            node->data = data;
            node->next = NULL;
            pyramid[level - 1] = node;
        } else {
            int insertLevel = getLevel(pyramid, level, data);
            insertData(pyramid, insertLevel, data);
            //如果插入元素在新的一层,金字塔的最大高度就+1
            if (insertLevel > level) {
                level++;
            }
        }
    }
    return level;
}

/**
 * 打印金字塔
 * @param pyramid 数字金字塔
 * @param level 金字塔的最大层数
 */
void printPyramid(Node pyramid[], int level) {
    for (int i = 1; i <= level; ++i) {
        for (Node node = pyramid[i - 1]; node != NULL; node = node->next) {
            printf("   %d", node->data);
        }
        printf("\n");
    }
}

/**
 * 打印排名
 * @param pyramid 数字金字塔
 * @param level 数字金字塔的最大层数
 * @param inputDataList 需要打印排名的数据
 */
void printRank(Node pyramid[], int level, int inputDataList[]) {
    printf("输出排名:\n");
    for (int i = 1; i <= 3; ++i) {
        int rank = 0;
        for (int j = 1; j <= level; ++j) {
            for (Node node = pyramid[j - 1]; node != NULL; node = node->next) {
                rank++;
                if (node->data == inputDataList[i]) {
                    printf("   %d,", rank);
                    break;
                }
            }
        }
    }
    printf("\n");
}

int main() {
    while (true) {
        int inputDataList[4] = {0};
        printf("输入信息:\n");
        for (int i = 0; i < 4; ++i) {
            //注意输入时的逗号是英文状态下的逗号
            scanf("%d,", inputDataList + i);
        }
        //金字塔的结构是一个数组,数组的每个元素代表一层,一层的多个元素用链表存储
        Node pyramid[10] = {NULL};
        int level = constructPyramid(pyramid, inputDataList[0]);
        printPyramid(pyramid, level);
        printRank(pyramid, level, inputDataList);
    }
    return 0;
}

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亻乍屯页女子白勺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值