数据结构算法C语言实现(七)--- 3.1栈的线性实现及应用举例
一.简述
栈,LIFO。是操作受限的线性表,和线性表一样有两种存储表示方法。下面以顺序存储为例,实现。
二.ADT
暂无。
三.头文件
1 //3_1.h 2 /** 3 author:zhaoyu 4 email:zhaoyu1995.com@gmail.com 5 date:2016-6-7 6 note:realize my textbook <<数据结构(C语言版)>> 7 */ 8 //Page 46 9 10 #ifndef _3_1_H_ 11 #define _3_1_H_ 12 #include <cstdio> 13 #include <cstdlib> 14 #include "head.h" 15 /** 16 My Code 17 */ 18 #define SElemType char 19 //----栈的顺序存储表示---- 20 #define STACK_INIT_SIZE 100//存储空间的初始分配值 21 #define STACKINCREMENT 10//存储空间分配增量 22 typedef struct{ 23 SElemType *base;//在栈构造之前和销毁之后,base 值为 NULL 24 SElemType *top;//栈顶指针 25 int stacksize;//当前已分配的存储空间,以元素为单位 26 }SqStack; 27 //----基本操作的函数原型说明及部分实现---- 28 Status InitStack(SqStack &S) 29 { 30 //构造一个空栈 S 31 S.base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); 32 if (!S.base) 33 { 34 exit(OVERFLOW); 35 } 36 S.top = S.base; 37 S.stacksize = STACK_INIT_SIZE; 38 return OK; 39 }//InitStack 40 Status DestroyStack(SqStack &S) 41 { 42 //销毁栈 S,S 不再存在 43 } 44 Status ClearStack(SqStack &S) 45 { 46 //将 S 置为空栈 47 S.top = S.base; 48 return OK; 49 } 50 Status StackEmpty(SqStack S) 51 { 52 //若 S 为空栈, 则返回 TRUE, 否则返回 FALSE 53 if (S.base == S.top) 54 { 55 return TRUE; 56 } 57 else 58 { 59 return FALSE; 60 } 61 } 62 int StackLength(SqStack S) 63 { 64 //返回 S 的元素的个数,即栈的长度 65 } 66 Status GetTop(SqStack S, SElemType &e) 67 { 68 //若栈不空,则用 e 返回 S 的栈顶元素,并返回 OK; 69 //否则返回ERROR 70 if (S.top == S.base) 71 { 72 return ERROR; 73 } 74 e = *(S.top - 1); 75 return OK; 76 }//GetTop 77 Status Push(SqStack &S, SElemType e) 78 { 79 //插入元素 e 为新的栈顶元素 80 if (S.top - S.base >= S.stacksize) 81 {//栈满,追加存储空间 82 S.base = (SElemType *)realloc(S.base, 83 (S.stacksize+STACKINCREMENT)*sizeof(SElemType)); 84 if (!S.base) 85 { 86 exit(OVERFLOW); 87 } 88 S.top = S.base + S.stacksize; 89 S.stacksize += STACKINCREMENT; 90 } 91 *S.top++ = e; 92 return OK; 93 }//Push 94 Status Pop(SqStack &S, SElemType &e) 95 { 96 //若栈不空,则删除 S 的栈顶元素,用 e 返回其 97 //值,并返回OK;否则返回ERROR 98 if (S.top == S.base) 99 { 100 return ERROR; 101 } 102 e = *--S.top; 103 return OK; 104 }//Pop 105 Status StackTraverse(SqStack S, Status (* visit)()) 106 { 107 //从栈底到栈顶一次对栈中每个元素调用函数visit() 108 //一旦visit() 失败,则操作失败 109 } 110 111 //----栈的应用举例----- 112 //注意代码之间的数据类型冲突,所以编译时要根据要编译的部分 113 //注释掉阈值冲突的部分 114 /** 115 algorithm 3.1 116 */ 117 /* 118 void conversion() 119 { 120 //对于输入的任意一个非负十进制整数, 121 //打印输出与其等值的 n 进制数 122 //note:书上是8进制,这里稍作拓展 123 SqStack S; 124 InitStack(S); 125 int N, n, e; 126 scanf("%d%d", &N, &n); 127 while (N) 128 { 129 Push(S, N%n); 130 N = N/n; 131 } 132 while (!StackEmpty(S)) 133 {//while (!StackEmpty)竟然不报错 134 //StackEmppty是一个非NULL的指针!!! 135 Pop(S, e); 136 printf("%d", e); 137 } 138 }//conversion 139 */ 140 141 142 //note:以下两个函数不能与conversion()同时编译 143 //因为具体处理的数据类型不同 144 /** 145 algorithm 3.4 146 */ 147 148 void PrintStack_LineEdit(SqStack S) 149 { 150 char ch; 151 SqStack TempStack; 152 InitStack(TempStack); 153 while (!StackEmpty(S)) 154 { 155 Pop(S, ch); 156 Push(TempStack, ch); 157 } 158 while (!StackEmpty(TempStack)) 159 { 160 Pop(TempStack, ch); 161 putchar(ch); 162 } 163 printf("\n"); 164 } 165 void LineEdit() 166 { 167 //利用字符栈 S 从终端接收一行并传送至调用过程的数据区 168 //编译时要将 SElemType 设置成 char(而不是 int) 169 SqStack S; 170 InitStack(S); 171 char c,ch; 172 ch = getchar(); 173 while (EOF != ch)//EOF 为全文结束符 174 { 175 while (EOF != ch && '\n' != ch) 176 { 177 switch (ch) 178 { 179 case '#': 180 { 181 Pop(S, c); 182 break;//仅当栈非空时退栈 183 } 184 case '@': 185 { 186 ClearStack(S);//重置 S 为空栈 187 break; 188 } 189 default: 190 { 191 Push(S, ch);//有效字符进栈 192 break; 193 } 194 } 195 ch = getchar();//从终端接收下一个字符 196 } 197 //将从栈底到栈顶的栈内字符传送至调用过程的数据区 198 PrintStack_LineEdit(S); 199 ClearStack(S);//重置 S 为空栈 200 if (EOF != ch) 201 { 202 ch = getchar(); 203 } 204 } 205 DestroyStack(S); 206 }//LineEdit 207 #endif
四.CPP文件
1 #include "3_1.h" 2 int main(int argc, char const *argv[]) 3 { 4 /* for (int i = 0; i < 5; i++) 5 { 6 conversion(); 7 }*/ 8 LineEdit(); 9 return 0; 10 }
五.测试
进制转换
行编辑程序