PTA作业分析6

目录

7-3 递归法求Hanoi塔输出

题目:

思路:

7-7 头插法创建单链表、遍历链表、删除链表

题目:

 思路:

知识点:链表的插入与删除 

插入:​编辑

删除:​编辑

7-8 单链表基础应用(1)--创建链表

题目:

思路:

7-9 sdut-C语言实验-单链表的顺序建立与结点的删除

题目:

思路:

 


7-3 递归法求Hanoi塔输出

题目:

题目描述:递归方法进行Hanoi塔问题求解,这里要求输入Hanoi塔层数n,输出盘子移动步骤。
汉诺塔问题:有三根杆子X,Y,Z。X杆上有n个(1<=n<=10)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至Z杆:每次只能移动一个圆盘,大盘不能叠在小盘上面。求解步骤可参照下图:

Hanoi.jpg

输入格式:

输入为一个正整数n为盘子数目,且1<=n<=10。

输出格式:

输出每一步移动盘子的记录。一次移动一行。
每次移动的记录为例如3:X->Y 的形式,即把编号为3的盘子从X杆移至Y杆。
我们约定圆盘从小到大编号为1, 2, ...n。即最上面那个最小的圆盘编号为1,最下面最大的圆盘编号为n。

输入样例:

在这里给出一组输入。例如:

3

输出样例:

在这里给出相应的输出。例如:

1:X->Z
2:X->Y
1:Z->Y
3:X->Z
1:Y->X
2:Y->Z
1:X->Z

输入样例:

在这里给出一组输入。例如:

0

输出样例:

在这里给出相应的输出。例如:

Wrong Input.

思路:

 一个非常经典的递归问题,关键要找到程序的出口和递归关系

        ps:为作区分,将盘数记为num,每个盘编号为1~n

1.当num=1,可以直接从X移到Z

2.num!=1时,将前n-1个看做一个整体,记为(n-1):

将(n-1)从X借Z移到Y,(X--(Z)-->Y)

那么此时,只有1个盘(编号为n),则为情况1(num=1)

现在,(n-1)在Y位置,只需要将(n-1)从Y借X移到Z(Y--(X)-->Z)

#include<stdio.h>
void hanoi(int n,char a,char b,char c){
    if(n==1){
        printf("%d:%c->%c\n",n,a,c);//情况1,直接从X->Z
    }else if(n>=1&&n<=10){
        hanoi(n-1,a,c,b);    //(n-1)从X借Z到Y,此时(n-1)在Y上
        printf("%d:%c->%c\n",n,a,c);
        hanoi(n-1,b,a,c);    //(n-1)从Y借X到Z
    }
}
int main() {  
    int n;  
    scanf("%d", &n);  
    if (n < 1 || n > 10) {  
        printf("Wrong Input.\n");  
        return 0;  
    }  
    hanoi(n, 'X', 'Y', 'Z');  
    return 0;  
}

7-7 头插法创建单链表、遍历链表、删除链表

题目:

输入一系列自然数(0和正整数),输入-1时表示输入结束。按照输入的顺序,用头插法建立单链表,并遍历所建立的单链表,输出这些数据。注意 -1 不加入链表。

输入格式:

第一行是一个正整数k,表示以下会有k组测试数据。

每组测试数据是一系列以空格隔开的自然数(0和正整数)。数列末尾的 -1 表示本组测试数据结束。按照输入的顺序,用头插法建立单链表,并遍历所建立的单链表,输出这些数据。注意 -1 不加入链表。

输出格式:

对于每组测试数据,输出链表中各节点的数据域。每个数据后有一个空格。每组测试数据的输出占1行。

输入样例:

3
1 2 3 4 5 -1 
30 20 10 -1 
4 2 2 1 1 2 0 2 -1 

输出样例:

在这里给出相应的输出。例如:

5 4 3 2 1 
10 20 30 
2 0 2 1 1 2 2 4 

注意:对每组测试数据,创建链表,遍历链表输出之后,一定要删除链表,否则会出现“内存超限”。

 思路:

