數據結構棧的實現。算法
很少說了,請直接看代碼。數據結構
1 // stack.h 2 3 /* 爲了使用bool */ 4 #include <stdbool.h> 5 6 #ifndef _H_STACK_H 7 #define _H_STACK_H 8 9 /* 數據類型 */ 10 typedef char type; 11 12 /* 棧結點 */ 13 typedef struct tsNode 14 { 15 type data; 16 struct tsNode *next; 17 } Node; 18 19 /* 棧類型 */ 20 typedef struct tsStack 21 { 22 Node *top; 23 unsigned int size; 24 } Stack; 25 26 /* 初始化Stack */ 27 Stack * 28 StackInit(void); 29 30 /* 判斷棧是否爲空。爲空返回true,不然返回false */ 31 bool 32 IsEmpty(Stack *); 33 34 /* 入棧操做 */ 35 void 36 StackPush(Stack *, type); 37 38 /* 出棧操做 */ 39 type 40 StackPop(Stack *); 41 42 /* 取得棧頂元素 */ 43 type 44 GetTop(Stack *); 45 #endif
1 // stack.c 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <stdbool.h> 6 #include "stack.h" 7 8 /* 功能:棧初始化 9 * 輸入:無 10 * 輸出:一個指向Stack型的指針,指針所指對象已被初始化 11 */ 12 Stack * 13 StackInit(void) 14 { 15 Stack *s = NULL; 16 17 s = (Stack *)malloc(sizeof(Stack)); 18 if (s == NULL) 19 exit(EXIT_FAILURE); 20 s->top = NULL; 21 s->size = 0; 22 return s; 23 } 24 25 /* 功能:判斷棧是否爲空。爲空返回true,不然返回false 26 * 輸入:一個指向Stack型的指針 27 * 輸出:一個bool型變量 28 */ 29 bool 30 IsEmpty(Stack *s) 31 { 32 /* s未被初始化 */ 33 if (s == NULL) 34 exit(EXIT_FAILURE); 35 else 36 return ((s->size) == 0); 37 } 38 39 /* 功能:入棧操做 40 * 輸入:一個指向Stack型的指針,一個type型待入棧變量 41 * 輸出:無 42 */ 43 void 44 StackPush(Stack *s, type x) 45 { 46 Node *temp = (Node *)malloc(sizeof(Node)); 47 48 if (temp == NULL) 49 exit(EXIT_FAILURE); 50 temp->data = x; 51 52 /* 若s未被初始化 */ 53 if (s == NULL) 54 exit(EXIT_FAILURE); 55 temp->next = s->top; 56 s->top = temp; 57 s->size = (s->size) + 1; 58 } 59 60 /* 功能:出棧操做 61 * 輸入:一個指向Stack型的指針 62 * 輸出:被出棧的元素 63 */ 64 type 65 StackPop(Stack *s) 66 { 67 Node *p = NULL; 68 type r; 69 70 if (IsEmpty(s)) 71 exit(EXIT_FAILURE); 72 p = s->top->next; 73 r = s->top->data; 74 free(s->top); 75 s->top = p; 76 s->size = (s->size) - 1; 77 return r; 78 } 79 80 /* 功能:返回棧頂元素 81 * 輸入:一個指向Stack型的指針 82 * 輸出:棧頂元素 83 */ 84 type 85 GetTop(Stack *s) 86 { 87 if (IsEmpty(s)) 88 exit(EXIT_FAILURE); 89 return s->top->data; 90 }
1 #include <stdio.h> 2 #include "stack.h" 3 4 int main(int argc, char *argv[]) 5 { 6 Stack *s = StackInit(); 7 8 /* test passed 9 printf("s->top = %p\n", s->top); 10 printf("s->size = %u\n", s->size); 11 printf("s is empty: "); 12 IsEmpty(s) ? printf("yes\n") : printf("no\n"); 13 */ 14 15 /* test passed 16 StackPush(s, 'h'); 17 StackPush(s, 'e'); 18 StackPush(s, 'l'); 19 StackPush(s, 'l'); 20 StackPush(s, 'o'); 21 printf("s is empty: "); 22 IsEmpty(s) ? printf("yes\n") : printf("no\n"); 23 printf("s->size = %u\n", s->size); 24 25 while ((s->size) > 0) 26 { 27 printf("%c\n", StackPop(s)); 28 } 29 printf("s is empty: "); 30 IsEmpty(s) ? printf("yes\n") : printf("no\n"); 31 */ 32 33 /* test passed 34 StackPush(s, 'h'); 35 StackPush(s, 'e'); 36 StackPush(s, 'l'); 37 StackPush(s, 'l'); 38 StackPush(s, 'o'); 39 while (IsEmpty(s) == false) 40 { 41 printf("%c\n", GetTop(s)); 42 StackPop(s); 43 } 44 printf("s is empty: "); 45 IsEmpty(s) ? printf("yes\n") : printf("no\n"); 46 */ 47 48 // 棧的內存組織狀況 - pass 49 /* 當s爲空棧時內存組織狀況 50 * p s - 0x602010 51 * p s->top - 0x0 52 * p s->size - 0 53 */ 54 55 StackPush(s, 'h'); 56 /* 當s中有一個值爲'h'的元素時內存組織狀況 57 * p s - 0x602010 58 * p s->top - 0x602030 59 * p s->size - 1 60 * p s->top->data - 'h' 61 * p s->top->next - 0x0 62 */ 63 64 StackPush(s, 'e'); 65 /* 當s中有兩個元素時內存組織狀況 66 * p s - 0x602010 67 * p s->top - 0x602050 68 * p s->size - 2 69 * p s->top->data - 'e' 70 * p s->top->next - 0x602030 71 * p s->top->next->data - 'h' 72 * p s->top->next->next - 0x0 73 */ 74 75 StackPop(s); 76 /* 當將棧頂元素彈出後內存組織狀況 77 * p s - 0x602010 78 * p s->top - 0x602030 79 * p s->size - 1 80 * p s->top->data - 'h' 81 * p s->top->next - 0x0 82 */ 83 84 return 0; 85 }
注意:爲了成功編譯包含了stack.h的主程序,你須要使用下面的命令。也即必須將stack.c編譯成目標文件,供連接程序連接使用,不然連接程序將報錯。不一樣於C標準庫的使用,由於C標準庫默認採用動態連接的方式,所用標準庫中的函數均已經被編譯好了,放在特定的目錄下面,連接程序只需去目錄中找相對應的目標文件便可。這裏咱們必須將stack.c編譯成目標文件,供主程序連接時使用。函數
gcc main.c stack.c
來作題吧!題目來源在此。須要說明的是下面的代碼質量很差,由於代碼是在上面的棧代碼基礎上拼湊而來的。爲了記錄每一個字符在輸入字符串中的位置,在棧結點中添加了一個index字段用於記錄結點位置。算法原理很簡單:將每個字符入棧,判斷入棧的字符是否爲右括號(')'),若是是則將左右括號出棧並將兩者在字符串中的位置按題目要求的順序打印出來便可。spa
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <stdbool.h> 5 #define ARR_MAX_LEN 128 6 static char array[ARR_MAX_LEN]; 7 8 /* 數據類型 */ 9 typedef char type; 10 11 /* 棧結點 */ 12 typedef struct tsNode 13 { 14 int index; 15 type data; 16 struct tsNode *next; 17 } Node; 18 19 /* 棧類型 */ 20 typedef struct tsStack 21 { 22 Node *top; 23 unsigned int size; 24 } Stack; 25 26 /* 初始化Stack */ 27 Stack * 28 StackInit(void); 29 30 /* 判斷棧是否爲空。爲空返回true,不然返回false */ 31 bool 32 IsEmpty(Stack *); 33 34 /* 入棧操做 */ 35 void 36 StackPush(Stack *, int, type); 37 38 /* 出棧操做 */ 39 type 40 StackPop(Stack *); 41 42 /* 取得棧頂元素 */ 43 Node * 44 GetTop(Stack *); 45 46 /* 功能:棧初始化 47 * 輸入:無 48 * 輸出:一個指向Stack型的指針,指針所指對象已被初始化 49 */ 50 Stack * 51 StackInit(void) 52 { 53 Stack *s = NULL; 54 55 s = (Stack *)malloc(sizeof(Stack)); 56 if (s == NULL) 57 exit(EXIT_FAILURE); 58 s->top = NULL; 59 s->size = 0; 60 return s; 61 } 62 63 /* 功能:判斷棧是否爲空。爲空返回true,不然返回false 64 * 輸入:一個指向Stack型的指針 65 * 輸出:一個bool型變量 66 */ 67 bool 68 IsEmpty(Stack *s) 69 { 70 /* s未被初始化 */ 71 if (s == NULL) 72 exit(EXIT_FAILURE); 73 else 74 return ((s->size) == 0); 75 } 76 77 /* 功能:入棧操做 78 * 輸入:一個指向Stack型的指針,一個type型待入棧變量 79 * 輸出:無 80 */ 81 void 82 StackPush(Stack *s, int index, type x) 83 { 84 Node *temp = (Node *)malloc(sizeof(Node)); 85 86 if (temp == NULL) 87 exit(EXIT_FAILURE); 88 temp->index = index; 89 temp->data = x; 90 91 /* 若s未被初始化 */ 92 if (s == NULL) 93 exit(EXIT_FAILURE); 94 temp->next = s->top; 95 s->top = temp; 96 s->size = (s->size) + 1; 97 } 98 99 /* 功能:出棧操做 100 * 輸入:一個指向Stack型的指針 101 * 輸出:被出棧的元素 102 */ 103 type 104 StackPop(Stack *s) 105 { 106 Node *p = NULL; 107 type r; 108 109 if (IsEmpty(s)) 110 exit(EXIT_FAILURE); 111 p = s->top->next; 112 r = s->top->data; 113 free(s->top); 114 s->top = p; 115 s->size = (s->size) - 1; 116 return r; 117 } 118 119 /* 功能:返回棧頂元素 120 * 輸入:一個指向Stack型的指針 121 * 輸出:棧頂元素 122 */ 123 Node * 124 GetTop(Stack *s) 125 { 126 if (IsEmpty(s)) 127 exit(EXIT_FAILURE); 128 return s->top; 129 } 130 131 int 132 main(int argc, char *argv[]) 133 { 134 //freopen("in.txt", "r", stdin); 135 int i, len, temp; 136 Stack *s = StackInit(); 137 138 scanf("%s", array); 139 len = strlen(array); 140 for (i = 0; i < len; i++) 141 { 142 StackPush(s, i, array[i]); 143 if ((GetTop(s))->data == ')') 144 { 145 temp = GetTop(s)->index; 146 StackPop(s); 147 printf("%d %d\n", (GetTop(s))->index, temp); 148 StackPop(s); 149 } 150 } 151 152 //fclose(stdin); 153 return 0; 154 }
四 版本二指針
相較於上面的版本一有細微的改動,增長了函數ClearStack()用於清空棧。code
1 /* stack.h */ 2 3 #ifndef _H_STACK_H 4 #define _H_STACK_H 5 6 #include <stdbool.h> 7 8 typedef char dtype; // 數據類型 9 10 typedef struct Node // 節點類型 11 { 12 dtype data; 13 struct Node * next; 14 } tNode; 15 16 typedef struct Stack // 棧類型 17 { 18 tNode * top; 19 unsigned long long size; 20 } tStack; 21 22 /* 棧初始化 */ 23 tStack * 24 StackInit(void); 25 26 /* 判斷棧是否爲空。爲空返回true;不然返回false */ 27 bool 28 IsEmpty(tStack *); 29 30 /* 入棧 */ 31 void 32 StackPush(tStack *, dtype); 33 34 /* 出棧 */ 35 dtype 36 StackPop(tStack *); 37 38 /* 取得棧頂元素 */ 39 dtype 40 GetTop(tStack *); 41 42 /* 清空棧 */ 43 void 44 ClearStack(tStack *); 45 46 #endif
1 /* stack.c */ 2 3 #include <stdlib.h> 4 #include <stdbool.h> 5 #include "stack.h" 6 7 /* 描述:棧初始化 8 * 輸入:無 9 * 輸出:一個指向tStack型的指針,指針所指向對象已被初始化 10 */ 11 tStack * 12 StackInit(void) 13 { 14 tStack * s = (tStack *)malloc(sizeof(tStack)); 15 if (s == NULL) 16 exit(EXIT_FAILURE); 17 s->top = NULL; 18 s->size = 0; 19 return s; 20 } 21 22 /* 描述:判斷棧是否爲空。爲空返回true,不然返回false 23 * 輸入:一個指向tStack型的指針 24 * 輸出:true或者false 25 */ 26 bool 27 IsEmpty(tStack * s) 28 { 29 /* s未被初始化 */ 30 if (s == NULL) 31 exit(EXIT_FAILURE); 32 return (s->size) == 0; 33 } 34 35 /* 描述:入棧操做 36 * 輸入:一個指向tStack型的指針,一個dtype型待入棧變量 37 * 輸出:無 38 */ 39 void 40 StackPush(tStack * s, dtype x) 41 { 42 /* s未被初始化 */ 43 if (s == NULL) 44 exit(EXIT_FAILURE); 45 tNode * temp = (tNode *)malloc(sizeof(tNode)); 46 if (temp == NULL) 47 exit(EXIT_FAILURE); 48 temp->data = x; 49 temp->next = s->top; 50 s->top = temp; 51 s->size = (s->size) + 1; 52 } 53 54 /* 描述:出棧操做 55 * 輸入:一個指向tStack型的指針 56 * 輸出:一個dtype型的被出棧元素 57 */ 58 dtype 59 StackPop(tStack * s) 60 { 61 tNode * p = NULL; 62 dtype r; 63 64 if (IsEmpty(s)) 65 exit(EXIT_FAILURE); 66 p = s->top->next; 67 r = s->top->data; 68 free(s->top); 69 s->top = p; 70 s->size = (s->size) - 1; 71 return r; 72 } 73 74 /* 描述:取得棧頂元素而不出棧 75 * 輸入:一個指向tStack型的指針 76 * 輸出:棧頂元素 77 */ 78 dtype 79 GetTop(tStack * s) 80 { 81 if (IsEmpty(s)) 82 exit(EXIT_FAILURE); 83 return s->top->data; 84 } 85 86 /* 描述:清空棧 87 * 輸入:一個指向tStack型的指針 88 * 輸出:無 89 */ 90 void 91 ClearStack(tStack * s) 92 { 93 /* s未被初始化 */ 94 if (s == NULL) 95 exit(EXIT_FAILURE); 96 while (IsEmpty(s) == false) 97 StackPop(s); 98 free(s); 99 }
1 /* tstack.c */ 2 3 #include <stdio.h> 4 #include "stack.h" 5 6 int main(int argc, char *argv[]) 7 { 8 tStack * s = StackInit(); 9 10 // test pass 11 // printf("s->top = %p\n", s->top); 12 // printf("s->size = %llu\n", s->size); 13 // printf("s is empty: "); 14 // IsEmpty(s) ? printf("yes\n") : printf("no\n"); 15 16 // test pass 17 // StackPush(s, 'h'); 18 // StackPush(s, 'e'); 19 // StackPush(s, 'l'); 20 // StackPush(s, 'l'); 21 // StackPush(s, 'o'); 22 // printf("s is empty: "); 23 // IsEmpty(s) ? printf("yes\n") : printf("no\n"); 24 // printf("s->size = %llu\n", s->size); 25 // 26 // while ((s->size) > 0) 27 // { 28 // printf("%c\n", StackPop(s)); 29 // } 30 // printf("s is empty: "); 31 // IsEmpty(s) ? printf("yes\n") : printf("no\n"); 32 33 // test pass 34 // StackPush(s, 'h'); 35 // StackPush(s, 'e'); 36 // StackPush(s, 'l'); 37 // StackPush(s, 'l'); 38 // StackPush(s, 'o'); 39 // while (IsEmpty(s) == false) 40 // { 41 // printf("%c\n", GetTop(s)); 42 // StackPop(s); 43 // } 44 // printf("s is empty: "); 45 // IsEmpty(s) ? printf("yes\n") : printf("no\n"); 46 47 // 棧的內存組織狀況 48 /* 當s爲空棧時內存組織狀況 49 * p s - 0x602010 50 * p s->top - 0x0 51 * p s->size - 0 52 */ 53 54 // StackPush(s, 'h'); 55 /* 當s中有一個值爲'h'的元素時內存組織狀況 56 * p s - 0x602010 57 * p s->top - 0x602030 58 * p s->size - 1 59 * p s->top->data - 'h' 60 * p s->top->next - 0x0 61 */ 62 63 // StackPush(s, 'e'); 64 /* 當s中有兩個元素時內存組織狀況 65 * p s - 0x602010 66 * p s->top - 0x602050 67 * p s->size - 2 68 * p s->top->data - 'e' 69 * p s->top->next - 0x602030 70 * p s->top->next->data - 'h' 71 * p s->top->next->next - 0x0 72 */ 73 74 // StackPop(s); 75 /* 當將棧頂元素彈出後內存組織狀況 76 * p s - 0x602010 77 * p s->top - 0x602030 78 * p s->size - 1 79 * p s->top->data - 'h' 80 * p s->top->next - 0x0 81 */ 82 83 // StackPop(s); 84 /* 當將棧元素全彈出後內存組織狀況 85 * p s - 0x602010 86 * p s->top - 0x0 87 * p s->size - 0 88 */ 89 90 // test pass 91 // StackPush(s, 'h'); 92 // StackPush(s, 'e'); 93 // ClearStack(s); 94 /* 當棧s被清空後,變量s被清除出了上下文中 */ 95 96 return 0; 97 }