[简述]数据结构-栈(c语言实现)
second60 20180422
1. 栈的定义
栈是一种只能在一端进行插入或删除操作的线性表。
表中只允许插入的一端叫栈顶,另一端叫栈底。
栈的特点是:后进先出。
2. 栈的抽象数类型定义
ADT Stack
{
数据对象:
D={ai | i<=i <= n,n>=0,ai ElemType类型}
数据关系:
R={<ai, ai+1> | ai,ai+1为D}
基本运算:
InItStack(&s):初始化栈
ClearStack(&s):销毁栈
StackLength(s):栈长度
StackEmpty(s):栈是否空
Push(&s,e):入栈
Pop(&s,&e):出栈
GetTop(s,&e):取栈顶元素
DispStack(s):打印栈
}ADT Stack
3. 栈的顺序储存结构
typedef struct
{
ElemType data[MAXSIZE];
int top;
}SqStack;
算法代码如下,C语言实现,已编译通过:
#include "stdio.h"
#define MAXSIZE 15
typedef int ElemType;
typedef struct
{
ElemType data[MAXSIZE];
int top;
}SqStack;
void InitStack(SqStack **s)
{
*s = (SqStack*)malloc(sizeof(SqStack));
(*s)->top = -1;
}
void ClearStack(SqStack **s)
{
if(s!= NULL && *s != NULL)
free(*s);
}
int StackLength(SqStack *s)
{
return (s->top +1);
}
int StackEmpty(SqStack *s)
{
return (s->top == -1);
}
int Push(SqStack **s,ElemType e)
{
if((*s)->top == MAXSIZE -1)
return 0;
(*s)->top ++;
(*s)->data[(*s)->top] = e;
return 1;
}
int Pop(SqStack **s,ElemType *e)
{
if((*s)->top == -1)
return 0;
*e = (*s)->data[(*s)->top];
(*s)->top --;
return 1;
}
int GetTop(SqStack *s,ElemType *e)
{
if(s->top == -1)
return 0;
*e = s->data[s->top];
return 1;
}
void DispStack(SqStack *s)
{
int i;
for(i=s->top; i>=0;i--)
printf("%d ",s->data[i]);
printf("\n");
}
int main()
{
int value = 0;
SqStack *stack;
InitStack(&stack);
Push(&stack,1);
Push(&stack,2);
Push(&stack,3);
Push(&stack,4);
DispStack(stack);
GetTop(stack,&value);
printf("stack top=%d\n",value);
Pop(&stack,value);
printf("stack pop=%d\n", value);
DispStack(stack);
getchar();
return 1;
}
4. 栈的链式储存结构
数据类型定义
typedef struct linknode
{
ElemType data;
struct linknode *next;
}LiStack;
算法实现,C语言,已自测通过:
#include <stdio.h>
#define MAXSIZE 15
typedef int ElemType;
typedef struct linknode
{
ElemType data;
struct linknode *next;
}LiStack;
void InitStack(LiStack **s)
{
*s = (LiStack*)malloc(sizeof(LiStack));
(*s)->next = NULL;
}
void ClearStack(LiStack **s)
{
LiStack *p = (*s)->next;
while( p != NULL)
{
free((*s));
*s = p ;
p = p->next;
}
free((*s));
}
int StackLength(LiStack *s)
{
int i = 0;
LiStack *p = s->next;
while(p!= NULL)
{
i++;
p = p->next;
}
return i;
}
int StackEmpty(LiStack *s)
{
return s->next == NULL;
}
void Push(LiStack **s,ElemType e)
{
LiStack *p;
p = (LiStack*)malloc(sizeof(LiStack));
p->data = e;
p->next = (*s)->next;
(*s)->next = p;
}
void Pop(LiStack **s,ElemType *e)
{
LiStack *p ;
if((*s)->next == NULL)
return 0;
p = (*s)->next;
*e = p->data;
(*s)->next = p->next;
free(p);
return 1;
}
int GetTop(LiStack *s,ElemType *e)
{
if(s->next == NULL)
return 0;
*e = s->next->data;
return 1;
}
void DispStack(LiStack *s)
{
LiStack *p = s->next;
while(p != NULL)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
int main()
{
int value = 0;
LiStack *stack;
InitStack(&stack);
Push(&stack,10);
Push(&stack,20);
Push(&stack,30);
Push(&stack,40);
Push(&stack,50);
DispStack(stack);
GetTop(stack,&value);
printf("stack top=%d\n",value);
Pop(&stack,value);
printf("stack pop=%d\n", value);
DispStack(stack);
getchar();
return 1;
}
5. 栈的运用
栈是一种最常用,最重要的数据结构之一。基本上无处不在。
例如:
1.汇编函数调用实现就是用了栈的原理,保存现场,恢复现场(最重要了吧)
2.很多算法中用了栈,如二叉树,递归调用等
3.在各类调度系统中,linux内核中很常见
6. 总结
早上起来,喝了杯茶,顺便温习下栈,代码都是手敲的,是但不觉得累,学习也是一种快乐,非常重要的数据结构。下一篇,队列,同样重要。