链表的基本操作,需要注意:

1.头插法和尾插的区别,使用头插法时,链表遍历的顺序为输入顺序的逆序

eg:

输入: 10 -9 2 8 6

存储顺序:( ^ 表示在此插入数据)

a.^

b.^ 10

c.^ -9 10

d.^ 2 -9 10

e.^ 8 2 -9 10

f. 6 8 2 -9 10

2.malloc和free 配合使用,free释放空间

#include <stdio.h>
#include <stdlib.h>
struct Node {
    int num; 
    struct Node* next; 
};
 
struct Node* createLinkedList() {
    struct Node* head = NULL;
    int value;
    while (1) {
        scanf("%d", &value);
        if (value == -1) {
            break;
        }
        struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
        newNode->num = value;
        newNode->next = head;    //插在头部
        head = newNode;    //改变头指针
    }
 
    return head;
}
 
// 遍历链表
void traverseAndPrint(struct Node* head) {
    struct Node* p = head;
    while (p != NULL) {
        printf("%d ", p->num);
        p = p->next;
    }
    printf("\n");
}
 
// 删除链表释放内存
void deleteLinkedList(struct Node* head) {
    struct Node* p = head;
    while (p != NULL) {
        struct Node* temp = p;
        p = p->next;
        free(temp);
    }
}
 
int main() {
    int k;
    scanf("%d", &k);
 
    for (int i = 0; i < k; i++) {
        struct Node* head = createLinkedList();
        traverseAndPrint(head);
        deleteLinkedList(head);
    }
 
    return 0;
}

知识点:链表的插入与删除 

插入:

删除:

7-8 单链表基础应用(1)--创建链表

题目:

编程实现一个简易学生信息管理系统,按如下步骤分别用自定义函数实现:
(1) 根据输入信息创建单链表。每个学生的信息包括姓名和成绩;
(2) 输出简易学生信息管理系统(单链表)的所有学生(结点)信息。

输入格式:

根据输入的若干个学生信息创建单链表。每一行代表一个学生信息,以成绩-1作为输入的结束。

输出格式:

每个学生信息占一行,姓名和成绩之间以空格分隔,成绩保留一位小数。

输入样例:

在这里给出一组输入。例如:

Cai 61.2
Cai 64.6
Cheng 68.4
Xiao 71.2
Zhang 83.2
Liu 90.4
Xiao 92.6
Cai 96.8
xx -1

输出样例:

在这里给出相应的输出。例如:

Cai 61.2
Cai 64.6
Cheng 68.4
Xiao 71.2
Zhang 83.2
Liu 90.4
Xiao 92.6
Cai 96.8

思路:

这道题和上一道题相似,但是有不同:

1.输入的为字符串,不能直接赋值,要用strcmp(s1,s2)

2.是顺序输出,为尾插法

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

typedef struct stu_data {    //使用typedef相当于把struct stu_data换一个名字,换成data
	char name[20];
	double num;
	struct stu_data *next;
} data;

data *creatchain() {
	data *head = NULL;
	data *tail = NULL;
	char name[20];
	double num;
	while (1) {
		scanf("%s %lf", name, &num);
		if (num == -1) {
			break;
		}
		data *newNode = (data *)malloc(sizeof(data));
		strcpy(newNode->name, name);    //存储字符串
		newNode->num = num;
		newNode->next = NULL;
		if (head == NULL) {    //插在头部
			head = newNode;
		} else {    //插在中间
			tail->next = newNode;
		}
		tail = newNode;
	}

	return head;
}
//遍历链表
void traverseAndPrint(data *head) {
	data *current = head;
	while (current != NULL) {
		printf("%s %.1f\n", current->name, current->num);
		current = current->next;
	}
	
}

int main() {
	data *head = creatchain();
	traverseAndPrint(head);
}

7-9 sdut-C语言实验-单链表的顺序建立与结点的删除

题目:

