此代码是栈的顺序结构的实现,你叫数组写的也行,都一个样,另外我把令一个我找到的别人的代码也放最下面了,和我写的好像有挺大的区别,也提供给读者借鉴
是在写实验过程中的小练习,如有错误,望指出以改进,在代码中皆有大量的注释帮助你理解。
今天周末,祝你开心
#include<iostream>//有个小问题,由于程序设计之初就必须要赋值那么如果没有创建,一系列的功能无法使用
#include<stdlib.h>//但是我改了改,又没啥问题了,总之你注意到就问题不大
using namespace std;
#define MAX 20 //这个20是我故意的,就是为了防止最后内个S.top++没有被你注意到
//如果没有被注意到的话,个人认为你的代码仅仅只是个半成品,技术含量不大
typedef struct stack {
int* base;
int* top;
int len;
}stack;
void create(stack& S);//用于初始化栈
void destroystack(stack& S);//用于销毁栈
void clean(stack& S);//用于清空栈里的数据
void pankong(stack& S);//判断栈是否为空
void outtop(stack S); //获取栈顶元素 !!!我们记住一下这个输出的函数哈,一定不可以使用引用传递哈,引用传递的话会改变top的位置
void charu(stack& S);//用于插入元素
void deleteelem(stack& S);//用于删除栈顶个元素
void outstack(stack S);//输出元素 !!!我们记住一下这个输出的函数哈,一定不可以使用引用传递哈,引用传递的话会改变top的位置
void outlen(stack &S);//感觉是最没用的函数,很显然就能输出长度啊
void jisuan(stack& S);//进行进制转换的函数
void menu(void)
{ //我觉得我这个菜单写的不赖很经典,写前边了,哈哈哈哈哈
char a01[] = "(1)创建栈";
char a02[] = "(2)销毁栈";
char a03[] = "(3)清空栈";
char a04[] = "(4)判断栈是否为空";
char a05[] = "(5)获取栈顶元素";
char a06[] = "(6)用于插入栈顶元素";
char a07[] = "(7)删除栈顶个元素";
char a08[] = "(8)输出元素";
char a09[] = "(9)输出长度";
char a10[] = "(10)进制转换的函数";
char a11[] = "出入任意不在前面菜单的数字将结束程序";
printf("%-50s", a01);
printf("%-50s\n", a02);
printf("%-50s", a03);
printf("%-50s\n", a04);
printf("%-50s", a05);
printf("%-50s\n", a06);
printf("%-50s", a07);
printf("%-50s\n", a08);
printf("%-50s", a09);
printf("%-50s\n", a10);
printf("%-50s\n", a11);
}
void caidancaozuo(stack& S)//再次自我感觉良好觉得这个自我调用也不赖,放前边了
{
cout << "请问你想选择哪个指令" << endl;
int mingling;
cin >> mingling;
switch (mingling)
{
case 1:
{
create(S);
cout << "您刚才创建的栈是:"<<endl;
outstack(S);
caidancaozuo(S);
}
case 2:
{
destroystack(S);
caidancaozuo(S);
}
case 3:
{
clean(S);
caidancaozuo(S);
}
case 4:
{
pankong(S);
caidancaozuo(S);
}
case 5:
{
outtop(S);
caidancaozuo(S);
}
case 6:
{
charu(S);
caidancaozuo(S);
}
case 7:
{
deleteelem(S);
caidancaozuo(S);
}
case 8:
{
outstack(S);
caidancaozuo(S);
}
case 9:
{
outlen(S);
caidancaozuo(S);
}
case 10:
{
jisuan(S);
caidancaozuo(S);
}
default:
cout << "您已经决定退出此程序,程序即将退出" << endl;
break;
}
}
int main(void)
{
menu();
stack stack01;//推荐在main函数创建栈(当然只是一个名字)
caidancaozuo(stack01);
}
void create(stack& S) //用于初始化栈,并且给几个值,是不是比仅仅初始化高级那么一丢丢
{
S.base = (int*)malloc(MAX * sizeof(int));
S.top = S.base;//注意哈,因为我们要干的事情是在计算机内存的某一段内存空间存放数值,
S.len = 0; // 那么我们必须给我们所要创建的数值安排一个位置,top=base则是我们把让top指向base刚刚创建的位置
cout << "请输入一串数字,输入负数时停止将停止输入" << endl;
cout << "请输入1至20个数字" << endl;
int x;
while (scanf("%d", &x) && x >= 0)
{
*S.top = x;
S.len++;
if(S.len==20)//realloc函数比较难搞偶,看我下边写的应该对你理解有帮助
{
cout<<"您的数组长度已经达到20了,不可以再输了嗷"<<endl;
cout << "此栈内已经达到最大容量了,若插入即将给原空间扩容用以存放top++" << endl;
S.base = (int*)realloc(S.base, (MAX+1) * sizeof(int));//上面内个存放top++是为了防止top++后变成野指针,
S.top=S.base+20; //就一个空间而已不算很浪费吧,还锻炼开辟空间的函数了
return ;
}
S.top++;
}
}
void destroystack(stack& S)//用于销毁栈
{
if(!S.base)//注意一下这个小东西在后面会重复出现,是判断栈有没有存在的很重要的部分
{
cout<<"初始化都没得,我退出这个函数了"<<endl;
return ;
}
cout << "您要求的栈即将会被销毁" << endl;
free(S.base);
S.base = NULL;
S.top = NULL;
S.len = 0;
cout << "您要求的栈已被销毁" << endl;
}
void clean(stack& S)
{
if(!S.base)
{
cout<<"初始化都没得,我退出这个函数了"<<endl;
return ;
}
S.top = S.base;
S.len = 0;
cout << "您要求的栈已被清空" << endl;
}
void pankong(stack& S)//就是判断是不是为空函数的函数
{
if(!S.base)
{
cout<<"初始化都没得,我退出这个函数了"<<endl;
return ;
}
if (S.top == S.base)
{
cout << "您滴栈是一个空栈" << endl;
cout<<"鉴于你的栈是空栈我们给你两个选择"<<endl;
cout<<"(1)退出程序"<<endl;
cout<<"(2)重新选择"<<endl;
int x;
cout<<"请输入你的选择:";
cin>>x;
switch(x){
case 1:
return ;
case 2:
caidancaozuo(S);
default:
cout<<"这位同学你怎么乱输啊,我不改程序了,毁灭吧,我退出"<<endl;
break;
}
}
else {
cout << "您的栈中有数值啊里面有" << S.len << "个数值" << endl;
}
}
void outtop(stack S)//一个超级简单的输出栈顶元素的小函数
{
if(!S.base)
{
cout<<"初始化都没得,我退出这个函数了"<<endl;
return ;
}
pankong(S);
S.top--;
cout << *S.top<< endl;
}
void charu(stack &S)//插入函数感觉是这个程序总最核心的函数体
{
if(!S.base)
{
cout<<"初始化都没得,我退出这个函数了"<<endl;
return ;
}
if (S.len == MAX)
{
cout << "此栈内已经达到最大容量了,若插入即将给原空间扩容" << endl;
S.base = (int*)realloc(S.base, (MAX+1) * sizeof(int));
S.top=S.base+20;
}
if (!S.base)//虽然但是吧,这个东西几乎就用不到
{
cout << "你未能成功开辟一个新的数组,程序即将停止" << endl;
return;
}
int e;
cout << "请输入你要插入的元素" << endl;
cin >> e;
*S.top=e;
cout << "您刚才输入的数是" << *S.top << endl;
S.top++;
S.len++;//放在后面以防止多此加长度
}
void deleteelem(stack &S)//经查阅书得出栈居然是只能在顶部进行各种操作,那这个栈岂不是只能删除栈顶嘛
{
if(!S.base)
{
cout<<"初始化都没得,我退出这个函数了"<<endl;
return ;
}
cout << "你要删除的数值是:";
outtop(S);
S.top--;
S.len--;
cout << "栈顶元素已经被删除" << endl;
cout<<"新的栈顶元素是:";
outtop(S);
}
void jisuan(stack &S)//进行进制转换的函数
{
cout<<"很抱歉这个函数只能把随意的把你输入的某个数转换成你想要的某个进制型,而不是把原有的数组转换成新的进制型的数组"<<endl;
cout<<"但是但是我都写出来这个了,你觉得我写不出来直接转换整个数组的嘛,直接调用就行,"<<endl;
cout<<"这个只是思想,具体,哥们你自己写吧"<<endl;
cout << "请选择你要进行的进制抓换的类型:" << endl;
int a;
cin>>a;
// cout << "请输入你要把已经存在的函数类型转化成什么进制的数组" << endl;
cout<<"请输入一个数字让我们来转化它"<<endl;
int t;
cin>>t;
stack newstack;
newstack.base = (int*)malloc(100000 * sizeof(int));//我随意开辟的哈,因为我也不知道新创建的数到底能占几位
newstack.top = newstack.base;//注意哈,因为我们要干的事情是在计算机内存的某一段内存空间存放数值,
newstack.len=0;
while(t/a>=1)
{
*newstack.top=t%a;
t=t/a;
newstack.top++;
newstack.len++;
}
//记住记住哈我们要记得把最后小于一的内个最后的商余压入栈中,这个很重要,·
*newstack.top=t;
newstack.top++;
newstack.len++;
outstack(newstack);
}
void outstack(stack S)//用于栈的整体的输出
{
if(!S.base)
{
cout<<"初始化都没得,我退出这个函数了"<<endl;
return ;
}
S.top--;
for (int i = 0; i < S.len; i++)
{
cout << *S.top<< endl;
S.top--;
if(S.top==S.base)//这个点是我怕--后成为野指针了
{
cout << *S.top<< endl;
break;
}
}
cout << "你这个栈的长度是:"<<S.len << endl;
}
void outlen(stack &S)//仅仅是输出栈的长度感觉就很鸡肋
{
if(!S.base)
{
cout<<"初始化都没得,我退出这个函数了"<<endl;
return ;
}
cout << "你这个栈的长度是" << S.len << endl;
}
下面是我找的其他人的,额...网站上应该没他的
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef int Elemtype;
typedef struct node {
int* a;
int top;//指示栈顶元素在数组中的位置
}stack;
stack initstack() {//初始化栈
stack s;
s.a=(int*)malloc(MAXSIZE*sizeof(int));
if (!s.a) {
printf("内存分配失败\n");
exit(0);
}
s.top = -1;
printf("初始化成功!\n");
return s;
}
void destroy(stack* s) {//销毁栈
if (!s->a) {
printf("栈已被销毁或还未初始化\n");
return;
}
free(s->a);
s->a=NULL;
s->top = -1;
printf("销毁成功\n");
}
void length(stack* s) {
if (s->top < 0) {
printf("栈已空!\n");
return;
}
printf("该栈的长度为%d\n", s->top + 1);
}
void gettop(stack* s) {
if (s->top < 0)
{
printf("栈已空\n");
return;
}
printf("栈顶元素为%d\n", s->a[s->top]);
}
void push(stack* s, Elemtype elem) {//插入栈顶元素
if (s->top >= MAXSIZE - 1) {
printf("栈满!\n");
return;
}
s->a[++s->top] = elem;
}
void pop(stack* s) {//删除栈顶元素
if (s->top < 0) {
printf("栈已空!\n");
return;
}
printf("弹栈元素:%d\n", s->a[s->top]);
s->a[s->top--] = 0;
}
void isNull(stack* s) {
if (s->top < 0)
printf("栈已空!\n");
else
printf("栈未空\n");
}
void traverse(stack* s) {
if (s->top < 0) {
printf("栈已空!\n");
return;
}
int i;
for (i = 0; i <= s->top; i++) {
printf("%d\t", s->a[i]);
}
printf("\n");
}
void clear(stack* s) {
int i;
if (s->top<0) {
printf("栈已空!\n");
return;
}
for (i = 0; i < s->top; i++) {
s->a[i] = 0;//遍历数组,将栈内所有元素置0
}
s->top = -1;
}
void transform() {//进制转换函数
int num, base;//相应进制数
int i;
stack a;
a=initstack();
stack *s=&a;
printf("请输入一个十进制数及要转换的进制数:\n");
scanf("%d %d", &num, &base);
while (num / base >= 1) {
push(s, num % base);//把每次取模的结果压入栈
num = num / base;
}
push(s, num);//将最后的商压入栈
printf("转换后的结果为");
for (i = s->top; i >= 0; i--) {//将栈内元素逆序输出
printf("%d",s->a[i]);
}
printf("\n");
free(s->a);
}
void menu() {
printf("1.--初始化栈-----\n");
printf("2.---销毁栈----\n");
printf("3.----清空栈-----\n");
printf("4.----栈判空------\n");
printf("5.------求栈的长度----\n");
printf("6.----获取栈顶元素-----\n");
printf("7.----插入一个元素-----\n");
printf("8.----删除一个元素-----\n");
printf("9.----输出所有元素----\n");
printf("10.-----进制转换----\n");
printf("---退出,输入一个负数\n");
}
int main() {
Elemtype num;
stack a;
a.top=-1;
stack *s=&a;
int choice;
menu();
while (1) {
printf("请选择相应的模块\n");
scanf("%d", &choice);
if (choice < 0)
break;
else {
switch (choice) {
case 1:a = initstack();
break;
case 2:destroy(s);
break;
case 3:clear(s);
break;
case 4:isNull(s);
break;
case 5:length(s);
break;
case 6:gettop(s);
break;
case 7:if(!s->a)
{
printf("请先初始化!\n");
break;
}
else{
printf("请输入要插入的元素\n");
scanf("%d", &num);
push(s, num);
break;
}
case 8:pop(s);
break;
case 9:traverse(s);
break;
case 10:transform();
break;
default:printf("请输入1~10的数\n");
}
}
}
return 0;
}
|