栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。是一种后进先出(LIFO)的数据结构。
一.栈的顺序存储
如图,左图为空栈,右图为已存放数据的栈。不难发现,栈只有一个口子,数据只能从一端进行入栈(push)和出栈(pop)操作。数据data的入栈顺序为 0, 1, 2.因此,出栈顺序只能为2, 1,0,从栈顶向栈底依次取出。
1 //顺序栈 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 typedef int Status; 6 typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */ 7 8 #define STACK_INTI_SIZE 100 //存储空间初始分配量 9 #define STACKINCREMENT 10 //存储空间分配增量 10 11 #define OK 1 12 #define ERROR 0 13 #define INFEASIBLE -1 14 #define OVERFLOW -2 15 16 typedef struct { 17 SElemType *base; 18 SElemType *top; //栈顶指针 19 int stacksize; //当前已分配的存储空间 20 }SqStack; 21 22 Status InitStack(SqStack &S); 23 Status DestroyStack(SqStack &S); 24 Status ClearStack(SqStack &S); 25 bool StackEmpty(SqStack S); 26 int StackLength(SqStack S); 27 Status GetTop(SqStack S, SElemType &e); 28 Status Push(SqStack &S, SElemType e); 29 Status Pop(SqStack &S, SElemType &e); 30 Status StackTraverse(SqStack S, Status(*visit)(SElemType e)); 31 32 Status visit(SElemType c) 33 { 34 printf("%d ", c); 35 return OK; 36 } 37 /*操作结果:构造一个空栈S*/ 38 Status InitStack(SqStack &S) 39 { 40 S.base = (SElemType *)malloc(STACK_INTI_SIZE * sizeof(SElemType)); 41 if (!S.base) exit(OVERFLOW); 42 S.top = S.base; 43 S.stacksize = STACK_INTI_SIZE; 44 return OK; 45 } 46 /*初始条件:栈S已存在。 47 操作结果:栈S被销毁*/ 48 Status DestroyStack(SqStack &S) 49 { 50 free(S.base); 51 free(&S); 52 S.top = NULL; 53 S.base = NULL; 54 S.stacksize = 0; 55 return OK; 56 } 57 /*初始条件:栈S已存在。 58 操作结果:将S清为空栈*/ 59 Status ClearStack(SqStack &S) 60 { 61 S.top = S.base; 62 return OK; 63 } 64 /*初始条件:栈S已存在。 65 操作结果:若栈S为空栈,则返回TRUE,否则FALSE*/ 66 bool StackEmpty(SqStack S) 67 { 68 if (S.top == S.base) 69 return true; 70 else 71 return false; 72 } 73 /*初始条件:栈S已存在。 74 操作结果:返回S的元素个数,即栈的长度*/ 75 int StackLength(SqStack S) 76 { 77 return (S.top - S.base); 78 } 79 /*初始条件:栈S已存在且非空。 80 操作结果:用e返回S的栈顶元素*/ 81 Status GetTop(SqStack S, SElemType &e) 82 { 83 if (S.top == S.base) return ERROR; //若栈空 返回ERROR 84 e = *(S.top - 1); 85 return OK; 86 } 87 /*初始条件:栈S已存在。 88 操作结果:插入元素e为新的栈顶元素*/ 89 Status Push(SqStack &S, SElemType e) 90 { 91 if (S.top - S.base >= S.stacksize) { //栈满追加存储空间 92 S.base = (SElemType *)realloc(S.base, 93 (S.stacksize + STACKINCREMENT) * sizeof(SElemType)); 94 if (!S.base) exit(OVERFLOW); //存储分配失败 95 S.top = S.base + S.stacksize;/*realloc可能返回了新的地址,所以top的地址需重新确定。*/ 96 S.stacksize += STACKINCREMENT; //更新stacksize的值 97 } 98 *S.top++ = e; //*S.top = e; S.top++ 99 return OK; 100 } 101 /*初始条件:栈S已存在且非空。 102 操作结果:删除S的栈顶元素,并用e返回其值*/ 103 Status Pop(SqStack &S, SElemType &e) 104 { 105 if (S.top == S.base) return ERROR; 106 e = * --S.top; //S.top--; e = *S.top; 107 return OK; 108 } 109 /*初始条件:栈S已存在且非空。 110 操作结果:从栈底到栈顶依次对S的每个数据元素调用函数visit()。 111 一旦visit()失败,则操作失败。*/ 112 Status StackTraverse(SqStack S, Status(*visit)(SElemType e)) 113 { 114 if (S.base == S.top) 115 { 116 printf("栈为空!"); 117 return ERROR; 118 } 119 for (SElemType *p = S.base;p < S.top;p++) 120 visit(*p); 121 122 printf("\n"); 123 return OK; 124 } 125 int main() 126 { 127 SqStack s; 128 int e,length; 129 130 if (InitStack(s) == OK) 131 for (int j = 1;j <= 10;j++) 132 Push(s, j); 133 length = StackLength(s); 134 StackTraverse(s,visit); 135 printf("length = %d\n", length); 136 if (StackEmpty(s) == true) 137 printf("empty!\n"); 138 else printf("not empty!\n"); 139 Pop(s, e); 140 printf("e = %d\n", e); 141 ClearStack(s); 142 if (StackEmpty(s) == true) 143 printf("empty!\n"); 144 else printf("not empty!\n"); 145 DestroyStack(s); 146 if (StackEmpty(s) == true) 147 printf("empty!\n"); 148 else printf("not empty!\n"); 149 system("pause"); 150 return 0; 151 }