栈是一种限定性线性表,它只允许在线性表的一端进行操作,只允许对栈顶的元素读取和取出,同时也只允许在栈顶元素的上方push进新的元素,形成新的栈顶。用通俗的话说就是后进先出类型的线性表。栈的插入操作被形象的说明为进栈和入栈,删除操作被形容为出栈和退栈。
栈也分为几种类型(其实和表一样,分为顺序表和链表,但是其实在逻辑上都差不多,只不过在物理上和具体的实现上有区别),先看顺序栈吧!
#define TRUE 1
#define FALSE 0
#define STACK_SIZE 50
typedef int Eletype;
typedef struct stack {
Eletype ele_array[STACK_SIZE];
int top_off;
}SeqStack;
这个就是顺序表的头文件,其中定义了一些常量和最重要的栈的数据结构。
#include <stdio.h>
#include "seqstack.h"
void init_stack (SeqStack *S) {
S->top_off = -1;
}
int is_empty (SeqStack *S) {
return (S->top_off == -1) ? TRUE : FALSE;
}
int is_full (SeqStack *S) {
return (S->top_off == STACK_SIZE) ? TRUE : FALSE;
}
int push (SeqStack *S , Eletype x) {
if (S->top_off == STACK_SIZE)
return FALSE;
S->ele_array[S->top_off+1] = x;
S->top_off++;
return TRUE;
}
int pop (SeqStack *S , Eletype *e) {
if (S->top_off == -1)
return FALSE;
*e = S->ele_array[S->top_off];
S->top_off--;
return TRUE;
}
int get_top (SeqStack *S , Eletype *e) {
if (S->top_off == -1)
return FALSE;
*e = S->ele_array[S->top_off];
return TRUE;
}
其实顺序栈的实现还是比较简单的,这里有一个比较有趣的细节,就是在is_empty is_full get_top的实现当中明明可以不用指针来实现,为什么还要用指针那?其实这里还是比较好理解的,记得《c和指针》中专门有提过这个细节,因为无论是什么类型的指针,只要在32位系统上是4字节大小,在64位系统上应该是8字节大小的,而要直接传SeqStack的参数的话,复制开销比这个要大多了。好了今晚上就这么多,明天还要考机组,呵呵。
——————————————————————————————————————————分割线2016.6.20
下面把共享栈实现一下,很简单我就贴个代码啦,啊哈哈,考完啦,有很多时间泡在自己的博客上了,哈哈。
#define STACK_SIZE 1024
#define TRUE 1
#define FALSE 0
typedef char Ele_type;
typedef struct {
int top[2];
Ele_type data[STACK_SIZE];
}ShareStack;
这个是头文件的定义
#include <stdio.h>
#include "sharestack.h"
void init_sharestack (ShareStack *S) {
S->top[0] = -1;
S->top[1] = STACK_SIZE;
}
int push (ShareStack *S , Ele_type c , int i) {
if ((S->top[0]+1) == S->top[1]) {
printf ("the stack is full\n");
return FALSE;
}
switch (i) {
case 0:
S->top[0] += 1;
S->data[S->top[0]] = c;
break;
case 1:
S->top[1] -= 1;
S->data[S->top[1]] = c;
break;
default:
printf ("the arguement i error\n");
return FALSE;
}
return TRUE;
}
int pop (ShareStack *S , Ele_type *c , int i) {
if (i != 0 && i != 1) {
printf ("the arguement i error\n");
return FALSE;
}else if (i == 0) {
*c = S->data[S->top[0]];
S->top[0] -= 1;
}else if (i == 1) {
*c = S->data[S->top[1]];
S->top[1] += 1;
}
return TRUE;
}
这个是共享栈的实现,主要是初始化,进栈出栈这几个操作。
————————————————————————————————————————————分割线2016.6.24
书上的后面还有介绍了链栈,在这里我也对它进行实现。同样比较简单,我就在这里不用太多的篇幅介绍了。
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef int Ele_type;
typedef struct node {
Ele_type data;
struct node *next;
}LinkStack;
LinkStack *init_linkstack () {
LinkStack *S = (LinkStack *) malloc (sizeof (LinkStack));
S->next = NULL;
return S;
}
int push (LinkStack *S , Ele_type *c) {
LinkStack *p = (LinkStack *) malloc (sizeof (LinkStack));
if (p == NULL)
return FALSE;
p->data = *c;
p->next = S->next;
S->next = p;
return TRUE;
}
int pop (LinkStack *S , Ele_type *c) {
LinkStack *temp;
if (S->next == NULL) {
printf ("the stack is empty\n");
return FALSE;
}else {
temp = S->next;
*c = temp->data;
S->next = temp->next;
free (temp);
return TRUE;
}
}
主要是栈的初始化和进栈和出栈的操作。到这里的基本概念和基本操作就完成了,下面就是,栈的练习,我选择做书上的对死则运算加一个括号的方式进行练习。