C语言 栈 链式结构 实现
2013-10-30 11:30 wid 阅读(3010) 评论(1) 编辑 收藏 举报一个C语言链式结构实现的栈 mStack (GCC编译)。
1 /** 2 * @brief C语言实现的链式结构类型的栈 3 * @author wid 4 * @date 2013-10-30 5 * 6 * @note 若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢! 7 */ 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 12 #define TRUE 1 13 #define FALSE 0 14 15 typedef struct SNODE 16 { 17 void *pelm; //元素指针 18 struct SNODE *next; //指向下一栈节点 19 }StackNode; 20 21 typedef struct 22 { 23 StackNode *btm; //栈底指针 24 StackNode *top; //指向栈顶元素 25 int height; //栈高度 26 }mStack; 27 28 //栈方法声明 29 30 mStack *CreateStack(); //创建一个空的栈 31 void DestroyStack( mStack *pStack ); //销毁栈 32 void ClearStack( mStack *pStack ); //清空栈内元素 33 int GetHeight( mStack *pStack ); //获取栈高度 34 int IsEmpty( mStack *pStack ); //检测是否为空栈 35 int Push( mStack *pStack, void *pdata ); //向栈内压入元素 36 int Pop( mStack *pStack, void **pdata ); //将栈顶元素出栈 37 int GetTop( mStack *pStack, void **pdata ); //获取栈顶元素 38 void ForEachStack( mStack *pStack, void (*func)(void *pdata) ); //从栈顶到栈底的每个元素依次执行 func 函数 39 40 41 //栈方法实现 42 43 /** 44 * @brief 创建一个高度为 nHeight 的栈 45 * 46 * @return 返回指向新建的栈的指针 47 */ 48 mStack *CreateStack() 49 { 50 ///创建一个栈 51 mStack *pStack = (mStack *)malloc( sizeof(mStack) ); 52 53 ///令栈顶指向栈底指向NULL 54 pStack->top = pStack->btm = NULL; 55 56 ///初始栈高度为0 57 pStack->height = 0; 58 } 59 60 /** 61 * @brief 销毁栈 pStack 62 * 63 * @param pStack 指向待销毁的栈的指针 64 * 65 * @return void 66 */ 67 void DestroyStack( mStack *pStack ) 68 { 69 StackNode *tmp = NULL; 70 71 ///释放栈内节点 72 while( tmp != NULL ) 73 { 74 tmp = pStack->top->next; 75 free( pStack->top ); 76 pStack->top = tmp; 77 } 78 79 ///释放栈 80 free( pStack ); 81 } 82 83 /** 84 * @brief 清空栈内元素 85 * 86 * @param pStack 指向待清空元素的栈的指针 87 * 88 * @return void 89 */ 90 void ClearStack( mStack *pStack ) 91 { 92 StackNode *tmp = NULL; 93 while( tmp != NULL ) 94 { 95 tmp = pStack->top->next; 96 free( pStack->top ); 97 pStack->top = tmp; 98 } 99 100 pStack->top = pStack->btm = NULL; 101 102 pStack->height = 0; 103 } 104 105 /** 106 * @brief 获取栈当前高度 107 * 108 * @param 指向待获取高度的栈的指针 109 * 110 * @return 返回栈当前高度 111 */ 112 int GetHeight( mStack *pStack ) 113 { 114 return pStack->height; 115 } 116 117 /** 118 * @brief 检测是否为空栈 119 * 120 * @param pStack 指向待检测的栈的指针 121 * 122 * @return 若为空, 则返回 TRUE, 否则返回 FALSE 123 */ 124 int IsEmpty( mStack *pStack ) 125 { 126 return pStack->height == 0 ? TRUE : FALSE; 127 } 128 129 /** 130 * @brief 向栈内压入元素 131 * 132 * @param pStack 待压入元素的栈 133 * @param pdata 指向待压入栈元素的指针 134 * 135 * @return 返回成功入栈后栈的高度 136 */ 137 int Push( mStack *pStack, void *pdata ) 138 { 139 ///创建一个栈节点 140 StackNode *pNode = (StackNode *)malloc( sizeof(StackNode) ); 141 142 ///为该节点赋值 143 pNode->pelm = pdata; 144 pNode->next = pStack->top; 145 146 ///令栈顶指向最新节点 147 pStack->top = pNode; 148 149 ++pStack->height; 150 } 151 152 /** 153 * @brief 将栈顶元素出栈 154 * 155 * @param pStack 指向待执行出栈操作的栈的指针 156 * @param pdata 接收弹出的元素的指针 157 * 158 * @return 出栈成功则返回出栈后栈的高度, 否则返回 -1 159 */ 160 int Pop( mStack *pStack, void **pdata ) 161 { 162 ///检测是否为空栈 163 if( pStack->top == pStack->btm ) 164 return -1; 165 166 ///取得栈节点数据元素值 167 *pdata = pStack->top->pelm; 168 169 ///将栈顶指针向下退一位 170 StackNode *p = pStack->top->next; 171 free( pStack->top ); 172 pStack->top = p; 173 174 return --pStack->height; 175 } 176 177 /** 178 * @brief 获取栈顶元素到 pt 179 * 180 * @param pStack 指向待弹出元素的栈的指针 181 * @param pdata 指向接收弹出的元素的指针 182 * 183 * @return 获取成功则返回栈顶元素的位置, 否则返回 -1 184 * 185 * @note 元素位置由 0 计起 186 */ 187 int GetTop( mStack *pStack, void **pdata ) 188 { 189 ///检测是否为空栈 190 if( pStack->height == 0 ) 191 return -1; 192 193 *pdata = pStack->top->pelm; 194 195 return pStack->height - 1; 196 } 197 198 /** 199 * @brief 从栈底到栈顶的每个元素依次执行 func 函数 200 * 201 * @param pStack 指向待处理的栈的指针 202 * @param func 需要执行的函数的指针 203 * 204 * @return void 205 */ 206 void ForEachStack( mStack *pStack, void (*func)(void *pt) ) 207 { 208 StackNode *tmp = pStack->top; 209 while( tmp != NULL ) 210 { 211 func( tmp->pelm ); 212 tmp = tmp->next; 213 } 214 } 215 216 void display( void *pn ) 217 { 218 printf( "%d ", *(int *)pn ); 219 } 220 221 int main() 222 { 223 int a = 10, b = 20, c = 30, n = 0; 224 void *pa = NULL; 225 226 ///测试 CreateStack 227 mStack *psk = CreateStack(); 228 229 ///测试 IsEmpty、GetHeight 230 if( IsEmpty(psk) == TRUE ) 231 printf( "Init Height = %d\n", GetHeight(psk) ); 232 233 ///测试 Push 234 printf("压入数字 10\n"); Push( psk, &a ); 235 printf("压入数字 20\n"); Push( psk, &b ); 236 printf( "压入2元素后栈高度 = %d\n", GetHeight(psk) ); 237 238 ///测试 Pop 239 printf( "\n测试 Pop:\n" ); 240 n = Pop( psk, &pa ); 241 if( n != -1 ) 242 printf( "Pop = %d\n", *(int *)pa ); 243 244 n = Pop( psk, &pa ); 245 if( n != -1 ) 246 printf( "Pop = %d\n", *(int *)pa ); 247 248 n = Pop( psk, &pa ); 249 if( n != -1 ) 250 printf( "Pop = %d\n", *(int *)pa ); 251 252 ///测试清空栈 253 Push( psk, &a ); 254 printf("\n清空栈.."); 255 ClearStack( psk ); 256 printf( "\n清空后栈高度 = %d\n", GetHeight(psk) ); 257 258 ///测试 ForEachStack 259 printf("\n\压入3元素.."); 260 Push( psk, &a ); 261 Push( psk, &b ); 262 Push( psk, &c ); 263 printf("\n测试 ForEachStack: "); ForEachStack( psk, display ); 264 265 ///测试GetTop 266 printf("\n测试GetTop:\n"); 267 n = GetTop( psk, &pa ); 268 if( n != -1 ) 269 printf( "GetTop = %d\n", *(int *)pa ); 270 271 ///再次输出当前栈高度 272 printf( "\n当前栈高度Height = %d\n", GetHeight(psk) ); 273 274 ///测试 DestroyStack 275 printf("\n销毁栈..\n"); 276 DestroyStack( psk ); 277 278 return 0; 279 }
测试运行:
若代码存在 bug 或程序缺陷, 请留言反馈, 谢谢。