C语言:求单链表结点的阶乘和

本题要求实现一个函数,求单链表L结点的阶乘和。这里默认所有结点的值非负,且题目保证结果在int范围内。

函数接口定义:

int FactorialSum( List L );
其中单链表List的定义如下:

typedef struct Node *PtrToNode;
struct Node {
    int Data; /* 存储结点数据 */
    PtrToNode Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */
-----------------------------------------------
-----------------------------------------------
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>

typedef struct Node *PtrToNode;
struct Node {
    int Data; /* 存储结点数据 */
    PtrToNode Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

int FactorialSum( List L );

int main()
{
    int N, i;
    List L, p;

    scanf("%d", &N);
    L = NULL;
    for ( i=0; i<N; i++ ) {
        p = (List)malloc(sizeof(struct Node));
        scanf("%d", &p->Data);
        p->Next = L;  L = p;
    }
    printf("%d\n", FactorialSum(L));

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:
3
5 3 6
输出样例:
846

【分析】:
好久没写C语言了。首先看看几个typedef的意思

typedef struct Node *PtrToNode;
//这个比较好理解,就是把Node* 给起了一个别名叫PtrToNode
typedef PtrToNode List;
//同样也是取别名

因此我们看到主程序段中有: List L, p;的声明这与Node *L, p;或者PtrToNode L, p;都是等价的。

这样也可以说明,一个链表的引用,实际上就是一个Node类型的指针嘛。

再分析一下这段代码的作用:
L = NULL;
for ( i=0; i<N; i++ ) {
        p = (List)malloc(sizeof(struct Node));
        scanf("%d", &p->Data);
        p->Next = L;  L = p;
    }

在这里插入图片描述
p通过malloc函数新创建一个节点之后,通过L指针可以找到原先的节点,然后把Next值赋为L指向的节点,最后L指针也指向新建的节点。这就是整个的添加节点过程。
在这里插入图片描述

因此,如果我们输入节点的顺序是:3, 4, 5
那么,最终添加到链表中的顺序实际上是:5,4, 3

然后对单链表遍历就能写出最终的代码:

//单链表遍历方法1,用指针
int FactorialSum( List L ){
	int sum = 0;
	PtrToNode p = L;
	while(p != NULL){
		int val = p->Data, i, fac = 1;
		//对val求阶乘
		for(i = val;i > 1;i--){
			fac *= i;
		}
		sum += fac;
		p = p->Next;
	}
	return sum;
}

当然,如果说你不想用指针来遍历整个链表行不行呢?当然也可以:

//遍历链表的方法2,不用指针
int FactorialSum( List L ){
	int sum = 0;
	Node p = *L;
	while(1){
		//printf("%d\n", p.Data);
		if(p.Next == NULL)	break;
		p = *(p.Next);
	}
	return sum;
}

我们只用一个Node类型的节点p,也可以完成对整个链表的遍历;但是判断是否跳出循环,还是需要用到指针。

【总结】:本题代码不难,关键是要理解List, Node*, PtrToNode这几种类型的关系
然后要明白,单链表遍历的原理。

  • 16
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值