C语言编程练习day15

1、有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数。(该题是昨天"C语言编程练习day14"的第二题,用两个数组来完成,今天用链表来做,思路更简单)
输入:10 4 (n个整数,前面各数顺序向后移m个位置)
0 1 2 3 4 5 6 7 8 9
输出在这里插入图片描述
优化目标:无
思路
在这里插入图片描述
调整结点链接的函数

/*
*改变结点链接
*@list:链表指针
*@m:要调整的最后m个元素
*/
void Change_ListLink(LinkList* list, int m){
	if(list == NULL || m < 0 || m > list->size){
		return;
	}
	
	//找到修改位置list->size - m,链接到头结点后面
	LinkNode* pCurrent = &(list->head);
	for(int i=0; i<=list->size - m; i++){
		pCurrent = pCurrent->next;
	}
	//找到链尾位置,把第一个数据元素链接到链尾
	LinkNode* pNext = &(list->head);
	for(int i=0; i<list->size; i++){
		pNext = pNext->next;
	}
	//修改位置
	pNext->next = list->head.next;
	list->head.next = pCurrent;
}

完整代码:

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

#define MAX_SIZE 1024

//链表结点
typedef struct LINKNODE{
	struct LINKNODE* next;
}LinkNode;

//链表
typedef struct LINKLIST{
	LinkNode head;
	int size;
}LinkList;

//自定义数据
typedef struct MYDATA{
	LinkNode data;
	int value;
}MyData;

//初始化和链表
LinkList* Init_LinkList(){
	LinkList* list = (LinkList*)malloc(sizeof(LinkList));
	list->head.next = NULL;
	list->size = 0;
	
	return list;
}

/*
*插入结点
*@list:链表指针
*@data:插入的数据
*/
void Insert_LinkList(LinkList* list, LinkNode* data){
	//判断参数的合法性
	if(list == NULL || data == NULL){
		return;
	}
	//找到插入位置,链尾
	LinkNode* pCurrent = &(list->head);
	for(int i=0; i<list->size; i++){
		pCurrent = pCurrent->next;
	}
	
	//插入结点,尾插
	data->next = pCurrent->next;
	pCurrent->next = data;
	
	list->size++;
}

/*
*改变结点链接
*@list:链表指针
*@m:要调整的最后m个元素
*/
void Change_ListLink(LinkList* list, int m){
	if(list == NULL || m < 0 || m > list->size){
		return;
	}
	
	//找到修改位置list->size - m,链接到头结点后面
	LinkNode* pCurrent = &(list->head);
	for(int i=0; i<=list->size - m; i++){
		pCurrent = pCurrent->next;
	}
	//找到链尾位置,把第一个数据元素链接到链尾
	LinkNode* pNext = &(list->head);
	for(int i=0; i<list->size; i++){
		pNext = pNext->next;
	}
	//修改位置
	pNext->next = list->head.next;
	list->head.next = pCurrent;
}

/*
*打印
*@list:链表指针
*/
void MyPrint(LinkList* list){
	LinkNode* pNext = list->head.next;
	for(int i=0; i<list->size; i++){
		MyData* data = (MyData*)pNext;
		printf("%d ", data->value);
		pNext = pNext->next;
	}
}
/*
*链表销毁
*@list:链表指针
*/
void FreeSpace_LinkList(LinkList* list){
	//判断参数的合法性
	if(list == NULL){
		return;
	}
	free(list);
}
int main(){
	int n, m;
	scanf("%d%d", &n, &m);
	MyData num[MAX_SIZE];
    //初始化链表
    LinkList* list = Init_LinkList();
    
    for(int i=0; i<n; i++){
    	//输入n个要调整的数
    	scanf("%d", &num[i].value);
    	//插入数据
    	Insert_LinkList(list, (LinkNode*)&num[i]);
	}

    //打印数据,修改位置前
    MyPrint(list);
	//修改位置
	Change_ListLink(list, m);
	printf("\n");
    //打印数据,修改位置后
    MyPrint(list);
    //释放空间
    FreeSpace_LinkList(list);
	
	return 0;
}

