C语言:求单链表结点的阶乘和
程序员文章站
2022-06-09 20:19:08
...
本题要求实现一个函数,求单链表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这几种类型的关系
然后要明白,单链表遍历的原理。
下一篇: iOS_实现物理仿真中的圆形碰撞