输入n个整数,先按照数据输入的顺序建立一个带头结点的单链表,再输入一个数据m,将单链表中的值为m的结点全部删除。分别输出建立的初始单链表和完成删除后的单链表。

输入格式:

第一行输入数据个数n(1<=n<=15);
第二行依次输入n个整数;
第三行输入欲删除数据m。

输出格式:

第一行输出原始单链表的长度;
第二行依次输出原始单链表的数据;
第三行输出完成删除后的单链表长度;
第四行依次输出完成删除后的单链表数据。

From:Teacher Wang

输入样例:

10
56 25 12 33 66 54 7 12 33 12
12

输出样例:

10
56 25 12 33 66 54 7 12 33 12
7
56 25 33 66 54 7 33

思路:



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

struct Node {
	int num;
	struct Node *next;
};
//创建链表,尾插法
struct Node *create_new(int n) {
	struct Node *head, *tail, *p;
	head = tail = NULL;
	for (int i = 1; i <= n; i++) {
		int num;
		scanf("%d", &num);
		p = (struct Node *)malloc(sizeof(struct Node));
		p->num = num;
		p->next = NULL;
		if (head == NULL) {
			head = p;
		} else {
			tail->next = p;
		}
		tail = p;
	}
	return head;
}

//删除指定链表
struct Node *delet_node(struct Node *head, int num) {
	struct Node *p, *q;
	q = p = head;
	while (p != NULL) {
		if (p->num == num) {
			if (p == head) {
				head = p->next;
				free(q);
				q = p = head;
			} else {
				q->next = p->next;
				free(p);
				p = q->next;
			}
		} else {
			q = p;
			p = p->next;
		}

	}
	return head;
}

//遍历链表
void print_node(struct Node *head) {
	struct Node *p = head;
	while (p != NULL) {
        if(p==head){
            printf("%d", p->num);
            p=p->next;
        }
        else{
    		printf(" %d", p->num);
    		p = p->next;
        }
	}

}

int count_node(struct Node *head) {
	struct Node *p = head;
	int count = 0;
	while (p != NULL) {
		count++;
		p = p->next;
	}
	return count;
}

int main() {
	int n, num;
	scanf("%d", &n);
	printf("%d\n", n);
	struct Node *head = create_new(n);
	print_node(head);
	printf("\n");
	scanf("%d", &num);
	struct Node *newhead = delet_node(head, num);
	printf("%d\n", count_node(newhead));
	print_node(newhead);

}

 

                                              

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很高兴为您解答有关 PTA 作业 7 函数的问题。 PTA 作业 7 中,主要涉及到函数的定义、调用和使用。下面是一些常见的函数问题: 1. 如何定义函数? 函数定义的一般形式为: ``` 返回值类型 函数名(参数列表) { 函数体 } ``` 其中,返回值类型可以是任意类型,函数名是用户自己定义的函数名,参数列表是函数的输入参数,可以有多个参数,也可以没有参数。函数体是函数的具体实现,包括一系列的语句和逻辑。 例如,定义一个求两个整数之和的函数: ``` int add(int a, int b) { return a + b; } ``` 2. 如何调用函数? 函数调用的一般形式为: ``` 函数名(参数列表); ``` 其中,函数名是需要调用的函数名,参数列表是函数的输入参数,需要按照函数定义的顺序传入。 例如,调用上面定义的 add 函数: ``` int result = add(3, 4); ``` 3. 如何使用函数? 函数的使用主要包括两个方面:函数的调用和函数的返回值的使用。 函数的调用已经在上面介绍过了,在这里重点讲解函数的返回值的使用。 如果函数有返回值,可以将函数调用的返回值赋值给一个变量,然后在程序中使用这个变量。 例如,使用上面定义的 add 函数: ``` int a = 3; int b = 4; int result = add(a, b); printf("%d + %d = %d\n", a, b, result); ``` 这样,程序就会输出:3 + 4 = 7。 希望这些信息对您有所帮助。如果您有任何其他问题,请随时问我。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值