‘壹’ 数据结构里顺序存储和链式存储判定栈空和栈满的条件分别是什么
顺序
空 top=-1;
满 top=maxsize-1
链式
空 top->next=null
动态分配空间,没有满
‘贰’ 请问一下c语言关于栈的基本应用
#include <stdlib.h>
010 #include <malloc.h>
011 #include <memory.h>
012 #include <assert.h>
/*------------------------------------------------------------
12 // 栈结构的定义
13 ------------------------------------------------------------*/
14 typedef struct Stack
15 {
16 ElemType *base; // 栈基址
17 ElemType *top; // 栈顶
18 int stacksize; // 栈存储空间的尺寸
19 } SqStack;
20
21 /*------------------------------------------------------------
22 // 栈的基本操作
23 ------------------------------------------------------------*/
24
25 bool InitStack(SqStack *S);
26 void DestroyStack(SqStack *S);
27 bool StackEmpty(SqStack S);
28 int StackLength(SqStack S);
29 bool GetTop(SqStack S, ElemType *e);
30 void StackTraverse(SqStack S, void (*fp)(ElemType));
31 bool Push(SqStack *S, ElemType e);
32 bool Pop(SqStack *S, ElemType *e);
33 bool bracketMatch(SqStack *S,const char *arr);
const int STACK_INIT_SIZE = 100; // 初始分配的长度
016 const int STACKINCREMENT = 10; // 分配内存的增量
017
018 /*------------------------------------------------------------
019 操作目的: 初始化栈
020 初始条件: 无
021 操作结果: 构造一个空的栈
022 函数参数:
023 SqStack *S 待初始化的栈
024 返回值:
025 bool 操作是否成功
026 ------------------------------------------------------------*/
027 bool InitStack(SqStack *S)
028 {
029 S->base = (ElemType *)malloc(STACK_INIT_SIZE *sizeof(ElemType));
030 if(S ->base == NULL)
031 return false;
032 S ->top = S ->base;
033 S->stacksize = STACK_INIT_SIZE;
034 return true;
035 }
036
037 /*------------------------------------------------------------
038 操作目的: 销毁栈
039 初始条件: 栈S已存在
040 操作结果: 销毁栈S
041 函数参数:
042 SqStack *S 待销毁的栈
043 返回值:
044 无
045 ------------------------------------------------------------*/
046 void DestroyStack(SqStack *S)
047 {
048 assert(S != NULL);
049 free(S ->base);
050 S->base = S->top = NULL;
051 }
052
053 /*------------------------------------------------------------
054 操作目的: 判断栈是否为空
055 初始条件: 栈S已存在
056 操作结果: 若S为空栈,则返回true,否则返回false
057 函数参数:
058 SqStack S 待判断的栈
059 返回值:
060 bool 是否为空
061 ------------------------------------------------------------*/
062 bool StackEmpty(SqStack S)
063 {
064 assert((S.base != NULL)&&(S.top != NULL));
065 return (S.base == S.top);
066 }
067
068 /*------------------------------------------------------------
069 操作目的: 得到栈的长度
070 初始条件: 栈S已存在
071 操作结果: 返回S中数据元素的个数
072 函数参数:
073 SqStack S 栈S
074 返回值:
075 int 数据元素的个数
076 ------------------------------------------------------------*/
077 int StackLength(SqStack S)
078 {
079 assert((S.base != NULL)&&(S.top != NULL));
080 return (S.top - S.base);
081 }
082
083 /*------------------------------------------------------------
084 操作目的: 得到栈顶元素
085 初始条件: 栈S已存在
086 操作结果: 用e返回栈顶元素
087 函数参数:
088 SqStack S 栈S
089 ElemType *e 栈顶元素的值
090 返回值:
091 bool 操作是否成功
092 ------------------------------------------------------------*/
093 bool GetTop(SqStack S, ElemType *e)
094 {
095 assert((S.base != NULL) && (S.top != NULL));
096 if(S.top == S.base)
097 exit(0);
098 *e = *(S.top - 1);
099 return true;
100 }
101
102 /*------------------------------------------------------------
103 操作目的: 遍历栈
104 初始条件: 栈S已存在
105 操作结果: 依次对S的每个元素调用函数fp
106 函数参数:
107 SqStack S 栈S
108 void (*fp)() 访问每个数据元素的函数指针
109 返回值:
110 无
111 ------------------------------------------------------------*/
112 void StackTraverse(SqStack S, void (*fp)(ElemType))
113 {
114 assert((S.base != NULL) && (S.top != NULL));
115 while(S.base < S.top)
116 {
117 (*fp)(*S.base);
118 S.base++;
119 }
120 }
121
122 /*------------------------------------------------------------
123 操作目的: 压栈——插入元素e为新的栈顶元素
124 初始条件: 栈S已存在
125 操作结果: 插入数据元素e作为新的栈顶
126 函数参数:
127 SqStack *S 栈S
128 ElemType e 待插入的数据元素
129 返回值:
130 bool 操作是否成功
131 ------------------------------------------------------------*/
132 bool Push(SqStack *S, ElemType e)
133 {
134 if(S == NULL)
135 return false;
136 assert((S->base != NULL) && (S ->top != NULL));
137 if(S ->top - S ->base >= S->stacksize)
138 {
139 S ->base = (ElemType *)realloc(S ->base,(S ->stacksize + STACKINCREMENT) * sizeof(ElemType));
140 if(! S ->base)
141 exit(0);
142 S ->top = S->base + S ->stacksize;
143 S ->stacksize += STACKINCREMENT;
144 }
145 *(S ->top++) = e;
146 return true;
147 }
148
149 /*------------------------------------------------------------
150 操作目的: 弹栈——删除栈顶元素
151 初始条件: 栈S已存在且非空
152 操作结果: 删除S的栈顶元素,并用e返回其值
153 函数参数:
154 SqStack *S 栈S
155 ElemType *e 被删除的数据元素值
156 返回值:
157 bool 操作是否成功
158 ------------------------------------------------------------*/
159 bool Pop(SqStack *S, ElemType *e)
160 {
161 if((* S).top == (*S).base)
162 return false;
163 *e = * --(* S).top;
164 return true;
165 }
‘叁’ 二级计算机怎么理解栈中的初始状态
栈的内容,画个图就好理解
‘肆’ 数据结构栈的基本操作
InitStack(&S)构造一个空栈;
DestroyStack(&S)栈s被撤销;
StackLength(S)计算栈的个数;
StackEmpty(S)初始条件:栈 S 已存在。 操作结果:若栈 S 为空栈,则返回 TRUE,否则 FALE;
GetTop(S, &e) 初始条件:栈 S 已存在且非空。操作结果:用 e 返回 S 的栈顶元素。
Push(&S, e) 初始条件:栈 S 已存在。 操作结果:插入元素 e 为新的栈顶元素。
Pop(&S, &e) 初始条件:栈 S 已存在且非空。 操作结果:删除 S 的栈顶元素,并用 e 返回其值。
‘伍’ 怎么初始化顺序栈
#include<stdio.h>
#include<stdlib.h>
#define elemtype int
typedef struct LsNode{
elemtype *elem;//给栈以动态形式分配内存,elem=(elemtype *)malloc(sizeof(elemtype)*length);
int length; //栈的空间大小,可以由用户来决定它的大小
int top;
} STACK;
//顺序存储的栈结构,以及其相应算法
void InitStack(STACK *S, int len)
{//初始化空栈
S->length=len;
S->elem = (elemtype *)malloc(sizeof(elemtype)*len);
S->top = -1;
}
int EmptyStack(STACK *S)
{//判断是否栈空,为空则返回1,否则返回0
if(S->top==-1){
return 1;
}
else{
return 0;
}
}
int push(STACK *S, elemtype x)
{//元素x进栈操作,成功返回1,否则返回0
if(S->top<S->length-1){
S->top++;
S->elem[S->top]=x;
return 1;
}
else{
return 0;
}
}
elemtype pop(STACK *S)
{//出栈操作,返回出栈元素
elemtype x;
if(EmptyStack(S)){
printf("栈为空");
return 0;
}
else{
x=S->elem[S->top];
S->top--;
return x;
}
}
void Print(STACK *S)
{//依次输出栈顶到栈底的所有元素
int i;
for(i=S->top;i>=0;i--){
printf("%4d",S->elem[i]);
}
printf("\n");
}
int main(void)
{
STACK *s=(STACK*)malloc(sizeof(STACK));
InitStack(s,100);
push(s,1);
push(s,2);
push(s,4);
Print(s);
push(s,5);
Print(s);
pop(s);
Print(s);
}
‘陆’ 动态和静态存储区中数据的初始化有什么不同
c语言中需要内存来存放数据。而内存主要分为两类:静态存储区和动态存储区;
1.静态存储区分为:只读数据(READONLY DATA)区、以读写数据(RW DATA)区、未初始化区(BSS)。它们都是在程序编译连接阶段确定的,在程序执行的阶段不会改变。
2.动态存储区分为堆和栈。都是程序执行的过程中动态分配的,大小也随之动态变化。从内存管理的实现的角度看来,堆使用的链表实现的,而栈使用的是线性存储的方法。
栈:栈是先进后出,实际的操作中,栈内存可以有满栈和空栈的情况,满栈的情况下,栈指针当前的位子是已经使用的的栈区域;空栈的情况是,栈指针当前的位子是没有使用的栈区域,所以两种情况的出入栈,指针和数据的操作先后顺序是不同的。
满栈时:入栈,是先移动指针,在放入数据;出栈则是先出数据,在移动指针;
空栈时:入栈,是先放入数据,在移动指针。出栈则是先移动指针,在出数据;
C语言必须注意的几个问题:
1.内存泄露:申请一块内存,但没有释放,程序结束也没回收,导致其他程序不能使用
2.野指针:指一个内存指针已经被释放free或者realloc,但指针依然在使用。避免野指针的情况,将内存的指针置为NULL,并在程序使用的时候判断该内存是否为NULL,如为空,则认为该内存已经释放,不对内存进行访问。
3.非法释放内存:原则上讲只有被malloc(),calloc()或realloc()分配并通过返回值返回返回的内存才能被释放,否则释放除此以外的内存都是非法的。即使有一个指针是*p是malloc,那么对p1=p++,这个时候free(p1)也是不合法的,但free(p)确实可以的。同样释放函数中的局部变量也是非法的.还有一种情况是,对一个堆内存释放两次也是错误的用法。因为free()函数是不能释放未分配的堆内存。在程序使用free释放内存之后,应该将指针置为NULL,free一个NULL地址是没有问题的。
‘柒’ C语言数据结构中,关于栈的初始化的问题!
不过是把int *S; S=(int*)malloc(sizeof(int));这两条语句合并成了一条而已
‘捌’ 为何在栈初始化时使用的是指针变量
这里就要牵涉到动态内存分配了,栈的定义如下
typedef struct IStack{
char *top; // 此为栈顶指针
char *base; // 此为栈底指针
int stackSize; // 此为栈的总大小
}IStack;
当对栈进行初始化时,我们来对其进行动态内存分配,假设程序中有个宏定义
#define MAX_SIZE 100 //用来定义栈的初始大小
void initStack(IStack *S){
S->base=(char*)malloc(sizeof(char)*MAX_SIZE);
if(!S->base) exit(0);
S->top=S->base;
S->stackSize=MAX_SIZE;
}
以上是初始化函数,也许直到此时,楼主依然不觉得使用指针有什么用处,那么接下来让我们思考一下如何对栈进行增加数据,说到这里的话,楼主可能就要好笑的说:不是这样增加的吗?——
*S->top='a';S->top++;
但是楼主要注意了,栈的初始大小只有100个char类型的空间,所以要是存储的字符超过了100个怎么办,这时候动态内存分配的强大就体现了,没错,动态内存允许我们在程序运行时为栈(指针实现)分配内存,分配语句如下:
#define OFFSETSIZE 10
S->base=(char*)realloc(S->base,(S->stackSize+OFFSETSIZE)*sizeof(char));
S->top=S->base+S->stackSize;
S->stackSize+=OFFSETSIZE;
楼主此时或许明白了一些问题,但是楼主在写main函数时,可能又遇到了一个问题,那就是如何给函数传递栈的参数,我们就拿栈的初始化函数initStack(IStack *S)来举例:
int main(){
IStack s;
initStack(&s);// 这里是传址调用,而非传值调用
return 0;
}
什么是传址调用,什么是传值调用,楼主可能觉得非常困惑,且听在下细细道来:
所谓的传值调用,只是把变量的值传递给了函数,即在函数中对那个传递过来的值无论作了什么修改,都不会体现到变量的本身上去,也就是变量的值并不会改变,因为变量仅仅是将本身的值传递给了函数,也就相当于变量将本身的一个副本传递给了函数,函数就算修改,修改的也不过是这个副本,与变量本身并没有关系
而所谓的传址调用就不同了,传址调用也就是将变量在内存中的地址传递给了函数,函数对这个地址上的值所做的任何修改都会体现到变量本身上去
我们在main函数中初始化栈s时必须进行传址调用(除非你采用返回值的方式,一般不推荐如此),否则我们对栈的初始化就不会体现到s本身上
‘玖’ 为什么栈的初始状态top等于m+1,则说明栈空时top=m+1
这是因为栈的初始状态是确定的。而栈的初始状态,也就是栈空的状态。所以,如果当栈的初始状态top等于m+1。那栈空时的top就等于m+1了。
栈的顺序存储空间为S(1:50),初始状态为top=0。现经过一系列入栈与退栈运算后,top=20,则栈顶-栈底=20-0=20个元素。
栈是向上增长的,每次压入一个元素,栈的TOP指针向上移动一位。当压入第一个元素时,TOP指针指向m+1-1 = m当压入第二个元素时,TOP指针指向m+1-2 = m-1。以此类推,当压入第N个元素时,TOP指针指向m+1-N = 20则N = m+1-20 = m-19。
(9)动态存储中栈的初始条件扩展阅读:
栈是允许在同一端进行插入和删除操作的特殊线性表。允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(PUSH),删除则称为退栈(POP)。栈也称为先进后出表。
在计算机系统中,栈则是一个具有以上属性的动态内存区域。程序可以将数据压入栈中,也可以将数据从栈顶弹出。在i386机器中,栈顶由称为esp的寄存器进行定位。压栈的操作使得栈顶的地址减小,弹出的操作使得栈顶的地址增大。