【C语言】编程初学者入门训练(14)

文章介绍了如何使用C语言实现基于结构体和指针的单向链表,包括创建、插入和删除节点的操作。同时,展示了如何用面向对象技术定义一个电子日历类TDate,包括构造函数和输出日期的方法。此外,还提供了两种不同规模的圣诞树打印算法,用于在控制台生成不同高度的圣诞树图案。
摘要由CSDN通过智能技术生成

131. kiki学结构体和指针

  • 问题描述:KiKi学习了结构体和指针,他了解了结构体类型可以定义包含多个不同类型成员,而指针本质是内存地址,是引用数据的另外一种方式。现在他想将多个输入的数据通过结构体和指针的方式连接在一起,形成一个单向链表,即:每个结点是结构体类型,包括整型数据成员(data)和结构体指针类型成员(next),每个结点的指针部分指向下一个输入的结点。具体建立过程如下:先输入n个整数,按照数据输入的顺序建立一个带头结点的单链表,再输入一个数据m,将单链表中的值为m的结点全部删除。输出删除后的单链表信息。

  • 输入描述:包括三行:

    • 第一行输入数据个数n (3≤n≤100);
    • 第二行依次输入n个整数,用空格分隔;
    • 第三行输入欲删除数据m。
  • 输出描述:包括两行:

    • 第一行输出完成删除后的单链表长度;
    • 第二行依次输出完成删除后的单链表数据。
  • 示例

输入:5
	1 2 2 3 4
	2
输出:3
	1 3 4
  • 代码实现:
#include <stdio.h>
#include <stdlib.h>

//链表结点的定义
struct Node
{
	int data;//数据域
	struct Node* next;//指针域
};

int main()
{	
	int n,i;
	scanf("%d",&n);
	struct Node* list = NULL;//指向链表的指针
	struct Node* tail = NULL;//指向链表尾部元素的指针	

	//接收n个数字,并尾部插入到单链表中	
	for(i = 0;i < n;i++)
	{
		int m = 0;
		scanf("%d",&m);
		struct Node* n = (struct Node*)malloc(sizeof(struct Node));
		n -> data = m;//往数据域存
		n -> next = NULL;

		if(NULL == list)//插入第一个元素
		{
			list = n;
			tail = list;//让尾指针指向当前结点
		}
		else//插入其他元素
		{
			tail -> next = n;//将下一个结点的地址赋尾指针的next域
			tail = tail -> next;//然后让尾指针指向下一个结点
		}
	}
	//获取要删除的元素
	int del;//要删除的元素
	scanf("%d",&del);//接收要删除的元素

	//删除链表中指定的元素
	struct Node* cur  = list;
	struct Node* prev = NULL;

	while(cur)
	{
		//找到了要删除的元素
		if(del == cur -> data)
		{
			//如果要删除的是第一个结点
			struct Node* pd = cur;//要先存着被删除的结点,防止找不到地址
			if(cur == list)
			{
				list = list -> next;//让list直接指向下一个结点
				cur = list;
			}
			else//删除的不是第一个结点
			{
				prev -> next = cur -> next;
				cur = prev -> next;
			}
			free(pd);
			n-- ;//删除了一个元素长度就变小一点
		}
		else//找不到
		{
			prev = cur;//prev始终记录cur指针的前一个结点的位置
			cur = cur -> next;
			//没找到自然是让指针指向下一个结点继续找
		}
	}
	printf("%d\n",n);//删除了结点之后的单链表长度
	
	//输出完成单链表删除操作后的单链表数据
	cur = list;//找到链表的起始位置
	while(cur)//知道cur变成空指针为止
	{
		printf("%d ",cur -> data);
		cur = cur -> next;
	}
	
	//释放链表-从头往后释放
	cur = list;
	struct Node* d = NULL;
	while(cur)
	{
		d = cur;
		cur = cur -> next;
		free(d);
	}

	list = NULL;//变成空链表了
	
	return 0;
}

132. kiki定义电子日历类

  • 问题描述:KiKi学习了面向对象技术,学会了通过封装属性(变量)和行为(函数)定义类,现在他要设计一个电子日历类TDate。
    它有3个私有数据成员:Month,Day,Year和若干个公有成员函数,要求:
    1. 带有默认形参值的构造函数,默认值为0, 0, 0;
    2. 输出日期函数,用“日/月/年”格式输出日期;
    3. 设置日期函数,从键盘输入年、月、日。
  • 输入描述:一行,三个整数,用空格分隔,分别表示年、月、日。
  • 输出描述:一行,用“日/月/年”格式输出日期。
  • 示例
    • 输入:2019 12 30
    • 输出:30/12/2019
  • 代码实现
#include <iostream>
using namespace std;
class TDate
{
private:
    int Year;
    int Month;
    int Day;
public:
    TDate(int year=0, int month=0, int day = 0)
   {
        Year = year;
        Month = month;
        Day = day;
   }
    void Print()
   {
        cout<<Day<<"/"<<Month<<"/"<<Year<<endl;
   }
};
int main()
{
    int year = 0;
    int month = 0;
    int day = 0;
    cin>>year>>month>>day;
    TDate d(year, month, day);
    d.Print();
    return 0;
}

133. 圣诞树

  • 问题描述:今天是圣诞节,牛牛要打印一个漂亮的圣诞树送给想象中的女朋友,请你帮助他实现梦想。
  • 输入描述:输入圣诞树的高度h,1<=h<=100
  • 输出描述:输出对应的圣诞树
  • 示例1
