C语言实现之牛的数量(细胞分裂问题)(利用树实现)
来源:互联网 发布:装修公司网络推广 编辑:程序博客网 时间:2024/05/16 16:55
起因:
老师上课的时候说了一个题:
牛长到3岁可以生小牛,长到9岁后去世,每年可以生一头小牛,最初牛圈中只有一头牛,经过X年后,牛圈里有几头牛?
当我听完之后第一反应,9年以内是一头牛,九年之后就没牛了,有的话也只剩尸体了。牛是哺乳动物,有性生殖,一头牛怎么生啊?我更喜欢称这个问题叫细胞分裂问题,比如说蛙的红细胞就是通过无丝分裂增殖的。不多扯了,还是用牛吧,我们先分析一下问题。
分析:
牛一年生一头,从三岁开始能生小牛,他总共能活九年,最后一年它怎么这把最后一头牛生下来再死吧(YY:可能是难产死的)。这样这题就是说一头牛活九年,从三岁开始到死,总共能生7头牛。
我们可以用什么方法解决这个问题来?
(1)找出一个数量关系的公式,直接计算。
(2)模拟这个生长的数量关系,(a)循环+数组,(b)循环+递归+树,(c)递归。
小弟不才,没找出数量关系的公式。所以只能模拟,那这个牛数量的存储用什么实现?老师说用数组,但是我向大家第一个想到的应该是用树来实现吧,类似家谱。我决定用树来实现(当然题目就是这个)。
利用树实现的缺点:当然这个确实是最符合思维的一种方法,但是缺点显而易见,效率比较低,相比数组,吃内存也比较多。
思路:
我是这样想的,将牛看做树上的节点,便利一次就是一年,年龄0-2岁不作处理,只给他增长年龄,3-9岁没便利一次,在此节点之下创建新的结点,年龄是1的话就让全局计数的变量增长1,表示有新牛出生,年龄到达10的话就已经死了,所以就让全局计数的变量减少1,表示有一头牛死了。所以有几年,就这样遍历几次这个树,最后的计数变量就是现在牛圈中还活着的牛的数量。
那么这个节点的结构体需要包含两部分,一个是这个节点的年龄,另一个是,指向它的子节点的7个指针。
▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
▕ago▕ node_0▕node_1▕ node_2▕ node_3▕node_4▕ node_5▕ node_6▕
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
实现:
#include <stdio.h>#include <stdlib.h>#define DIETIME 9 //死亡时间#define INCREASETIME 3 //开始繁殖时间#define COUNTINCREASE DIETIME - INCREASETIME + 1 //总繁殖时间//节点typedef struct OXnode{ int age; //年龄 struct OXnode * nextOX[COUNTINCREASE]; //子(小牛)节点}OX;int countOX = 0; //记录牛的总数/*********************************** 函 数:OX * createNode() ** 参 数:无 ** 功 能:创建一个牛的节点 ** 返 回:创建好的节点的指针 ***********************************/OX * createNode(){ int loop = COUNTINCREASE; OX * node = (OX *)malloc(sizeof(OX)); //申请内存空间 //判断内存申请是否不成功 if(node == NULL) { puts("not have enough memory."); exit(0); //退出程序 } node->age = 0; //初始化年龄 //循环初始化节点 while(loop--) { node->nextOX[loop] = NULL; } return node; //返回创建的节点}/*********************************** 函 数:void traversal(OX * ox) ** 参 数:无 ** 功 能:遍历结点 ** 返 回:无 ************************************/void traversal(OX * ox){ //判断年龄是否还需要增加(防止不必要的增加) if(ox->age <= DIETIME) { ox->age++; //年龄增加 } //判断年龄状况 switch(ox->age) { case 1: //1岁说明是新牛 countOX++; //总数增加1 break; case DIETIME: //9岁说明是将要死去的牛 countOX--; //总数减少1 break; } //判断牛是否到达繁衍的年龄 if(ox->age >= INCREASETIME) { int loop = 0; int age = ox->age == DIETIME + 1 ? DIETIME : ox->age ; //计算当前年龄 //循环他的子节点(即亲生的小牛节点) for(; loop < (age - INCREASETIME + 1); loop++) { //判断节点是否为NULL(即此小牛刚出生) if(ox->nextOX[loop] == NULL) { ox->nextOX[loop] = createNode(); //创建新生的小牛节点 } traversal(ox->nextOX[loop]); //遍历此小牛节点 } }}/********************************** 函 数:int main() ** 参 数:无 ** 功 能:主函数 ** 返 回:0 ***********************************/int main(){ int year; puts("years:"); scanf("%d",&year); OX * firstOX = createNode(); //创建首节点 //年数循环遍历全部节点 while(year--) { traversal(firstOX); //遍历 } printf("count : %d\n", countOX); return 0;}
结果:
这是前39年的结果:
current year: 1, count: 1
current year: 2, count: 1
current year: 3, count: 2
current year: 4, count: 3
current year: 5, count: 5
current year: 6, count: 8
current year: 7, count: 13
current year: 8, count: 21
current year: 9, count: 33
current year: 10, count: 53
current year: 11, count: 85
current year: 12, count: 136
current year: 13, count: 218
current year: 14, count: 349
current year: 15, count: 559
current year: 16, count: 895
current year: 17, count: 1433
current year: 18, count: 2295
current year: 19, count: 3675
current year: 20, count: 5885
current year: 21, count: 9424
current year: 22, count: 15091
current year: 23, count: 24166
current year: 24, count: 38698
current year: 25, count: 61969
current year: 26, count: 99234
current year: 27, count: 158908
current year: 28, count: 254467
current year: 29, count: 407490
current year: 30, count: 652533
current year: 31, count: 1044932
current year: 32, count: 1673299
current year: 33, count: 2679533
current year: 34, count: 4290863
current year: 35, count: 6871162
current year: 36, count: 11003117
current year: 37, count: 17619812
current year: 38, count: 28215439
current year: 39, count: 45182718
...
总结:
主要还是思路,没有难的地方,发出来和大家分享下,希望大家多多多提意见,就写这些吧。
- C语言实现之牛的数量(细胞分裂问题)(利用树实现)
- 利用动态规划法求解旅行商问题(TSP)的C语言实现(一)
- C语言通讯录(利用数组实现)
- C语言实现回文判断(利用指针的方法)
- 显示两个文件不一致的内容的实现(细胞分裂的方法)
- C语言之二叉树(包括遍历的实现)
- 判断素数问题(C语言实现)
- 哲学家就餐问题(C语言实现)
- 判断素数问题(C语言实现)
- 荷兰旗问题(C语言实现)
- 迷宫问题 C语言实现(深搜)
- 推理问题(c语言实现)
- 删数问题(C语言实现)
- 100盏灯的问题(C语言实现)
- 连通性问题的快速查找解决方案(C语言实现)
- 多项式加法利用链表实现(c语言)
- 利用递归函数逆序一个栈(C语言实现)
- C语言通讯录(利用链表实现)
- 基于.NET的WebService的实现
- tomcat的server.xml文件分析
- Mac功夫:OS X 的300多个技巧和小窍门
- 成都计委原副主任贪污640万获刑:自己太自信-党员领导-贪污罪-计委
- 绿色版手动配置tomcat
- C语言实现之牛的数量(细胞分裂问题)(利用树实现)
- javascript键盘事件大全
- innerXml,outerXml,innerText的不同
- Intent和PendingIntent的区别
- linux里端口转发
- spring mvc 杂
- Android——DisplayMetrics之我见
- Google图片搜索的原理
- Extjs4---鼠标右键事件