實驗內容:
實驗4、順序棧的基本操作及應用
(1)實驗目的
通過該實驗,讓學生掌握棧的相關基本概念,認識棧是插入和刪除集中在一端進行的線性結構,掌握棧的“先入后出”操作特點。棧在進行各類操作時,棧底指針固定不動,掌握棧空、棧滿的判斷條件。
(2)實驗內容
用順序存儲結構,實現教材定義的棧的基本操作,提供數制轉換功能,將輸入的十進制整數轉換成二進制、八進制或十六進制。
(3)參考界面
菜單中包括以下功能:
1.初始化棧,2.銷毀棧,3.清空棧,4.棧判空,5.求棧長度,6.獲取棧頂元素,7.插入一個 元素,8.刪除一個元素,9輸出所有元素,10進制轉換。
要求:自定義的函數中不允許出現提示語和輸出語句。
(4)驗收/測試用例
通過菜單調用各個操作,測試點:
l 沒有初始化前進行其他操作,程序是否能控制住;
l 初始化一個棧;
l 判棧空,屏幕顯示棧為空;
l 3個數入棧, 2、4、6;
l 棧長度,屏幕輸出3;
l 取棧頂元素,再判棧空,然后再判棧長度。讓學生知道取棧頂元素不改變棧中的內容,棧頂指針不發生改變;
l 出棧,再判棧長度和輸出棧中內容;(多次出棧,直到棧為空;再出棧,是否提示棧為空)
l 銷毀棧,再做其他操作,判斷程序是否能控制;
數制轉換,(允許用戶輸入想把十進制轉換成幾進制),然后靈活的轉換成對應的進制。
實驗環境:
VS2019
設計思想
1.設置主函數類main.cpp進行菜單的展示和執行,設置頭文件stuck.h存放函數和構造體聲明,設置功能函數類stuck.cpp存放功能函數;
2.每個函數調用前判斷棧是否初始化,個別函數之后仍需判斷棧是否為空;
3.菜單展示和執行使用while循環,每次循環前進行清屏,提高用戶體驗;
4.進制轉換:
可以進行十以內進制包括十六進制的轉換,在進行十六進制轉換輸出時,判斷元素>9則輸出相應的字母,否則直接輸出;程序使用過后釋放內存; 增加對輸入數為0的判斷;
5.直接退出程序先調用銷毀函數釋放內存空間;
二、主要源代碼
main.cpp
1 #include "stack.h" //引入自定義頭文件 2 int main() 3 { 4 Stuck stuck; 5 stuck.base = NULL; 6 Stuck trans_stuck; //進制轉換所需棧 7 trans_stuck.base = NULL; 8 int position; 9 while (true) 10 { 11 system("cls"); 12 cout << "歡迎使用本程序" << endl; 13 cout << "1. 初始化棧" << endl; 14 cout << "2. 銷毀棧" << endl; 15 cout << "3. 清空棧" << endl; 16 cout << "4. 棧判空" << endl; 17 cout << "5. 求棧長度" << endl; 18 cout << "6. 獲取棧頂元素" << endl; 19 cout << "7. 插入一個元素" << endl; 20 cout << "8. 刪除一個元素" << endl; 21 cout << "9. 輸出所有的元素" << endl; 22 cout << "10.進制轉換" << endl; 23 cout << "請輸入指令完成操作" << endl; 24 cin >> position; 25 if (position < 0) 26 { 27 cout << "謝謝您的使用" << endl; 28 destoryStuck(stuck); //結束時釋放棧內存空間 29 break; 30 } 31 switch (position) 32 { 33 case 1: 34 if (stuck.base) 35 { 36 cout << "請進行銷毀操作后再初始化" << endl; 37 } 38 else 39 { 40 initializeStuck(stuck); 41 if (stuck.base) 42 cout << "初始化成功" << endl; 43 else 44 cout << "初始化失敗" << endl; 45 } 46 system("pause"); break; 47 case 2: 48 if (stuck.base) 49 { 50 destoryStuck(stuck); 51 if (stuck.base) 52 cout << "銷毀失敗" << endl; 53 else 54 cout << "銷毀成功" << endl; 55 } 56 else 57 { 58 cout << "請初始化后再進行銷毀" << endl; 59 } 60 system("pause"); break; 61 case 3: 62 if (stuck.base) 63 { 64 emptyStuck(stuck); 65 if (ifEmpty(stuck)) 66 cout << "清空失敗" << endl; 67 else 68 cout << "清空成功" << endl; 69 } 70 else 71 { 72 cout << "請初始化后再進行清空操作" << endl; 73 } 74 system("pause"); break; 75 case 4: 76 if (stuck.base) 77 { 78 if (ifEmpty(stuck)) 79 cout << "棧不為空" << endl; 80 else 81 cout << "棧為空" << endl; 82 } 83 else 84 { 85 cout << "請初始化后再進行此操作" << endl; 86 } 87 system("pause"); break; 88 case 5: 89 if (stuck.base) 90 { 91 92 cout << "該棧的長度為: " <<(stuck.top - stuck.base) << endl; 93 } 94 else 95 { 96 cout << "請初始化后再進行此操作" << endl; 97 } 98 system("pause"); break; 99 case 6: 100 if (stuck.base) 101 { 102 if(ifEmpty(stuck)) 103 { 104 cout << " 棧頂元素為:" << getTop(stuck) << endl; 105 } 106 else 107 cout << "請插入元素后再進行此操作" << endl; 108 } 109 else 110 cout << "請初始化后再進行此操作" << endl; 111 system("pause"); break; 112 case 7: 113 if (stuck.base) 114 { 115 if((stuck.top-stuck.base)==stuck.stacksize) 116 { 117 cout << "棧已滿,正在申請新的內存空間" << endl; 118 stuck.base = (element*)realloc(stuck.base,(STACKINCREMENT + STACK_INIT_SIZE) * sizeof(element)); 119 if (stuck.base) 120 { 121 stuck.top = stuck.stacksize + stuck.base; 122 stuck.stacksize += STACKINCREMENT; 123 } 124 else 125 { 126 cout << "申請失敗,請聯系管理員" << endl; 127 } 128 } 129 else { 130 element elem; 131 cout << "請輸入要插入的元素" << endl; 132 cin >> elem; 133 insertElem(stuck,elem); 134 } 135 } 136 else 137 cout << "請初始化后再進行此操作" << endl; 138 system("pause"); break; 139 case 8: 140 if (stuck.base) 141 { 142 if (ifEmpty(stuck)) 143 deleteElem(stuck); 144 else { 145 cout<< "請添加元素后再進行刪除操作" << endl; 146 } 147 } 148 else 149 { 150 cout << "請初始化后再進行此操作" << endl; 151 } 152 system("pause"); break; 153 case 9: 154 if (stuck.base) 155 { 156 if (ifEmpty(stuck)) 157 { 158 cout << "目前元素為:" << endl; 159 printElem(stuck); 160 } 161 else 162 cout << "棧為空" << endl; 163 } 164 else 165 cout << "請初始化后再進行此操作" << endl; 166 system("pause"); break; 167 case 10: 168 int num; 169 int num_system; 170 initializeStuck(trans_stuck); 171 cout << "請輸入要轉換的十進制數: " << endl; 172 cin >> num; 173 cout << "請輸入要轉換的數制" << endl; 174 cin >> num_system; 175 if(num == 0) //判斷輸入數為0的情況 176 cout<<num << "的" << num_system << "進制為:" <<0<< endl; 177 else if ((num_system > 10 && num_system != 16) || num_system < 2) 178 { 179 cout << "暫時不支持此進制的轉換" << endl; 180 } 181 else 182 { 183 cout << num << "的" << num_system << "進制為:" << endl; 184 initializeStuck(trans_stuck); 185 while (num != 0) 186 { 187 int remainder = num % num_system; 188 insertElem(trans_stuck, remainder);//將余數壓入棧中 189 num = num / num_system; 190 } 191 if (num_system == 16) //當轉換進制為16時 192 { 193 while (trans_stuck.base != trans_stuck.top) 194 { 195 int choice = *(--trans_stuck.top); 196 switch (choice) 197 { 198 case 10:cout << "A"; break; 199 case 11:cout << "B"; break; 200 case 12:cout << "C"; break; 201 case 13:cout << "D"; break; 202 case 14:cout << "E"; break; 203 case 15:cout << "F"; break; 204 default:cout << choice; break; 205 } 206 } 207 } 208 else 209 printElem(trans_stuck); 210 } 211 destoryStuck(trans_stuck); //釋放內存空間 212 system("pause"); break; 213 } 214 } 215 }
studck.h
1 #pragma once 2 #include <iostream> 3 using namespace std; 4 #define STACK_INIT_SIZE 100 5 #define STACKINCREMENT 10 6 typedef int element; 7 typedef struct 8 { 9 element *base; //棧底指針 10 element *top; //棧頂指針 11 int stacksize; // 當前已分配的存儲空間 12 }Stuck; 13 void initializeStuck(Stuck &stuck); //初始化 14 void destoryStuck(Stuck& stuck); //銷毀 15 void emptyStuck(Stuck& stuck); //清空 16 bool ifEmpty(Stuck stuck); //判斷是否為空 17 element getTop(Stuck stuck); //獲取棧頂元素 18 void insertElem(Stuck& stuck,element elem); //插入元素 19 void deleteElem(Stuck& stuck); //刪除元素 20 void printElem(Stuck stuck); //輸出所有元素
stuck.cpp
1 #include "stack.h" //引入頭文件 2 //1 初始化棧 3 void initializeStuck(Stuck& stuck) 4 { 5 stuck.base = (element*)malloc(STACK_INIT_SIZE * sizeof(element)); 6 stuck.top = stuck.base; 7 stuck.stacksize = STACK_INIT_SIZE; 8 } 9 // 2 銷毀棧 10 void destoryStuck(Stuck& stuck) 11 { 12 free(stuck.base); 13 stuck.stacksize = 0; 14 stuck.top = NULL; 15 stuck.base = NULL; 16 } 17 // 3 清空棧 18 void emptyStuck(Stuck& stuck) 19 { 20 stuck.top = stuck.base; 21 } 22 // 4 判斷棧是否為空 23 bool ifEmpty(Stuck stuck) 24 { 25 if (stuck.top == stuck.base) 26 return false; 27 else 28 return true; 29 } 30 // 6 獲取棧頂元素 31 element getTop(Stuck stuck) 32 { 33 /*int pos = (stuck.top - stuck.base) - 1; 34 return stuck.base[pos];*/ 35 return *(--stuck.top); 36 } 37 // 7 插入元素 38 void insertElem(Stuck& stuck, element elem) 39 { 40 //較麻煩,不推薦使用已注釋的方法 41 /*int pos = stuck.top - stuck.base; 42 stuck.base[pos] = elem; 43 stuck.top++;*/ 44 *(stuck.top++) = elem; 45 } 46 // 8 刪除元素 47 void deleteElem(Stuck& stuck) 48 { 49 stuck.top--; 50 } 51 // 9 輸出所有元素 52 void printElem(Stuck stuck) 53 { 54 while (stuck.base != stuck.top) 55 { 56 cout << *(--stuck.top) << " "; 57 } 58 cout << endl; 59 //這種方法也可以使用,二者先選其一即可; 60 /*for (int i = 0; i < (stuck.top - stuck.base); i++) 61 { 62 cout << stuck.base[i] << " "; 63 } 64 cout << endl;*/ 65 }
實驗結果總結
在未進行初始化前不可進行其它操作
初始化后棧為空,長度為0,不可獲取棧頂元素也不能進行刪除操作,輸出元素則會提示棧為空;
插入兩個數
求棧長
輸出當前元素
刪除一個元素並檢查棧長,輸出所有元素
獲取棧頂元素
銷毀棧
數制轉換測試
輸入負數退出程序(忘記在菜單中添加了,加上下面這條語句:cout << "輸入負數退出程序" << endl;)
實驗結果的運用:
1.熟悉了順序棧的基本操作和運行原理;
2.對於16進制轉換時,可以在輸出時進行處理,因此並不妨礙進棧操作的進行;
3.在進行出棧操作時進行棧是否為空的判斷,同時進棧時考慮分配的空間滿的情況下,進行內存擴容。
進行實驗時參考了以下內容:
https://blog.csdn.net/qq_24654501/article/details/109273418?ops_request_misc=&request_id=&biz_id=102&utm_term=%E7%94%A8%E9%A1%BA%E5%BA%8F%E5%AD%98%E5%82%A8%E7%BB%93%E6%9E%84%EF%BC%8C%E5%AE%9E%E7%8E%B0%E6%95%99%E6%9D%90%E5%AE%9A%E4%B9%89%E7%9A%84%E6%A0%88%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C%EF%BC%8C%E6%8F%90%E4%BE%9B%E6%95%B0%E5%88%B6%E8%BD%AC%E6%8D%A2%E5%8A%9F%E8%83%BD&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-109273418.pc_search_result_hbase_insert&spm=1018.2226.3001.4187