输入:1
输出:
  *  
 * * 
* * *
  *

说明:

在这里插入图片描述

  • 示例2
输入:2
输出:
     *     
    * *    
   * * *   
  *     *  
 * *   * * 
* * * * * *
     *
     *

说明:

在这里插入图片描述

  • 示例3
输入:3
输出:
        *  
       * * 
      * * *
     *     *  
    * *   * * 
   * * * * * *
  *     *     *  
 * *   * *   * * 
* * * * * * * * *
        *
        *
        *

说明:

在这里插入图片描述

  • 代码实现
#include <stdio.h>
int main()
{
    int num;
    scanf("%d",&num);
    
    for(int i = 1; i <= 3 * num; i++)
    {
        for(int j = 0; j < 3 * num - i; j++)
        {
            printf(" ");
        }
        int cnt = 0;
        for(int k = 0; k < ((i + 2) / 3); k++)
        {
            if(i % 3 == 0)
            {
                cnt = 3;
            }
            else 
            {
                cnt = i % 3;
            }
            for(int p = 0; p < cnt; p++)
            {
                printf("* ");
            }
            for(int p = 0; p < 3 - cnt; p++)
            {
                printf("  ");
            }
        }        
        printf("\n"); 
    }
    for(int i = 0; i < num; i++)
    {
        for(int j = 0; j < 3 * num - 1; j++)
        {
            printf(" ");
        }
        printf("*\n");
    }
    return 0;
}

134. 超级圣诞树

  • 问题描述:今天是圣诞节,牛牛要打印一个漂亮的圣诞树送给想象中的女朋友,请你帮助他实现梦想。
    输入描述:输入圣诞树的大小 1≤n≤8
  • 输出描述:输出对应的圣诞树
  • 示例1
输入:1
输出:
  *
 * *
* * *
  *

说明:

在这里插入图片描述

  • 示例2
输入:2
输出:
     *
    * *
   * * *
  *     *
 * *   * *
* * * * * *
     *
     *

说明:

在这里插入图片描述

  • 示例3
输入:3
输出:
           *
          * *
         * * *
        *     *
       * *   * *
      * * * * * *
     *           *
    * *         * *
   * * *       * * *
  *     *     *     *
 * *   * *   * *   * *
* * * * * * * * * * * *
           *
           *
           *

说明:

在这里插入图片描述

  • 示例4
输入:4
输出:
                       *
                      * *
                     * * *
                    *     *
                   * *   * *
                  * * * * * *
                 *           *
                * *         * *
               * * *       * * *
              *     *     *     *
             * *   * *   * *   * *
            * * * * * * * * * * * *
           *                       *
          * *                     * *
         * * *                   * * *
        *     *                 *     *
       * *   * *               * *   * *
      * * * * * *             * * * * * *
     *           *           *           *
    * *         * *         * *         * *
   * * *       * * *       * * *       * * *
  *     *     *     *     *     *     *     *
 * *   * *   * *   * *   * *   * *   * *   * *
* * * * * * * * * * * * * * * * * * * * * * * *
                       *
                       *
                       *
                       *

说明:

在这里插入图片描述

  • 解题思路:实在搞不定,看的题解。
    1. 定义二维数组ch[最大行数][最大列数],并初始化为n=1时的内容char ch[400][800] = {" * ", " * * ", “* * *”},还有现在三角的行数row=3,列数col=5

    2. 最外层循环 n-1 次。

    3. 将现在的三角复制到左下角和右下角。

    4. 清除原来左上角的三角。

    5. 将左下角的三角复制到上一层的中间位置。

    6. 设置新三角的行数row=row*2,列数col=col*2+1,完成了一次循环,跳到第2步。

    7. 根据row和col打印出来。

    8. 打印树干。

  • 代码实现
#include <stdio.h>
int main() {
    int n;
    scanf("%d", &n);
    int i, j, k;
    int row = 3;
    int col = 5;
    // 行数 = 3 * pow(2,n-1) 列数 = 5 * pow(2,n-1)
    char ch[400][800] = {"  *  ", " * * ", "* * *"};
    for (i = 0; i < n - 1; i++) {
        for (j = 0; j < row; j++) {
            for (k = 0; k < col; k++) {
                ch[j + row][k] = ch[j][k]; // 左下角的图形复制
                ch[j + row][k + 1 + col] = ch[j][k];
            }
        }
        // 清空原来的三角位置
        for (j = 0; j < row; j++) {
            for (k = 0; k < col; k++)
                ch[j][k] = ' ';
        }
        // 将左下角的三角复制到两个中间去
        for (j = 0; j < row; j++) {
            for (k = 0; k < col; k++)
                ch[j][k + row] = ch[j + row][k];
        }
        row *= 2;           // 当前的行数
        col = col * 2 + 1;  // 当前的列数
    }
    // 打印出来
    for (j = 0; j < row; j++) {
        for (k = 0; k < col; k++) {
            if (ch[j][k] == '*')
                printf("%c", ch[j][k]);
            else
                printf(" ");
        }
        printf("\n");
    }
    // 打印树干
    for (j = 0; j < n; j++) {
        for (k = 0; k < row - 1; k++)
            printf(" ");
        printf("*\n");
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值