这个问题我们来用栈来实现
首先,我们先定义一个栈的结构体(栈的结构体与链表的结构体不可同,栈的结构体第二项是用int定义栈的顶端; 而链表的第二项,是用struct定义一个指针)
struct stack{int data[10005];int top;
};
接下来,我们来写一个创建栈的函数
void CreateStack(stack *st){st->top=-1;
}
注意,要将栈顶top定位-1,即栈的初始化
下面,我们来编写进栈的功能,用一个函数来实现
void push(int a,stack *st){st->top++;st->data[st->top]=a;
}
在push函数中,现将top+1,然后将top定位data数组的标号。这样我们就明白了为什么上个函数中要将栈的top定为-1,这样我们存入栈的第一个数就是data[0],第二个数就是data[1],与我们数组中的标号相一致,方便记忆:)
接下来,我们来编写出栈的功能。这样的功能我们用3个函数来实现,分别是 1.判断栈是否为空的函数 2.top-1的函数 3.取栈顶的函数
int isEmpty(stack *st){if(st->top==-1)return 1;return 0;
}void pop(stack *st){st->top--;
}int GetTop(stack *st){return st->data[st->top];
}
这时候我们就想问了,为什么进栈用一个函数就能实现,而出栈要用三个函数实现嘞?其实我们在int main()主函数之前做的函数声明,都是为主函数内的功能服务的,我们在主函数中的出栈代码是这样的
while(!isEmpty(&st)){printf("%d",GetTop(&st));pop(&st);}
我们可以看到while()的判断条件是 !isEmpty(&st),也就是说如果栈不为空,就执行下面的程序:printf("%d",GetTop(&st)),即打印栈顶函数,然后再pop(&st),即令top-1。我们知道栈的特点是什么呢?先进后出,后进先出。所以我们这段出栈代码的含义就是先输出栈顶的数,再令top-1,输出栈顶第二个函数......
最后,我们来编写主函数
int main(){int n;stack st;CreateStack(&st);scanf("%d",&n);while(n){push(n%2,&st);n=n/2;}while(!isEmpty(&st)){printf("%d",GetTop(&st));pop(&st);}return 0;
}
我们可以看到,这里进栈函数中的并不是单纯的push(n,&st)而是先用一个while循环,如果n>0,那么将n/2进栈,再将n变成n/2。那么,这种算法是什么意思嘞?我们知道,正常算十进制变二进制的时候,我们是这样算的
那么,这个算法也是同样的道理,先将数/2,记录下余数,进栈;再将数/2,记录......
其实这道题用栈写最关键的原因,就是我们想要输出的时候是从后往前出栈,也就是先进后出,后进先出。知道了这样的特点,我们就不难看出这种存储问题用队列或栈来写都可以。不过,最好、最简单的就是用栈了。
下面,为大家附上完整版的代码
#include<stdio.h>
#include<stdlib.h>
struct stack{int data[10005];int top;
};void CreateStack(stack *st){st->top=-1;
}void push(int a,stack *st){st->top++;st->data[st->top]=a;
}int isEmpty(stack *st){if(st->top==-1)return 1;return 0;
}void pop(stack *st){st->top--;
}int GetTop(stack *st){return st->data[st->top];
}int main(){int n;stack st;CreateStack(&st);scanf("%d",&n);while(n){push(n%2,&st);n=n/2;}while(!isEmpty(&st)){printf("%d",GetTop(&st));pop(&st);}return 0;
}