ADT 栈(Stack)
Data
  栈的数据对象集合为{a1, a2,..., an},每个元素的类型均为DataType。其中除第一个元素a1以外,每个元素有且只有一个直接前驱元素;除了最后一个
  元素an以外,每个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。
Operation
  initStack(*S):       初始化操作,建立一个空栈S
  destoryStack(*S):     若栈存在,则销毁它
  stackEmpty(*S):     若栈为空,则返回true,否则返回false
  clearStack(*S):         将栈清空,栈本身还存在
  getTop(S, *e):        若栈存在且非空,用e返回S的栈顶元素
  push(*S, e):        若栈存在,插入新元素e到栈S中,并成为栈顶元素
  pop(*S, *e):              删除栈S中栈顶元素,并用e返回其值
  stackLength(L):     返回栈S的元素个数
endADT

先写一个Element.h的头文件:

 1 #ifndef ELEMENT_H_INCLUDED
 2 #define ELEMENT_H_INCLUDED
 3 #define MAX_SIZE 255
 4 #define TRUE 1
 5 #define FALSE 0
 6 
 7 
 8 
 9 typedef struct ElementType
10 {
11     int id;
12     char *name;
13 }ElementType;

定义顺序栈数据结构及常用操作,以下是关于顺序栈的头文件(SeqStack.h):

 1 #ifndef SEQSTACK_H_INCLUDED
 2 #define SEQSTACK_H_INCLUDED
 3 
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 #include "Element.h"
 7 
 8 typedef struct SeqStack{
 9     ElementType elements[MAX_SIZE];
10     int top;                                            //栈顶,如果为-1,则栈为空
11     int length;                                        //当前栈的长度
12 }SeqStack;
13 
14 /** 初始化栈*/
15 void InitSeqStack (SeqStack *seqStack);
16 
17 /** 压栈操作:向栈中压入元素,返回压如结果*/
18 int PushSeqStack (SeqStack *seqStack, ElementType element);
19 
20 /** 以指针的方式返回出栈的元素,返回值为出栈结果*/
21 int PopSeqStack (SeqStack *seqStack, ElementType *element);
22 
23 /** 清空栈*/
24 void ClearSeqStack (SeqStack *seqStack);
25 
26 /** 判断栈是否为空*/
27 int SeqStackEmpty (SeqStack *seqStack);
28 
29 /** 返回栈顶元素*/
30 void GetTopSeqStack (SeqStack *seqStack, ElementType *element);
31 
32 #endif // SEQSTACK_H_INCLUDED
33         

以下是关于顺序栈的.c文件(SeqStack.c):

 1 #include "SeqStack.h"
 2 
 3 /** 初始化栈*/
 4 void InitSeqStack (SeqStack *seqStack){
 5     seqStack->top = -1;                            //当top指向-1时表明栈内没有元素
 6     seqStack->length = 0;                         //同样的初始化时,栈的长度为0
 7 }
 8 
 9 /** 入栈操作:向栈中压入元素,返回压如结果*/
10 int PushSeqStack (SeqStack *seqStack, ElementType element)
11 {
12     if (seqStack->top == MAX_SIZE -1){    //压栈的过程当中需要先判断栈内元素是否是满的
13         printf("满栈,压栈操作失败!");
14         return FALSE;
15     }
16     /**
17        1 将顺序栈的栈顶指到下一个空间
18        2 将元素赋给新的栈顶
19        3 将栈的长度加1
20        4 最后若是压栈成功则返回TRUE
21     */
22     seqStack->top++;
23     seqStack->elements[seqStack->top] = element;
24     seqStack->length++;
25     return TRUE;                                       //由于事先define了TRUE和FALSE的值是1和0所以返回值用int来接收,下同
26 }
27 
28 /** 以指针的方式返回出栈的元素,返回值为出栈结果*/
29 int PopSeqStack (SeqStack *seqStack, ElementType *element)
30 {
31     if (seqStack->top == -1){
32         printf("空栈,出栈失败!");
33         return FALSE;
34     }
35     *element = seqStack->elements[seqStack->top];
36     seqStack->top--;
37     seqStack->length--;
38     return TRUE;
39 }
40 
41 /** 清空栈*/
42 void ClearSeqStack (SeqStack *seqStack)
43 {
44     seqStack->top = -1;
45     seqStack->length = 0;
46 }
47 
48 /** 判断栈是否为空*/
49 int SeqStackEmpty (SeqStack *seqStack)
50 {
51     if (seqStack->top == -1){
52         return TRUE;
53     }
54     return FALSE;
55 }
56 
57 /** 返回栈顶元素*/
58 void GetTopSeqStack (SeqStack *seqStack, ElementType *element)
59 {
60     if (seqStack->top == -1){
61         printf("空栈,栈顶元素为空!");
62         element = NULL;
63         return;
64     }
65     *element = seqStack->elements[seqStack->top];
66 }
67     

接下来在main.c中实现:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include "SeqStack.h"
 4 
 5 ElementType datas [] = {
 6     {1, "小A"},
 7     {2, "小B"},
 8     {3, "小C"},
 9     {4, "小D"},
10 };                             //由于是检测一下功能,就只取4个数据
11 
12 void TestSeqStack();
13  
14 void TestSeqStack(){
15     SeqStack *stack = (SeqStack *)malloc(sizeof(SeqStack));
16     ElementType *element = (ElementType *)malloc(sizeof(ElementType));
17     InitSeqStack(stack);
18     for (int i=0; i<4; i++){
19         printf("当前入栈的是:%d\t%s\n", datas[i].id, datas[i].name);
20         PushSeqStack(stack, datas[i]);
21         }
22     printf("\n");
23     PopSeqStack(stack, element);
24     printf("当前出栈元素是:%d\t%s\n", element->id, element->name);
25     printf("\n");
26     for (int i=0; i<stack->length; i++){
27         printf("当前栈内的元素是: %d\t%s\n", stack->elements[i].id, stack->elements[i].name);
28     }
29     free(stack);
30 }
31 
32 int main()
33 {
34     TestSeqStack();
35     return 0;
36 }

栈是按照FILO(先入后出)或者LIFO(后入先出)的原则,关于链栈的一些笔记在之后给出

根据栈的一些特性,我们可以用来实现一些信息的有序存储,例如在一些回合制的游戏当中可以运用这种栈的结构,可以按照一定的顺序来存入玩家的操作数据,来方便对玩家的操作进行回撤。

 

 posted on 2019-04-21 17:14  TheNobody  阅读(165)  评论(0编辑  收藏  举报