studyday2

学习以及成为想要成为的人day2

寒假c语言学习

函数

汉诺塔问题初次探究

今天又看了一下汉诺塔问题,试图将它弄明白,但是递归这个东西感觉不太好懂,所以我决定不急着消化它,每天都弄明白一点点。

汉诺塔的代码通过书上指导,已经上机调试过,代码如下:

#include <stdio.h>
#include <stdlib.h>
#include<math.h>
int main()//汉诺塔问题用递归方法来解决
{
    void hanoi(int n,char one,char two,char three);
    int m;
    printf("请输入需要移动的棋子个数:\n");
    scanf("%d",&m);
    printf("移动这些棋子需要的步骤为:\n");
    hanoi(m,'A','B','C');
    printf("一共需要%2.0f步",pow(2,m)-1);
    return 0;
}
void hanoi(int n,char one,char two,char three)
{
    void move(char x,char y);
    if(n==1)
    move(one,three);
    else
    {
        hanoi(n-1,one,three,two);//1
        move(one,three);
        hanoi(n-1,two,one,three);//2
    }
}

void move(char x,char y)
{
    printf("%c-->%c\n",x,y);
}

最难理解的还是这个1和2部分的语句,看了书上的解释后,我开始明白了一点点,如果盘子上只有1个棋子,那么直接将它移动到第三个就可以了,如果盘子上有超过一个棋子,那么执行程序化的三个步骤:First 将第一个盘子上n-1个棋子都移动到第二个盘子上;Second 将盘子上剩余的一个最下面的棋子移动到第三个盘子上;Third 将第二个盘子上剩余的n-1个棋子全部移动到第三个盘子上。这就是 voidhanoi函数解决的方法关键所在,也就是这题的算法核心。

但是我在调试的时候,还是没弄明白它这个语句怎么实现的,

hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);

函数的学习果然任重道远,仍需不断努力呀!

选择法与冒泡法排序

老实说,由于大一上学期初来乍到,对大学什么东西都很新奇,唯独对学习不感冒hhh,导致C语言没有学好。当时老师在课堂上讲了好久这个排序方法,我丝毫不为所动,想着就是比个大小而已,有什么好稀奇的真是。现在终于为自己的无知感到后悔,就算是平平无奇的排序算法也有相当缜密的逻辑,希望今天我能将这两种算法弄清楚。

冒泡法排序的代码如下(已经上机调试过):

#include <stdio.h>
#include <stdlib.h>
int main()//冒泡法排序
{
    int i,j,a[10],t;
    printf("请输入十个数字:\n");
    for(i=0; i<10; i++)
        scanf("%d",&a[i]);
    printf("\n");

    for(j=0; j<9; j++)
    {
        for(i=0; i<9-j; i++) //这两个循环内的判断才是灵魂
        {
            if(a[i]>a[i+1])
            {
                t=a[i];
                a[i]=a[i+1];
                a[i+1]=t;
            }
        }
    }
    printf("经排序后输入数字的顺序为:\n");
    for(i=0; i<10; i++)
    {
        printf("%d ",a[i]);
    }
    return 0;
}

所谓冒泡法,其实就是每相邻的两个数比较大小,在我这个题目要求下是从小到大排序,所以每一次比较较大的数都会下沉,较小的数都会上浮,这样的话一趟完整的比较过程后,就会出现最大的数在最后一位,就是最大的数沉底了。所以冒泡法并不像字面上理解的那样好像是最小的数会最先浮起来,当然也有可能第一次比较最小的数就在第一位,但是这是概率性的,而最大的数必然会在第一趟比较过程完成后沉底。

其次需要注意的就是循环里面的判断,经过自己手工画图分析就知道,n个数据,一个完整比较过程只需要进行n-1次。而经历过一个完整过程后需要比较的数据就会少掉一个(那个最大的数沉底了),所以 j<9;i<9-i; 这里面有很深的逻辑关系。

再者就是选择法排序,代码如下(已经上机调试过):

#include <stdio.h>
#include <stdlib.h>
int main()//选择法实现排序
{
    int i,a[10];
    void sort(int array[],int n);
    printf("请输入10个数字:\n");
    for(i=0; i<10; i++)
        scanf("%d",&a[i]);
        sort(a,10);//这个地方是利用一维数组名作为实参,向形参传递的是数组首元素的地址。
    printf("经排序后所输入数字的顺序为:\n");
    for(i=0; i<10; i++)
        printf("%d ",a[i]);
    printf("\n");
    return 0;
}

void sort(int array[],int n)//排序函数
{
    int i,j,k,t;
    for(i=0; i<n-1; i++)
    {
        k=i;
        for(j=i+1; j<n; j++)
        {
            if(array[k]>array[j])
            {
                k=j;
                t=array[i];
                array[i]=array[k];
                array[k]=t;
            }
        }
    }

}

从上面的代码可以看出选择法和冒泡法还是存在些许差异的,首先选择排序的核心思想是将第一个数后面的每一个数都来与第一个数比较,如果后面有比第一个数小的数,就和第一个数互换位置。一趟完整的比较过程完成后,第一个数一定是现存数据中最小的数,那么下一趟比较过程就可以从去掉上一次比较中最小的数后留下的数据里面重复上面的过程,这样每次都能确定一个最小的数,直至最后一次。第二个循环里面,j为什么从i+1开始也就有了合理的解释,因为每一次比较都是后面的所有数和第一个比较,所以要从i+1开始。

关于这两种算法的解析就这么多了,今天虽然没有做太多事情,还是小有收获,希望自己能够一直坚持下去

不积跬步,无以至千里;不积小流,无以成江海。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值