2、输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出fu字。十个数字对应的拼音如下:
在这里插入图片描述
输入:输入在一行中给出一个整数,如:1234。
输出:在一行中输出这个整数对应的拼音,每个数字的拼音之间用空格分开,行末没有最后的空格。如 yi er san si。
优化目标:无


```c
#include <stdio.h>
#include <string.h>

#define MAX 1024

/*
*打印结果函数
*@n:需要读的数
*@num:存放n取出的每一位
*/
void test(int n, int* num){
	int i = 0;
    while(n > 0){
        int k = n % 10;
        num[i] = k;
        i++;
        n = n / 10;
    }
    for(int j=i-1; j>=0; j--){
    	if(num[j] == 0){
    		printf("ling");
		}else if(num[j] == 1){
			printf("yi");
		}else if(num[j] == 2){
			printf("er");
		}else if(num[j] == 3){
			printf("san");
		}else if(num[j] == 4){
			printf("si");
		}else if(num[j] == 5){
			printf("wu");
		}else if(num[j] == 6){
			printf("liu");
		}else if(num[j] == 7){
			printf("qi");
		}else if(num[j] == 8){
			printf("ba");
		}else if(num[j] == 9){
			printf("jiu");
		}
		if(j != 0){
			printf(" ");
		}
        
	}
}

int main(){
    
    int N;
    scanf("%d", &N);
    int num[MAX];
    
    if(N > 0){
        test(N, num);
    }else if(N < 0){
        N = -N;
        printf("%s ", "fu");
        test(N, num);
    }else{
        printf("%s", "ling");
    }
   
    return 0;
}

3、你的程序要读入一行文本,其中以空格分隔为若干个单词,以.结束。你要输出每个单词的长度。这里的单词与语言无关,可以包括各种符号,比如it’s算一个单词,长度为4。注意,行中可能出现连续的空格;最后的.不计算在内。
输入:输入在一行中给出一行文本,以.结束。样例:It’s great to see you here.
输出:在一行中输出这行文本对应的单词的长度,每个长度之间以空格隔开,行 末没有最后的空格。样例:4 5 2 3 3 4
优化目标:无

#include <stdio.h>
#include <string.h>

#define MAX 1024

int main(){
    
    char str[MAX];
    gets(str);
    
    int count=0;
    int j=0, i=0; 
    int num[MAX] = {0};
    
   while(str[i] != '\0'){
       if(str[i] == ' ' || str[i] == '.'){
            if(count > 0){
                num[j] = count;
                j++;
                count = 0;
            }
            
        }else{
            count++;
        }
       i++;
   }
    
    if(j>0){//屏蔽掉输入为"空句子"这种特殊情况
        for(int k=0; k<j-1; k++){
        if(num[k] != 0){
            printf("%d ", num[k]);
        }
    }
    printf("%d",num[j-1]);
    }
    
    return 0;
}

4、队列的顺序存储
队列是一种先进先出(First In First Out,FIFO)的数据结构。队列只能在队尾插入元素,在队首删除元素。队列被用在很对地方,比如提交操作系统执行的一系列进程、打印任务池等。
4.1实现队列孙秀存储相关API的声明。创建头文件SeqQueue.h来声明相关函数。

#ifndef SEQQUEUE_H
#define SEQQUEUE_H

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

#define MAX_SIZE 024

typedef struct SEQQUEUE {
	void* data[MAX_SIZE];
	int size;
}SeqQueue;

//初始化队
SeqQueue* Init_SeqQueue();
//入队
void Push_SeqQueu(SeqQueue* queue, void* data);
//返回队头元素
void* Front_SeqQueu(SeqQueue* queue);
//出队
void Pop_SeqQueu(SeqQueue* queue);
//返回队尾元素
void* Back_SeqQueu(SeqQueue* queue);
//返回队列大小
int Size_SeqQueu(SeqQueue* queue);
//清空队
void Clear_SeqQueu(SeqQueue* queue);
//销毁队
void FreeSpace_SeqQueu(SeqQueue* queue);

#endif // !SEQQUEUE_H

4.2实现队列顺序存储相关API的定义。创建c文件SeqQueue.c来定义相关函数。

#include "SeqQueue.h"

/*
*初始化队
*/
SeqQueue* Init_SeqQueue() {
	SeqQueue* queue = (SeqQueue*)malloc(sizeof(SeqQueue));
	for (int i = 0; i < MAX_SIZE; i++) {
		queue->data[i] = NULL;
	}
	queue->size = 0;

	return queue;
}

/*
*入队,数组模拟队,用数组的左边做队头
*@queue:队列指针
*@data:入队的数据
*/
void Push_SeqQueu(SeqQueue* queue, void* data) {
	//判断参数的合法性
	if (queue == NULL || data == NULL) {
		return;
	}
	//如果入队时,队列已经满了,则直接返回
	if (queue->size == MAX_SIZE) {
		return;
	}
	
	//入队,因为队的特定是先进先出,队头入,队尾出
	queue->data[queue->size] = data;
	queue->size++;
}

/*
*返回队头元素
*@queue:队列指针
*/
void* Front_SeqQueu(SeqQueue* queue) {
	//判断参数的合法性
	if (queue == NULL) {
		return NULL;
	}
	//如果队空,则返回空
	if(queue->size == 0){
		return NULL;
	}
	return queue->data[0];
}

/*
*出队
*@queue:队列指针
*/
void Pop_SeqQueu(SeqQueue* queue) {
	//判断参数的合法性
	if (queue == NULL) {
		return;
	}
	//如果队空,则返回空
	if (queue->size == 0) {
		return;
	}
	for (int i = 0; i < queue->size - 1; i++) {
		queue->data[i] = queue->data[i + 1];
	}

	queue->size--;
}

/*
*返回队尾元素
*@queue:队列指针
*/
void* Back_SeqQueu(SeqQueue* queue) {
	//判断参数的合法性
	if (queue == NULL) {
		return NULL;
	}
	//如果队空,则返回空
	if (queue->size == 0) {
		return NULL;
	}
	return queue->data[queue->size - 1];
}

/*
*返回队列大小
*@queue:队列指针
*/
int Size_SeqQueu(SeqQueue* queue) {
	//判断参数的合法性
	if (queue == NULL) {
		return -1;
	}
	return queue->size;
}

/*
*返清空队
*@queue:队列指针
*/
void Clear_SeqQueu(SeqQueue* queue) {
	//判断参数的合法性
	if (queue == NULL) {
		return;
	}
	for (int i = 0; i < queue->size; i++) {
		queue->data[i] = NULL;
	}
	queue->size = 0;
}

/*
*销毁队
*@queue:队列指针
*/
void FreeSpace_SeqQueu(SeqQueue* queue) {
	//判断参数的合法性
	if (queue == NULL) {
		return;
	}
	free(queue);
}

4.3函数测试。队列的顺序存储.c文件

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

#include "SeqQueue.h"

typedef struct PERSON {
	char name[64];
	int age;
}Person;

int main() {
	//初始化队列
	SeqQueue* queue = Init_SeqQueue();

	//初始化队列
	Person p1 = { "aaa", 10 };
	Person p2 = { "bbb", 20 };
	Person p3 = { "ccc", 30 };
	Person p4 = { "ddd", 40 };
	Person p5 = { "eee", 50 };

	//入队
	Push_SeqQueu(queue, &p1);
	Push_SeqQueu(queue, &p2);
	Push_SeqQueu(queue, &p3);
	Push_SeqQueu(queue, &p4);
	Push_SeqQueu(queue, &p5);

	//打印数据
	while (Size_SeqQueu(queue) > 0) {
		Person* p = (Person*)Front_SeqQueu(queue);
		printf("Name:%s, Age:%d\n", p->name, p->age);
		Pop_SeqQueu(queue);
	}
	//释放内存
	FreeSpace_SeqQueu(queue);

	return 0;
}

总结:今天用链表把昨天的第二题写了一下,用链表看似代码较之前的方法多一些,但逻辑却非常清晰。此外,通过这一次的链表解题,自己对链表的操作更加熟练了。同时,自己可以通过链表来解决一些问题了,而不是在学习链表时仅仅写一些给到的例子。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

别偷我的猪_09

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

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

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

打赏作者

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

抵扣说明:

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

余额充值