你在main里调用InitStack初始化栈,后面就可以Push Pop进出了
B. c语言 为什么栈的初始化时候栈顶指针要指向-1
这种初始化是用于线性栈的,也就是用一个数组来组成栈,栈顶指针厅消值为当前栈顶元素的下标值。
当有数据入栈时,会先执行栈顶指针自加。
初始化为空栈,
规定空栈的时候指向-1,这样在有握伏知第一个元素入栈的时候栈段消顶指针就可以通过自加指向0元素,从而避免其它判断。
C. C语言中如何初始化栈 每个元素均为空
<1>如果顺序栈的定义如下
typedef struct
{datatype data[stacksize];
int top;
}SeqStack;
---则置空栈的操作如下
void InitStack(seqstack *s)
{s->top=-1;
}
<2>如果链栈的定义如下
typedef struct node
{datatype data;
struct node *next;
}LinkStack;
---则置空栈的操作如下
void InitStack(linkstack *s)
{s->top=null;
}
D. C语言中链栈 栈顶指针始终指向NULL
你的问题很仿拿简单,就是你没有区分清楚函数形参和实参之间传值和传址的区别。
#include <stdio.h>
#include <malloc.h>
typedef struct node { int data;
struct node *next;
} stacknode;
/*
stacknode *initnode()
{
stacknode *top; //这声明的是个局部变量,你这里这样用是没有意义的,因为局部变量在函数结束后就释放了
top = NULL;
return top;
}
//修改为:*/
void initnode(stacknode **top)
{
*top = NULL;
}
int emptynode(stacknode * top) //判空
{
if (top == NULL)
return 1;
else
return 0;
//return top == NULL;//可写为一行代备乎搭码
}
/*从本质上来说,函数调用都是值传递的。这里,crnode(top)的实参top把top的值赋给了crnode函数里形参top的值,即相当于top(形参) = top(实参);注意,这里两个top是不一样的变量,两者的内存地址也不同,形参top是crnode函数里分配的内存,而实参top则是main函数里分配的内存。所以你crnode函数里去改变top的值当然就不会相对应的改变main函数里top的值*/
/*void crnode(stacknode * top) //进栈
{
stacknode *p; int i;
for (i = 0; i < 5; i++) {
p = (stacknode *) malloc(sizeof(stacknode));
printf("input data:\n");
scanf("%d", &p->data);
p->next = top;
top = p; //这样是无法改变主函数里top的值的,只是改变了该函数里top指针的值
}
}
//修改为:*/
void crnode(stacknode ** top) //进栈,
{
stacknode *p; int i;
for (i = 0; i < 5; i++) {
p = (stacknode *) malloc(sizeof(stacknode));
printf("input data:\n");
scanf("%d", &p->data);
p->next = *top;
*top = p;
}
}
int numnode(stacknode * top) //计栈中结点数
{
stacknode *p, *s;
int i = 0; //i应该从0开始,这样当top为NULL时i才会为0
s = top;
while (s != NULL) {
p = s->next;
s = p;
i++;
}
return i;}
void outnode(stacknode * top) //出栈
{
stacknode *p;
int x;
while (top != NULL) {
x = top->data;
printf("%d\t", top->data);
p = top->next;
top = p;
//top = top->next;//上面两个代码写为一行就行了。。。
}
}
void main()
{
int i;
stacknode *top;
initnode(&top);//top = initnode();
i = emptynode(top);
if (i == 1)
printf("栈空");
crnode(&top);/顷老/crnode(top);
i = emptynode(top);
if (i == 1)
printf("栈空");
printf("%d\n", numnode(top));
outnode(top);
i = emptynode(top);
if (i == 1)
printf("栈空");
}
E. C语言中链栈 栈顶指针始终指向NULL
调用c函数是把实参值传给形参,在
crnode(top);
这一句处,是把top
这个指针的值,也就是NULL
传个函数培判脊crnode
的形参,在进栈时,只是对crnode函数里的
top
变量做了改变,如top
=
p;
但是
在main函数里的
top
和
crnode函数里的
top
完全是两个不同的变量,所以main
函数里的
top
始终为NULL。
另外说一下,你刚开始学编程吧,编程要仔细理解你写的东西到底做什么用,也就是真正了解你的代码,就像你写的那个初始化函数,仅仅是返回一个空值给了top,其他什么都没做,还不如直接
top
=
NULL
来的爽快。
又例如这个函数
void
outnode(stacknode
*top)//出栈
{
stacknode
*p;
int
x;
while(top!=NULL)
{
x=top->data;
printf("%d\t",top->data);
p=top->冲散next;
top=p;
}
}
你定义配渗的
x
是干什么用的,仅仅是为了给它赋个值吗?
等等吧,再好好看看书吧,编程要仔细理解
F. C语言链栈问题
#include<stdio.h>
#include<malloc.h>
#define null 0
typedef struct node
{
int data;
struct node *next;
}linkstack;
linkstack *top;
/*linkstack *initstack(linkstack *top) //初始化栈将栈的数据设空//
{
top->next=null;
return top;
} 这个函数没必要。return (top->next==null);也是错的。*/
linkstack *push(linkstack *top,int x) ////入栈
{
linkstack *p;
p=(linkstack*)malloc(sizeof(linkstack));
p->data=x;
p->next=top;////要理解栈的结构,栈顶是链表的头部,所以p->next要指向即时的top////
top=p;
return top;
}
linkstack* pop(linkstack *top) //出栈
{
linkstack *p;
if(!top)
{
printf("空链栈");
return null;
}
p=top;
top=top->next;
free(p); //释放存储空间
return top;
}
void print(linkstack *top) //输出栈
{
linkstack *p;
p=top;
while(p!=null) ////刚开始栈顶的next项为空////
{
printf("%d\n",p->data);
p=p->next;
}
}
void main()
{
int x,i;
top=(linkstack*) malloc(sizeof(linkstack));
scanf("%d",&x);
top->data=x;//头部赋值。
top->next=null;
// initstack(top);
for(i=1;i<=3;i++)
{
scanf("%d",&x);
top=push(top,x);//返回一个指针。
}
print(top);
top=pop(top);//返回一个指针。
print(top);
}
G. C语言解决链栈
#include<stdio.h>
//#include<stdlib.h>
#include<malloc.h>
typedefintDataType;
typedefstructnode{
DataTypedata;
structnode*next;
}Node,*Stack,*ps;
StackGetEmptyStack(){
Stacks=(ps)malloc(sizeof(Node));
s->next=NULL;
returns;
}
voidInitStack(Stack&s){//链栈初始化
s=(ps)malloc(sizeof(Node));//配置头结点方便后续操作
s->next=NULL;
}
voidDestroyStack(Stacks){//销毁链栈
psq,p=s->next;
while(p) {//依次释放链栈的每一个结点
q=p;
p=p->next;
free(q);
//p=s;
}
free(s);//最后删除头结点
}
voidPush(Stack&s,DataTypex){//入栈操作
pst=(ps)malloc(sizeof(Node));
t->data=x;
t->next=s->next;
s->next=t;
}
intEmpty(Stacks){
return(s->next==NULL);
}
intPop(Stacks,DataType*ptr){
psp;
if(Empty(s)){
printf("下溢错误,删除失败。
");
ptr=NULL;
return0;//0返回值时,ptr指向的内容不可用
}
p=s->next;
*ptr=p->data;//存取要删除的栈顶元素
s->next=p->next;//头指针指向下一个数据结点
free(p);
return1;
}
intGetTop(Stacks,DataType*ptr){//取栈顶元素
if(Empty(s)){
printf("下溢错误。
");
return0;
}
*ptr=s->next->data;
return1;
}
intmain(){
DataTypex;
Stacks=GetEmptyStack();//定义链栈的栈顶指针并初始化
// InitStack(s);//指针相当于一个地址&
printf("对15和10进行入栈操作
");
Push(s,15);
Push(s,10);
if(GetTop(s,&x))printf("当前栈顶元素为:%d
",x);//输出当前栈顶元素10
if(Pop(s,&x))printf("执行一次出栈操作,等同于删除栈顶元素:%d
",x);//输出出栈元素10
if(GetTop(s,&x))printf("现在的栈顶元素为:%d
",x);//输出当前栈顶元素15
printf("请输入待插元素:");
scanf("%d",&x);
Push(s,x);
if(Empty(s))printf("栈为空。
");
elseprintf("栈并不为空。
");
return0;
}
H. 求编程高手用c语言编写链栈完整源代码
/****************************************************************************************
实现链栈各种基本运算的算法 *
编写程序实现链栈种基本运算,并在此基础上设计一个主程序完成如下功能:
1、 初始化栈
2、 判断栈是否为空
3、 依次进栈a,b,c,d,e元素。
4、 判断栈是否为空
5、 输出栈的长度
6、 输出从栈顶到栈底元素
7、 输出出栈序列
8、 判断栈是否为空
9、 释放栈/
*********************************************************************************************/
#include<iostream.h>
#include<stdlib.h>
#include<stdio.h>
#define OVERFLOW -2
#define ok 1
#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKCREMENT 10 //增加分量
typedef struct{
char *base;
char *top;
int stacksize;//当前分配的空间
int lenght;
}SqStack; //Sqlist
/*********************************初始化栈*************************************/
int InitStack(SqStack &S)
{
S.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));// 分配存储空间
if(!S.base) exit(0);
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
S.lenght=0;
return 1;
}
/******************************************************************************/
/********************************判断栈是否为空******************************/
bool StackEmpty(SqStack&S){
if(S.top==S.base)return 1;
else
return 0;
}
/*****************************释放栈********************************/
int FreeStack(SqStack&S)
{
free(S.base);
S.top=S.base;
return ok;
}
/******************************************************************/
/*********************求出栈的长度*********************************/
int StackLenth(SqStack&S){
S.lenght=S.top-S.base;
return S.lenght;
}
/******************************************************************/
/**********************入栈*****************************************/
int Push(SqStack &S,char e){
if(S.lenght>=S.stacksize){
S.base=(char*)realloc(S.base,(S.stacksize+STACKCREMENT)*sizeof(char));//增加分配存储
if(!S.base) exit(OVERFLOW);
S.top=S.base+S.stacksize;
S.stacksize+=STACKCREMENT;
}
*S.top++=e;
S.lenght++;
return ok;
}
/**************************************************************/
/****************************出栈****************************/
char Pop(SqStack&S,char &e){
if(S.base==S.top)
return 0; //当栈为空时,返回错误
else
e=*--S.top;
S.lenght--;
return e;
}
/*************************显示*******************************/
void DispStack(SqStack S)
{
int i;
for(i=S.lenght;i>0;i--)
{
printf("%c",*(--S.top));
}
printf("\n");
}
//*******************主函数************************************/
int main(){
int i;
SqStack Lst;
char a,b,c,d,e,f;
char g;
printf("初始化栈:\n");
InitStack(Lst);
printf("依次进栈元素a,b,c,d,e,f\n");
cin>>a>>b>>c>>d>>e>>f;
Push(Lst,a);
Push(Lst,b);
Push(Lst,c);
Push(Lst,d);
Push(Lst,e);
Push(Lst,f);
printf("打印\n");
DispStack(Lst);
int l=StackLenth(Lst);
cout<<"栈的长度为"<<l<<endl;
printf("出栈序列:");
for(i=1;i<=6;i++)
{
Pop(Lst,g);
printf("%c ",g);
}
printf("\n");
printf("栈为:%s\n",(StackEmpty(Lst)?"空":"非空"));
printf("释放栈\n");
FreeStack(Lst);
return 0;
}
可以正确运行,你看下可以不??希望能帮到楼主! 我用visual C++6.0编译的,现在主流都是用这个,不好意思,WINTC我没有用过,楼主可以自己改吗??
额,你们老师太不人道了,WINTC好像在后面得加一个getch()吧??这个软件我没有用过
I. C语言数据结构 栈的初始化
base被定义为int的指针,却传给他一个char型的指针
char和int虽然经常通用,但char是8位,int是16位,两者还是不一样的。
J. 链表初始化的问题,指针问题。
最近学习链表栈队列时候,发现逻辑上来说这几个问题是很容易就搞明白的,但是具体实现尤其是用C语言实现,这个指针参数的传入,有很大的问题,还牵扯到malloc函数的亮模调用的用法,我来一一总结一下。
关于栈链初始化,我们一般来说用以下方法。
typedef struct SNode *Stack;
typedef struct SNode{
ElementType Data;
Stack Next;
};
Stack InitStack(){
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Next=NULL;
return S;
}
我们先定义了一个SNode的结构体,是节点,然后我们定义了Stack 是一个指针变量指向了SNode,实际上它就是链表的最开始的头指针,然后我们进行初始化,定义头节点指针为S,这时候我们注意,Stack是一个指针型变量,指向的是结构体,因此,malloc分配函数直接进行强制转化 左边括号就是Stack, 转化成了一种指针类型,我们顺便复习一下malloc的用法,malloc函数分配就是动态的分配内存,右边括号是计算出需要用的字节数,也即是我们申请存放变量的类型字节数,前面的括号里的即是要转化成的指针类型,是属于一种强制类型转化。最后我们定义S的下一个节点是空,这样就可以完成初始化了形成一个空栈。
值得一提的是,malloc申请分配完的内存在使用完毕后需要free,将其释放。
再例如以下初始化。
typedef struct Node
{
StackElementType data;
struct node *next;
} LinkStackNode;
typedef LinkStackNode *LinkStack;
void initStack(LinkStack *L)
{
*L=(LinkStack)malloc(sizeof(Node))
(*L)->next=NULL;
}
这种初始化和上面那种初始化实际上是一样的,虽然看起来有较大差异,同样的,我们定义了一个Node节点的结构体,然后LinkStack是一个指向结构敬正缓体的指针,我们初始化的参数是一个指向指针的指针L,因此在初始化过程清渗中我们用的是*L,这里的*L是指向头节点的指针变量也即使前一种方法里面的Stack。
我们一定要分清楚,前者是不用二重指针的,因为它有了返回值,而后者需要用二重指针,原因就在于我们需要改变一重指针的下一个节点,也就是改变一重指针的内容,因此我们需要用到指向该一重指针的指针,也就是二重指针,听起来很难理解,但是实际上我们可以把一重指针想象成一个普通变量,我们要在函数里修改该变量并且将其返回主函数,要么是有返回值,要不然就是传入该变量的地址,通过该地址来改变,也即使传入该变量的指针,这么说想必大家就明白了这两种方法的区别。链表初始化的问题也就搞明白了,链表初始化的目的就是我们要新建一个头指针,让其指向为空。