《C语言教程》22章 链表

[复制链接]
1153|4
 楼主| niuyaliang 发表于 2015-3-17 20:54 | 显示全部楼层 |阅读模式

这一章的范围其实属于数据结构和算法,早已超出小雅的能力,因小雅在SDK教程中用到这些知识,所以只作简单讲解。如果对链表还一无所知,建议先看一点数据结构方面的书,或者干脆跳过这一章。

下面的例子是一个报数游戏,输入a、b、c三个小于20的整数,如果符合勾股定理,即“a平方+b平方=c平方”同得2000分,否则得“a平方+b平方-c平方”分,这个分也可能为负分。超过1000或-1000则算赢或输,游戏结束。


 楼主| niuyaliang 发表于 2015-3-17 20:54 | 显示全部楼层

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

  3. struct TriAngle{
  4.     int a ;            //直角三角形的勾
  5.     int b ;            //直角三角形的股
  6.     int c ;            //直角三角形的弦
  7.     int score ;        //累计得分
  8.     struct TriAngle *next ;    //下一个
  9. } ;

  10. //计算得分
  11. int getScore(unsigned char x,
  12.              unsigned char y,
  13.              unsigned char z)
  14. {
  15.     //得分 = x平方 + y平方 - z平方
  16.     int iret = x * x + y * y - z * z ;

  17.     //如果三个数是勾股弦,则得2000分
  18.     if (iret==0) {
  19.         iret = 2000;
  20.     }

  21.     return iret ;
  22. }

  23. //动态分配一个新节点
  24. struct TriAngle *newNode(void)
  25. {
  26.     return malloc(sizeof(struct TriAngle));
  27. }

  28. //输出历次结果,并释放内存
  29. void output(struct TriAngle *node, int no)
  30. {
  31.     //显示当前节点的情况
  32.     printf("%2d  %2d,%2d,%2d   %4d\n", no, node->a, node->b, node->c, node->score);

  33.     //如果下一个节点不为空
  34.     if (node->next != NULL) {
  35.         //递归调用下一个节点的输出并释放内存
  36.         output(node->next, no+1);
  37.     }

  38.     //如果不是“头”结点,释放当前节点的内存
  39.     if (no != 1) {
  40.         free(node);
  41.     }
  42. }

  43. int main(void)
  44. {
  45.     struct TriAngle head;        //头部地址固定,这很重要
  46.     struct TriAngle *p = &head ; //p为当前节点,从头部开始

  47.     //初始化
  48.     head.score = 0;
  49.     head.next = NULL;

  50.     //循环输入数据
  51.     while (1) {
  52.         printf("请输入三个小于20的数:");
  53.         scanf("%d,%d,%d", &p->a, &p->b, &p->c);

  54.         //检查输入的数据合法性
  55.         if (p->a > 20 || p->b > 20 || p->c > 20) {
  56.             printf("三个数不能大于20,请重试。\n");
  57.         } else {
  58.             //当前分数进行累加
  59.             p->score += getScore(p->a, p->b, p->c);

  60.             //如果超过正负1000
  61.             if (p->score < -1000 || p->score > 1000) {
  62.                 //设置最终结点并退出循环
  63.                 p->next = NULL;
  64.                 break;
  65.             } else {
  66.                 //动态请示下一个节点,并初始化累加分数,然后当前指针移向下一个
  67.                 p->next = newNode();
  68.                 p->next->score = p->score ;
  69.                 p = p->next ;
  70.             }
  71.         }
  72.     }

  73.     //打印输出头部,调用输出并释放内存函数
  74.     printf("No   a  b  c   得分\n");
  75.     output(&head, 1);

  76.     return 0;
  77. }

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| niuyaliang 发表于 2015-3-17 20:55 | 显示全部楼层
一、单向链表的定义和赋值
链表的结构多种多样,单向链表是最简单的一种。也就是结构体中有一个元素是一个指针,这个指针的数据类型是自身,用来表示下一个结构体的地址。
  1. struct TriAngle{
  2.     int a ;            //直角三角形的勾
  3.     int b ;            //直角三角形的股
  4.     int c ;            //直角三角形的弦
  5.     int score ;        //累计得分
  6.     struct TriAngle *next ;    //下一个
  7. } ;
 楼主| niuyaliang 发表于 2015-3-17 20:55 | 显示全部楼层
二、下一个节点的申请和终止
使用链表就必然要用到动态分配,所以内存泄漏又成了一个麻烦。单向链表在释放内存方面,一个关键地方是要记住链表的头,然后顺着这个“头”的指针一个一个地释放,这时用递归算法是比较好的做法。
  1.             //如果超过正负1000,则终止循环
  2.             if (p->score < -1000 || p->score > 1000) {
  3.                 //设置最终结点并退出循环
  4.                 p->next = NULL;
  5.                 break;
  6.             } else {
  7.                 p->next = newNode();         //动态请示下一个节点
  8.                 p->next->score = p->score ;  //初始化累加分数
  9.                 p = p->next ;                //当前指针移向下一个
  10.             }
 楼主| niuyaliang 发表于 2015-3-17 20:55 | 显示全部楼层
三、内存的释放
使用链表就必然要用到动态分配,所以内存泄漏又成了一个麻烦。单向链表在释放内存方面,一个关键地方是要记住链表的头,然后顺着这个“头”的指针一个一个地释放,这时用递归算法是比较好的做法。
  1.             //如果超过正负1000,则终止循环
  2.             if (p->score < -1000 || p->score > 1000) {
  3.                 //设置最终结点并退出循环
  4.                 p->next = NULL;
  5.                 break;
  6.             } else {
  7.                 p->next = newNode();         //动态请示下一个节点
  8.                 p->next->score = p->score ;  //初始化累加分数
  9.                 p = p->next ;                //当前指针移向下一个
  10.             }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

212

主题

2427

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部