顺序栈和链栈的各种操作
2011-08-19 09:28
399 查看
一.先说顺序栈
二.再说链栈
先看验证注释(1)的运行结果截图
如果按照之前说的,将Init函数改成传二重指针的方式,在main里面仅仅给top=NULL,z Init里面再给top换个值,也就是开辟一段内存。这样就可以了,后面的(2)就可以正常运行了。
具体改动:
1.InitStack中
2.main中
看一下运行结果截图:
最后看正常情况下程序的运行结果的图
/********************************************************** 顺序栈的各种操作13-5-1.cpp 1.初始化栈 2.判断栈空 3.入栈 4.出栈 5.取栈顶元素 6.主函数测试以上功能 ***********************************************************/ #include<stdio.h> #include<stdlib.h> #define MAX 1000 typedef struct { int data[MAX]; int top; }SeStack; void InitStack(SeStack *S) { S->top=-1; } int EmptyStack(SeStack *S) { return ((S->top==-1)?1:0); } int Push(SeStack *S, int x) { if(S->top==MAX-1) { printf("栈满!\n"); return 0; } S->data[++S->top]=x; return 1; } int Pop(SeStack *S, int *x) { if(EmptyStack(S)) { printf("栈空!\n"); return 0; } *x=S->data[S->top--]; return 1; } int GetTop(SeStack *S, int *x) { if(EmptyStack(S)) { printf("栈空!\n"); return 0; } *x=S->data[S->top]; return 1; } int main() { SeStack *S=(SeStack *)malloc(sizeof(SeStack)); int n, x, fx, j; InitStack(S); printf("输入入栈元素个数:\n"); scanf("%d",&n); for(int i=1; i<=n; i++) { Push(S, i); } GetTop(S, &fx); printf("栈顶元素:%d\n", fx); printf("栈中元素:\n"); for(j=S->top; j>-1; j--) { printf("%3d",S->data[j]); } for(int i=1; i<=n; i++) { Pop(S, &x); printf("\n出栈元素为:%d\n", x); } system("pause"); return 0; }
二.再说链栈
/********************************************************** 链栈的各种操作13-5-2.cpp和13-5-3.cpp 1.初始化栈 2.判断栈空 3.入栈 4.出栈 5.取栈顶元素 6.主函数测试以上功能 ***********************************************************/ #include<stdio.h> #include<stdlib.h> typedef struct Lnode { int data; struct Lnode *next; }LinkList; typedef LinkList LinkStack; void InitStack(LinkStack *top) { /* top=(LinkStack *)malloc(sizeof(LinkStack));//(1) if(top==NULL) { printf("分配空间失败!\n"); return 0; } */ //printf("(InitStack)top addr:%x\n", top); top->next=NULL; //return 1; } int EmptyStack(LinkStack *top) { return ((top->next==NULL)?1:0); } int Push(LinkStack *top, int x) { LinkStack *s=(LinkStack *)malloc(sizeof(LinkStack)); if(s==NULL) { printf("分配空间失败!\n"); return 0; } s->data=x; s->next=top->next; top->next=s; //printf("(Push)top addr:%x\n", top); return 1; } int Pop(LinkStack *top, int *x) { LinkStack *p; if(EmptyStack(top)) { printf("栈空!\n"); return 0; } *x=top->next->data; p=top->next; top->next=p->next; //printf("(Pop)top addr:%x\n", top); free(p); return 1; } int GetTop(LinkStack *top, int *x) { if(EmptyStack(top)) { printf("栈空!\n"); return 0; } *x=top->next->data; return 1; } int main() { LinkStack *top=(LinkStack *)malloc(sizeof(LinkStack)); //printf("(main)top addr:%x\n", top); LinkStack *p; int n, x, fx; InitStack(top); printf("输入入栈元素个数n:\n"); scanf("%d", &n); for(int i=1; i<=n; i++) { Push(top, i); } GetTop(top, &fx); printf("栈顶元素:%d\n", fx); printf("栈中元素:\n"); for(p=top->next; p!=NULL; p=p->next)//(2) { printf("%3d", p->data); } for(int i=1; i<=n; i++) { Pop(top, &x); printf("\n出栈元素为:%d\n", x); } system("pause"); return 0; } /************************************************************************************* 注意:(1)注意这段注释掉的代码,我习惯性的按照链队列里面初始化队列的方式来初始化 链栈,结果导致运行(2)处,发生地质访问错误。仔细分析一下:(2)处的p移动到最后一个 节点的时候,再往后移动一个就出问题了。按理说最后一个节点的next应该是NULL,看 InitStack函数,确实应该在一开始就给top->next=NULL,但是我在InitStack函数里面却 又申请了一个内存空间,实际上就是给top又赋了一个新的地址,相当于传个参数(指针top) 进去又在函数里面改变了它的地址(给to赋了一个新地址),但是根据函数改变参数的机制, 只有使用二重指针做参数或者传递引用的时候,才能实际的改变参数。如果仅传一个一维指 针,只能改变指针里存的值,不能改变指针本身。这个和p65页面试题很像。可以看验证 截图。main中开辟的空间的首地址是x714e38赋给top,IintStack函数中又给top一个新地 址x714e80,但是IintStack结束之后,到了Push, Pop函数,地址皆为x714e38,和main 中的一样。也就验证了地址在InitStack结束之后根本木有改变。既然这样,在InitStack中给 top->next赋值为NULL,InitStack结束之后,top还是x714e38,这个top的next根本不知 道是什么,所以Push到最后一个的时候,最后一个元素的next就不知道是什么了,因为是由 top->next觉定的,所以也就发生了内存错误。所以再说一点就是建立栈操作时候,想在main函数中给top赋个NULL,然后在Init中开辟空间的,是不行了,要么在主函数中开辟空间给指针赋值,然后到init中直接传过去,注意,通过传参,在别的函数体力就改变不了指针值了。如果习惯在主函数中不管,赋值的活交给Init函数的话,就是用二重指针方式了。 ***************************************************************************************/
先看验证注释(1)的运行结果截图
如果按照之前说的,将Init函数改成传二重指针的方式,在main里面仅仅给top=NULL,z Init里面再给top换个值,也就是开辟一段内存。这样就可以了,后面的(2)就可以正常运行了。
具体改动:
1.InitStack中
int InitStack(LinkStack **top) { *top=(LinkStack *)malloc(sizeof(LinkStack));//(1) if(*top==NULL) { printf("分配空间失败!\n"); return 0; } printf("(InitStack)top addr:%x\n", *top); (*top)->next=NULL; return 1; }
2.main中
int main() { //LinkStack *top=(LinkStack *)malloc(sizeof(LinkStack)); LinkStack *top=NULL; … InitStack(&top); … }//去掉上面的,不用给top赋实际地址了,在调用InitStack(&top)的 //时候传递top的地址过去就行了,改到InitStack里面来改变top的值。
看一下运行结果截图:
最后看正常情况下程序的运行结果的图
相关文章推荐
- 顺序栈和链栈的各种操作
- 顺序栈和链栈的各种操作
- 顺序栈和链栈的基本操作
- 顺序栈和链栈的基本操作
- 学习之路四:各种异步操作我也来山寨一下 → 思维导图
- Java对各种文件的操作详解
- Selenium + Webdriver 学习(二) 各种浏览器简单操作
- Oracle数据库的概念(权限、角色)以及各种操作(创建表空间、创建表、查询、更新、删除、插入)和常用函数
- Hash表各种基本操作
- 阻塞与死锁(二)——各种操作对锁的申请
- 数据结构第一题线性表的各种操作SqList
- net,C#,Ftp各种操作,上传,下载,删除文件,创建目录,删除目录,获得文件列表
- gridview+checkbox的各种操作【转】
- 有关清空表单的各种可能的操作
- hdu 3397 Sequence operation(线段树的各种操作)
- Unity3D 学习笔记3——了解U3D引擎的操作面板和各种工具
- iOS sqlite对数据库的各种操作(日常整理全)
- java.io.File类各种文件操作
- 二叉查找树的各种操作C++实现
- 通过JSCH 实现FTP各种操作