【完结】大二上课内作业与实验代码分享
大二上《数据结构》《操作系统》作业和实验代码
随着大二上学期结束,本博文完结停止更新。
完整操作系统部分代码见博文《理解操作系统相关知识》
1.数据结构实验一
#include <iostream> #include <algorithm> #include <string> #include <fstream> using namespace std; #define MAXN 100004 typedef unsigned int uint; const int mut1 = 127; const int mut2 = 131; const int MOD = 2000007; const unsigned int INF = 0x3fffffff; struct hash_map { int head[MOD], nEle; struct node { uint key1, key2; int key3, pos, pre; node() { } node(uint key1, uint key2, int key3, int pos, int pre) : key1(key1), key2(key2), key3(key3), pos(pos), pre(pre) { } } ele[MOD * 2]; void init() { nEle = 0; memset(head, -1, sizeof(head)); } int find(uint key1, uint key2, int len) { int hashcode = key1 % MOD; for (int i = head[hashcode]; i != -1; i = ele[i].pre) if (ele[i].key1 == key1 && ele[i].key2 == key2 && ele[i].key3 == len) return i; return -1; } int getPos(uint key1, uint key2, int len) { int pos = find(key1, key2, len); if (pos == -1) return -1; return ele[pos].pos; } void updata(uint key1, uint key2, int len, int pos) { int tmp = key1 % MOD; ele[nEle] = node(key1, key2, len, pos, head[tmp]); head[tmp] = nEle++; } void addstring(string s, int pos) { int len = s.length(); uint key1 = 0, key2 = 0; for (int i = 0; i < len; i++) { key1 = key1 * mut1 + s[i]; key2 = key2 * mut2 + s[i]; } updata(key1, key2, len, pos); } void remove(string s, int pos) { int len = s.length(); uint key1 = 0, key2 = 0; for (int i = 0; i < len; i++) { key1 = key1 * mut1 + s[i]; key2 = key2 * mut2 + s[i]; } int hashcode = key1 % MOD; for (int i = head[hashcode]; i != -1; i = ele[i].pre) if (ele[i].key1 == key1 && ele[i].key2 == key2 && ele[i].key3 == len && ele[i].pos == pos) ele[i].key1 = INF, ele[i].key2 = INF; } } hash; class MY_CLASS { public: struct STUDENT { int node_id; string name, ethnic, fromplace, id, sex; int age; STUDENT* next; STUDENT* pre; STUDENT() { next = pre = NULL; node_id = -1; } void input(string _id, string _name, string _sex, string _ethnic, string _fromplace, int _age) { name = _name, ethnic = _ethnic; id = _id, fromplace = _fromplace; sex = _sex, age = _age, ethnic = _ethnic; } void output() { cout << name << " " << ethnic << " " << fromplace << " " << id << " " << sex << " " << age << endl; } }; STUDENT *front; STUDENT *back; STUDENT *pointer[MAXN]; int tot; int tot_age; void init() { tot = tot_age = 0; front = new STUDENT; back = front; memset(pointer, 0, sizeof(pointer)); front->next = front->pre = NULL; front->age = 0; hash.init(); } void insert(string id, string name, string sex, string ethnic, string fromplace, int age) { hash.addstring(name, tot); front->age++; STUDENT *node = new STUDENT; node->input(id, name, sex, ethnic, fromplace, age); back->next = node; node->pre = back; pointer[tot] = node; node->node_id = tot++; node->name = name; node->age = age; tot_age += age; back = node; } void remove(string id) { int age_t; STUDENT *head = front; for (; head != back; head = head->next) { if (head->next->id == id) { age_t = head->next->age; STUDENT *tmp = head->next; hash.remove(head->next->name, head->next->node_id); pointer[head->next->node_id] = NULL; if (head->next == back) back = head; else head->next = head->next->next; delete tmp; break; } } front->age--; tot_age -= age_t; } void output() { STUDENT *head = front; puts("*******************"); for (; head != back; head = head->next) { head->next->output(); } puts("*******************"); } void Sort() { STUDENT *p, *p1, *p2; for (STUDENT* end = NULL; end != front; end = p) { for (p = p1 = front; p1->next->next != end; p1 = p1->next) { if (p1->next->age > p1->next->next->age) { p2 = p1->next->next; // 要交换的第二个数 p1->next->next = p2->next; p2->next = p1->next; p1->next = p2; p = p1->next->next; } } if (p != front && end == NULL) { back = p; back->next = NULL; } } } void clear() { STUDENT* temp = front; int cnt = -1; while (front != NULL) { cnt ++; STUDENT *tmp = front; front = front->next; delete tmp; } printf("clear %d people's List\n\n", cnt); } }; MY_CLASS SHU_MIE; void findstudent(string NAME) { int len = NAME.length(); uint key1 = 0, key2 = 0; for (int i = 0; i < len; i++) { key1 = key1 * mut1 + NAME[i]; key2 = key2 * mut2 + NAME[i]; } int flag = 0; int hashcode = key1 % MOD; for (int i = hash.head[hashcode]; i != -1; i = hash.ele[i].pre) if (hash.ele[i].key1 == key1 && hash.ele[i].key2 == key2) { SHU_MIE.pointer[hash.ele[i].pos]->output(); flag++; } if (!flag) puts("NO THIS STUDENT"); else { printf("-----> done! 为您找到了姓名为"); cout << NAME; printf("的%d人有关信息\n", flag); } puts(""); } int main() { // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); ifstream inFile("data3.txt"); if (!inFile) exit(1); int opr; SHU_MIE.init(); string ID, NAME, SEX, ETHNIC, Fromplace; int AGE; inFile >> ID >> NAME >> SEX >> ETHNIC >> Fromplace >> ETHNIC; while (!inFile.eof()) { inFile >> ID >> NAME >> SEX >> ETHNIC >> Fromplace >> AGE; SHU_MIE.insert(ID, NAME, SEX, ETHNIC, Fromplace, AGE); } inFile.close(); puts("**********操作小提示*********"); printf( "1。输入姓名查询学生信息\n2。对学生年龄进行排序后输出\n3。输出学生个数\n4。输出学生年龄的平均数\n5。输入ID删除学生信息\n"); puts("*****************************"); puts("请输入操作"); while (1) { scanf("%d", &opr); system("cls"); if(opr == 6) { puts("谢谢使用再见"); break; } puts("执行结果为"); if (opr == 1) { cin >> NAME; findstudent(NAME); } else if (opr == 2) { SHU_MIE.Sort(); printf("output Sorted List %d people\n", SHU_MIE.front->age); SHU_MIE.output(); puts(""); } else if (opr == 3) { printf("total number of student is %d \n\n", SHU_MIE.front->age); } else if (opr == 4) { printf("averge age of student is %.2lf \n\n", SHU_MIE.tot_age / (double) SHU_MIE.front->age); } else if (opr == 5) { cin >> ID; SHU_MIE.remove(ID); puts("OK! Delete it"); puts(""); } puts("**********操作小提示*********"); printf( "1。输入姓名查询学生信息\n2。对学生年龄进行排序后输出\n3。输出学生个数\n4。输出学生年龄的平均数\n5。输入ID删除学生信息\n"); puts("*****************************"); puts("请输入操作"); } SHU_MIE.clear(); return 0; } /* data3.txt 学号 姓名 性别 民族 生源 年龄 120834101 赵一 男 汉 北京 19 120834102 钱二 男 汉 山东 18 120834103 孙三 男 蒙 天津 19 120834104 李四 女 汉 湖南 20 120834105 周五 女 回 江西 17 120834201 吴一 女 朝鲜 吉林 18 120834202 郑二 男 汉 河北 19 120834203 王三 男 汉 江苏 19 120834204 冯四 女 汉 四川 20 120834205 陈五 女 汉 陕西 18 120814101 赵一 女 汉 黑龙江 18 120814102 楮二 男 汉 辽宁 19 120814103 卫三 男 汉 内蒙古 16 120814104 蒋四 女 满 山西 20 120814105 沈五 男 汉 江西 18 120814201 韩一 女 汉 河南 18 120814202 杨二 女 汉 福建 19 120814203 王三 男 苗 广东 18 120814204 朱四 男 汉 浙江 19 120814205 秦五 女 汉 江苏 17 */ /* input.txt 5 120814103 2 5 120834105 5 120814102 2 3 4 6 */
2.操作系统实验一 进程调度
#include <iostream> #include <cstdio> #include <queue> #include <string> #include <algorithm> #include <cstring> #include <set> #include <map> #include <fstream> using namespace std; #define MAXN 109 char info[21]; int block_id[MAXN]; int DEV_endtime[MAXN]; int block_endtime[MAXN]; int DEV_runtime[MAXN]; int tot_DEV; int tot_block; int N; struct Node { int priority; int Type; int id; int time; int end; Node() { } Node(int p, int a, int b, int c) { priority = p, Type = a, id = b, time = c, end = 0; } bool operator <(const Node &tmp) const { if (id == tmp.id) return priority < tmp.priority; return id < tmp.id; } }; set<Node> block; void translate() { // ifstream fin("data.xml", ios::in); // if (fin == NULL) { // cerr << "error in open FILE.." << endl; // exit(-1); // } string temp; int cnt = 0; int time, end; while (getline(cin, temp)) { if (temp.find("program", 1) != temp.npos) { N++; cnt = -1; } else if (temp.find("step", 1) != temp.npos) { time = end = 0; cnt++; int Type; int len = temp.length(); if (temp[len - 8] == 'u') Type = 0; else Type = temp[len - 8] - '0'; tot_DEV = max(tot_DEV, Type); int i = 6, t = 1; while (temp[i] != ',') { time = time * t + (temp[i] - '0'); t *= 10, i++; } i++, t = 1; while (temp[i] != ',') { end = end * t + (temp[i] - '0'); t *= 10, i++; } block.insert(Node(N, Type, cnt, end - time)); tot_block++; } } } struct ans { int begin, end, name; ans(int _begin, int _end, int _name) : begin(_begin), end(_end), name(_name) { } }; vector<ans> Ans[MAXN]; int main() { // freopen("data.xml", "r", stdin); // freopen("output.xml", "w", stdout); block.clear(); for (int i = 0; i < MAXN; i++) Ans[i].clear(); N = -1; tot_block = tot_DEV = 0; translate(); memset(block_id, 0, sizeof(block_id)); memset(DEV_endtime, 0, sizeof(DEV_endtime)); memset(DEV_runtime, 0, sizeof(DEV_runtime)); memset(block_endtime, 0, sizeof(block_endtime)); set<Node>::iterator it; int j = 0; while (tot_block) { for (it = block.begin(); it != block.end() && j >= (*it).id;) { if ((*it).id == block_id[(*it).priority]) { //是进程下一个请求 block_id[(*it).priority]++; DEV_runtime[(*it).priority] += (*it).time; DEV_endtime[(*it).Type] = max(DEV_endtime[(*it).Type], block_endtime[(*it).priority]) + (*it).time; Ans[(*it).Type].push_back( ans(DEV_endtime[(*it).Type] - (*it).time, DEV_endtime[(*it).Type], (*it).priority)); block_endtime[(*it).priority] = DEV_endtime[(*it).Type]; block.erase(it++); tot_block--; } else it++; } j++; } puts("<output>"); puts("<unit>"); printf("<resource>cpu</resource>\n"); for (int i = 0; i <= tot_DEV; i++) { if (i > 0) printf("<unit>\n<resource>dev%d</resource>\n", i); for (int j = 0; j < Ans[i].size(); j++) printf("<phase>%d,%d,%c</phase>\n", Ans[i][j].begin, Ans[i][j].end, Ans[i][j].name + 'A'); puts("</unit>"); } int Max = -1; puts("<result>"); for (int i = 0; i <= tot_DEV; i++) Max = max(Max, DEV_endtime[i]); printf("<name>cpu</name>\n<ratio>%d</ratio>\n", DEV_runtime[0]); for (int i = 1; i <= tot_DEV; i++) { printf("<name>dev%d</name>\n<ratio>%d</ratio>\n", i, DEV_runtime[i]); } puts("</result>"); puts("</output>"); return 0; } /* <input> <unit> <program>A</program> <step>0,10,cpu</step> <step>10,20,dev1</step> <step>20,30,cpu</step> <step>30,40,dev2</step> </unit> <unit> <program>B</program> <step>0,15,dev1</step> <step>15,25,cpu</step> <step>25,35,dev2</step> <step>35,40,cpu</step> </unit> <unit> <program>C</program> <step>0,5,cpu</step> <step>5,15,dev2</step> <step>15,30,cpu</step> <step>30,40,dev1</step> </unit> </input> */
3.霍夫曼编码
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <map> #include <string> #include <queue> using namespace std; #define MAXN 109 map<int, pair<double, string> > str_map; vector<int> Tree[MAXN]; set<pair<double, int> > SET; set<pair<double, int> >::iterator it, it2; bool vis[MAXN]; int n, tot; void addedge(int u, int v) { Tree[u].push_back(v); } void bfs(int u) { queue<int> Q; memset(vis, 0, sizeof(vis)); Q.push(u); vis[u] = 1; while (!Q.empty()) { int head = Q.front(); if (head > n) printf("%d ", head); else cout << str_map[head].second << " "; Q.pop(); for (size_t i = 0; i < Tree[head].size(); i++) if (!vis[Tree[head][i]]) { vis[Tree[head][i]] = 1; Q.push(Tree[head][i]); } } } void dfs(int u, int d, int num) { if (!Tree[u].size()) return; int tmp; for (int i = 0; i < 2; i++) { tmp = num | (i << d); if (Tree[u][i] <= n) { cout << str_map[Tree[u][i]].second << " "; if (!tmp) for (int i = 0; i <= d; i++) printf("0"); else { int cnt = 0; while (tmp) { printf("%d", tmp % 2); tmp = tmp / 2; cnt++; } for (; cnt <= d; cnt++) printf("0"); } puts(""); } dfs(Tree[u][i], d + 1, tmp); } } int main() { // freopen("data3.txt", "r", stdin); string str; double p; puts("根据概率产生霍夫曼编码的程序"); while (~scanf("%d", &n)) { tot = n + 1; SET.clear(); str_map.clear(); for (int i = 1; i <= n; i++) { cin >> str; scanf("%lf", &p); SET.insert(make_pair(p, i)); str_map[i] = make_pair(p, str); } double first, second; int f_id, s_id; while (SET.size() > 1) { first = (*SET.begin()).first; f_id = (*SET.begin()).second; SET.erase(SET.begin()); second = (*SET.begin()).first; s_id = (*SET.begin()).second; SET.erase(SET.begin()); if (first > second) { swap(first, second); swap(f_id, s_id); } addedge(tot, s_id); addedge(tot, f_id); SET.insert(make_pair(first + second, tot++)); } // bfs(tot - 1); dfs(tot - 1, 0, 0); } return 0; } /* 8 A 0.07 B 0.19 C 0.02 D 0.06 E 0.32 F 0.03 G 0.21 H 0.1 */
4.两个遍历顺序确定另一个
#include <iostream> #include <algorithm> #include <vector> using namespace std; #define MEM(a) memset(a, 0, sizeof(a)) char str[30]; vector<char> ans; vector<bool> beleft; int back_id[300]; void check(vector<char> tmp) { for (size_t i = 0; i < tmp.size(); i++) back_id[(int) tmp[i]] = i; } void debug(vector<char> tmp) { puts("*****DEBUG****"); for (size_t i = 0; i < tmp.size(); i++) cout << tmp[i] << " "; puts(""); } void dfs(vector<char> back, vector<char> mid, bool isleft) { int len = back.size(); if (len == 0) return; vector<char> left, mid_tmp; char root = back[len - 1]; ans.push_back(root); beleft.push_back(isleft); len--; if (len == 0) return; check(back); size_t i, j; int max1 = -1; for (i = 0; i < mid.size() && mid[i] != root; i++) { max1 = max(max1, back_id[(int) mid[i]]); mid_tmp.push_back(mid[i]); } for (j = 0; j < back.size() - 1 && (int) j != max1 + 1; j++) left.push_back(back[j]); dfs(left, mid_tmp, 0); mid_tmp.clear(); left.clear(); max1 = -1; for (++i; i < mid.size(); i++) { max1 = max(max1, back_id[(int) mid[i]]); mid_tmp.push_back(mid[i]); } for (; j < back.size() - 1 && j != (size_t) max1 + 1; j++) left.push_back(back[j]); dfs(left, mid_tmp, 1); } int main() { freopen("data3.txt", "r", stdin); puts("分别输入中序遍历顺序,和后序遍历顺序,输出先序遍历的程序"); while (~scanf("%s", str)) { ans.clear(); vector<char> mid, back; size_t i; for (i = 0; i < strlen(str); i++) { mid.push_back(str[i]); } scanf("%s", str); for (i = 0; i < strlen(str); i++) { back_id[(int) str[i]] = i; back.push_back(str[i]); } dfs(back, mid, 0); puts("下面按照先序遍历输出树形"); for (i = 0; i < ans.size(); i++) { if (!beleft[i]) printf("L "); else printf("R "); putchar(ans[i]); puts(""); } puts(""); } return 0; }
5.数据结构实验2 表达式求值
#include <stack> #include <cstdio> #include <cstring> using namespace std; stack<char> OP; stack<int> NUM; char str[1009]; bool isOP(char c) { if (c != '+' && c != '-' && c != '*' && c != '/' && c != '(' && c != ')') return 0; return 1; } int MAP[100]; bool OUT(int op) { int top_op = (int) OP.top(); if (top_op == '!' || top_op == '(') return 0; if (op == ')' || MAP[top_op] >= MAP[op]) return 1; return 0; } void init() { while (!OP.empty()) OP.pop(); OP.push('!'); while (!NUM.empty()) NUM.pop(); } void cal() { int b = NUM.top(); NUM.pop(); int a = NUM.top(); NUM.pop(); char op = OP.top(); OP.pop(); if (op == '+') NUM.push(a + b); else if (op == '-') NUM.push(a - b); else if (op == '*') NUM.push(a * b); else NUM.push((int) a / b); } int main() { freopen("data.txt", "r", stdin); MAP[(int) '-'] = MAP[(int) '+'] = 0; MAP[(int) '*'] = MAP[(int) '/'] = 1; MAP[(int) '('] = 3; while (~scanf("%s", str)) { init(); for (int i = 0; str[i]; ) { char cur = str[i]; if (!isOP(cur)){ int tmp = 0; while (str[i] && !isOP(cur)){ tmp = tmp * 10 + cur - '0'; cur = str[++i]; } NUM.push(tmp); continue; } else { if (!OUT(cur)) OP.push(cur); else { if (cur != ')') { while (OP.top() != '!' && OUT(cur)) cal(); OP.push(cur); } else { while (OP.top() != '(') cal(); OP.pop(); } } } i++; } while (OP.top() != '!') cal(); printf("%d\n", NUM.top()); } return 0; }
6.操作系统实验二 计算缺页率
先贴单进程的计算FIFO和LRU缺页率的程序
这个程序姑且算在这个分享博文中,有关OS的我开了个新博文深入讨论OS一些问题,《理解操作系统相关知识》。
#include <cstdio> #include <queue> #include <iostream> #include <string> #include <list> using namespace std; const int LRU = 1; const int FIFO = 0; int page[1009]; list<int> L; list<int>::iterator it; int main() { freopen("data3.txt", "r", stdin); string output[2] = { "FIFO", "LRU" }; int page_num, mem_size; int target; int OP; while (~scanf("%d%d", &page_num, &mem_size)) { target = 0; for (int i = 0; i < page_num; i++) scanf("%d", &page[i]); for (OP = 0; OP < 2; OP++) { L.clear(); target = 0; cout << output[OP] << endl; for (int i = 0; i < page_num; i++) { if (OP == LRU) { for (it = L.begin(); it != L.end(); it++) if (*it == page[i]) { L.erase(it); target++; break; } L.insert(L.begin(), page[i]); if ((int) L.size() > mem_size) L.erase(--L.end()); } else { for (it = L.begin(); it != L.end(); it++) if (*it == page[i]) { target++; break; } if (it == L.end()) L.insert(L.begin(), page[i]); if ((int) L.size() > mem_size) L.erase(--L.end()); } for (it = L.begin(); it != L.end(); it++) printf("%d ", *it); puts(""); } printf("命中个数:%d\n", target); printf("缺页率: %.2lf\n", (page_num - target) / (double) page_num); } } return 0; } /* 6 4 1 2 3 2 4 3 */
7.数据结构第3次实验
着急写的很水
#include <iostream> #include <cstdio> #include <cstring> #include <stack> #include <queue> using namespace std; #define MAXN 1009 int tot, head[MAXN]; char symbel[26]; struct Node{ int data; Node *L, *R; Node(){ L = R = NULL; } }; void build(Node* Root, Node* fa, int dir){ if(fa != Root) printf("%d %d connect to \n", fa->data, dir); scanf("%d\n", &Root->data); if(Root->data != -1){ Root->L = new Node; Root->R = new Node; build(Root->L, Root, 0); build(Root->R, Root, 1); }else{ if(dir == 0) fa->L = NULL; else{ fa->R = NULL; } } } int count_d(Node* Root){ if(Root == NULL) return 0; int sum = count_d(Root->L) + count_d(Root->R); if(Root->L && Root->R) return sum + 1; return sum; } void BFS(Node* Root){ queue<Node*> Q; Q.push(Root); bool vis[100] = {0}; vis[Root->data] = 1; while(!Q.empty()){ Node* cur = Q.front(); printf("%d", cur->data); Q.pop(); if(cur->L && !vis[cur->L->data]){ Q.push(cur->L); vis[cur->L->data] = 1; } if(cur->R && !vis[cur->R->data]){ vis[cur->R->data] = 1; Q.push(cur->R); } } } struct Edge { int to, next; } edge[MAXN * 4]; void init() { tot = 0; memset(head, -1, sizeof(head)); } void addedge(int u, int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } int vis[MAXN]; void BFS() { queue<int> Q; Q.push(1); memset(vis, 0, sizeof(vis)); vis[1] = 0; printf("%c", symbel[1]); while (!Q.empty()) { int cur = Q.front(); Q.pop(); for (int i = head[cur]; i != -1; i = edge[i].next) { if (!vis[edge[i].to]) { printf("%c", symbel[edge[i].to]); vis[edge[i].to] = cur; Q.push(edge[i].to); } } } puts(""); } void DFS_last(int u, int fa) { for (int i = head[u]; i != -1; i = edge[i].next) if (edge[i].to != fa) DFS_last(edge[i].to, u); printf("%c", symbel[u]); } void DFS_first(int u, int fa) { printf("%c", symbel[u]); for (int i = head[u]; i != -1; i = edge[i].next) if (edge[i].to != fa) DFS_first(edge[i].to, u); } void DFS_first_last(int u, int fa) { if (head[u] != -1) { printf("%c", symbel[u]); } else { printf("%c", symbel[u]); return; } for (int i = head[u]; i != -1; i = edge[i].next) { if (edge[i].to != fa) DFS_first_last(edge[i].to, u); printf("%c", symbel[u]); } if (head[u] == -1) printf("%c", symbel[u]); } void DFS_mid(int u, int fa) { if (head[u] == -1) { printf("%c", symbel[u]); return; } int cnt = 0; for (int i = head[u]; i != -1; i = edge[i].next) if (edge[i].to != fa) { DFS_mid(edge[i].to, u); cnt++; if (cnt == 1) printf("%c", symbel[u]); } } stack<int> sta; int count_end(int u, int fa) { if (head[u] == -1) { sta.push(u); return 1; } int sum = 0; for (int i = head[u]; i != -1; i = edge[i].next) if (fa != edge[i].to) sum += count_end(edge[i].to, u); return sum; } int main() { freopen("data_tmp.txt", "r", stdin); for (int i = 1; i <= 26; i++) symbel[i] = 'A' + i - 1; int n, u, v; while (~scanf("%d", &n)) { init(); while (!sta.empty()) sta.pop(); for (int i = 1; i < n; i++) { scanf("%d%d", &u, &v); addedge(u, v); } printf("树的叶子节点的个数为: %d\n", count_end(1, -1)); printf("按层遍历 "); BFS(); printf("先序遍历 "); DFS_first(1, -1); puts(""); printf("后序遍历 "); DFS_last(1, -1); puts(""); printf("中序遍历 "); DFS_mid(1, -1); puts(""); printf("双序遍历 "); DFS_first_last(1, -1); puts(""); while (!sta.empty()) { int cur = sta.top(); printf("%c 到叶子节点路径 ", symbel[cur]); while (cur) { printf("%c", symbel[cur]); cur = vis[cur]; } sta.pop(); puts(""); } puts("下面输出每个结点的度"); for (int i = 1; i <= n; i++) { printf("%c ", symbel[i]); if (head[i] == -1) puts("度为0"); else if (edge[head[i]].next == -1) puts("度为1"); else { puts("度为2"); swap(edge[head[i]].to, edge[edge[head[i]].next].to); } } puts("输出左右翻转后的二叉树 按层次遍历"); BFS(); } return 0; }
8.数据结构实验四
哈希表和平衡二叉树和快排的数据的整合处理,兼顾三种结构顺序存储特点,我采用了把哈希表作为根,所有信息的改变都要维护哈希表的位置信息
#include <iostream> #include <algorithm> #include <string> #include <fstream> using namespace std; #define MAXN 100004 typedef unsigned int uint; const int mut1 = 127; const int mut2 = 131; const int MOD = 2000007; const unsigned int INF = 0x3fffffff; struct STUDENT { int id; string name, ethnic, fromplace, sex; int age; STUDENT() { } void input(int _id, string _name, string _sex, string _ethnic, string _fromplace, int _age) { name = _name, ethnic = _ethnic; id = _id, fromplace = _fromplace; sex = _sex, age = _age, ethnic = _ethnic; } void output() { cout << name << " " << ethnic << " " << fromplace << " " << id << " " << sex << " " << age << endl; } } student[1001]; struct hash_map { int head[MOD], nEle; struct node { uint key1, key2; int key3, pos, pre; node() { } node(uint key1, uint key2, int key3, int pos, int pre) : key1(key1), key2(key2), key3(key3), pos(pos), pre(pre) { } } ele[MOD * 2]; void init() { nEle = 0; memset(head, -1, sizeof(head)); } int find(uint key1, uint key2, int len) { int hashcode = key1 % MOD; for (int i = head[hashcode]; i != -1; i = ele[i].pre) if (ele[i].key1 == key1 && ele[i].key2 == key2 && ele[i].key3 == len) return i; return -1; } int getPos(uint key1, uint key2, int len) { int pos = find(key1, key2, len); if (pos == -1) return -1; return ele[pos].pos; } void updata(uint key1, uint key2, int len, int pos) { int tmp = key1 % MOD; ele[nEle] = node(key1, key2, len, pos, head[tmp]); head[tmp] = nEle++; } void addstring(string s, int pos) { int len = s.length(); uint key1 = 0, key2 = 0; for (int i = 0; i < len; i++) { key1 = key1 * mut1 + s[i]; key2 = key2 * mut2 + s[i]; } updata(key1, key2, student[pos].age, pos); } } hash; #define LH 1 //左高 #define EH 0 //等高 #define RH -1 //右高 typedef struct Node { int hash_num; int data; Node() { } int bf; //结点的平衡因子 Node *LChild, *RChild; //左、右孩子指针 }*AVL; void L_Rotate(AVL &p) { Node *rc = p->RChild; p->RChild = rc->LChild; rc->LChild = p; p->bf = rc->bf = EH; p = rc; } void R_Rotate(AVL &p) { Node *lc = p->LChild; p->LChild = lc->RChild; lc->RChild = p; p->bf = lc->bf = EH; p = lc; } void LeftBalance(AVL &T) { //对以指针T所指结点为根的二叉树作左平衡旋转处理,指针T指向新的根结点 AVL lc, rd; lc = T->LChild; switch (lc->bf) { //判断*T的左子树的平衡因子 case LH: //LL,只需要一次R旋转 T->bf = lc->bf = EH; R_Rotate(T); break; case RH: //LR,新结点插入在*T的左孩子的右子树上,需要对左子树L旋转,和对T作R旋转 rd = lc->RChild; //rd指向*T的左孩子的右子树的根 switch (rd->bf) { //修改*T及其左孩子的平衡因子 case LH: T->bf = RH; lc->bf = EH; break; case EH: T->bf = lc->bf = EH; break; case RH: T->bf = EH; lc->bf = LH; break; } L_Rotate(T->LChild); //对*T的左子树作左旋平衡处理 R_Rotate(T); //对*T作右旋平衡处理 rd->bf = EH; //是新的根节点,保证平衡 } } void RightBalance(AVL &T) { AVL ld, rc; rc = T->RChild; switch (rc->bf) { case RH: //RR,只需要一次L旋转 T->bf = rc->bf = EH; L_Rotate(T); break; case LH: //RL,需要对右子树R旋转,和对T作L旋转 ld = rc->LChild; switch (ld->bf) { case LH: T->bf = EH; rc->bf = LH; break; case EH: T->bf = rc->bf = EH; break; case RH: T->bf = RH; rc->bf = EH; break; } ld->bf = EH; R_Rotate(T->RChild); L_Rotate(T); break; } } bool Insert(AVL &T, int key, int ID, bool &taller) { //若在平衡的二叉树T中不存在和e有相同关键字的结点,则插入一个数据元素 //为e的新结点,并返回1,否则返回0,旋转处理,布尔变量taller反映是否需要继续向上检验平衡因子 if (!T) { //插入新结点,树“长高”,置taller为true T = (AVL) malloc(sizeof(Node)); int len = student[ID].name.length(); uint key1 = 0, key2 = 0; for (int i = 0; i < len; i++) { key1 = key1 * mut1 + student[ID].name[i]; key2 = key2 * mut2 + student[ID].name[i]; } T->hash_num = hash.find(key1, key2, student[ID].age); T->data = key; T->LChild = T->RChild = NULL; T->bf = EH; taller = 1; return 1; } if (key == T->data) { //树中已存在和e有相同关键字的结点 taller = 0; return 0; } if (key < T->data) { //在T的左子树中搜索 if (!Insert(T->LChild, key, ID, taller)) //未插入返回 return 0; if (taller) //已插入到T的左子树中且左子树“长高” switch (T->bf) { //检查T的平衡度 case LH: //原本左子树比右子树高,需要作左平衡处理 LeftBalance(T); taller = 0; break; case EH: //原本左、右子树等高,需要作左平衡处理 T->bf = LH; taller = 1; break; case RH: //原本右子树比左子树高 T->bf = EH; taller = 0; break; } } else { //在T的右子树中搜索 if (!Insert(T->RChild, key, ID, taller)) //未插入 return 0; if (taller) //已插入到T右子树且右子树长高 switch (T->bf) { //检查T的平衡度 case LH: T->bf = EH; taller = 0; break; case EH: T->bf = RH; taller = 1; break; case RH: RightBalance(T); taller = 0; break; } } return 1; }void output(AVL T) { if (T) { output(T->LChild); student[hash.ele[T->hash_num].pos].output(); output(T->RChild); } } void findstudent(string NAME) { int len = NAME.length(); uint key1 = 0, key2 = 0; for (int i = 0; i < len; i++) { key1 = key1 * mut1 + NAME[i]; key2 = key2 * mut2 + NAME[i]; } int flag = 0; int hashcode = key1 % MOD; for (int i = hash.head[hashcode]; i != -1; i = hash.ele[i].pre) if (hash.ele[i].key1 == key1 && hash.ele[i].key2 == key2) { student[hash.ele[i].pos].output(); flag++; } if (!flag) puts("NO THIS STUDENT"); else { printf("-----> done! 为您找到了姓名为"); cout << NAME; printf("的%d人有关信息\n", flag); } puts(""); } int Partition(int low, int high) { //执行快排交换时调整哈希表记录的同学位置 int len; uint key1 = 0, key2 = 0; STUDENT t = student[low]; int stan = student[low].age; while (low < high) { while (low < high && student[high].age >= stan) high--; student[low] = student[high]; len = student[high].name.length(); key1 = 0, key2 = 0; for (int i = 0; i < len; i++) { key1 = key1 * mut1 + student[high].name[i]; key2 = key2 * mut2 + student[high].name[i]; } hash.ele[hash.find(key1, key2, student[high].age)].pos = low; while (low < high && student[low].age <= stan) low++; student[high] = student[low]; len = student[low].name.length(); key1 = 0, key2 = 0; for (int i = 0; i < len; i++) { key1 = key1 * mut1 + student[low].name[i]; key2 = key2 * mut2 + student[low].name[i]; } hash.ele[hash.find(key1, key2, student[low].age)].pos = high; } student[low] = t; len = student[low].name.length(); key1 = 0, key2 = 0; for (int i = 0; i < len; i++) { key1 = key1 * mut1 + t.name[i]; key2 = key2 * mut2 + t.name[i]; } hash.ele[hash.find(key1, key2, stan)].pos = low; return low; //返回中间元素所在的位置 } void Sort(int low, int high) { if (low < high) { int n = Partition(low, high); Sort(low, n); Sort(n + 1, high); } } int main() { freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); ifstream inFile("data3.txt"); if (!inFile) exit(1); string NAME, SEX, ETHNIC, Fromplace; int AGE, ID; inFile >> NAME >> NAME >> SEX >> ETHNIC >> Fromplace >> ETHNIC; int tot = 0; bool flag; hash.init(); AVL Root = NULL; while (!inFile.eof()) { inFile >> ID >> NAME >> SEX >> ETHNIC >> Fromplace >> AGE; student[tot].input(ID, NAME, SEX, ETHNIC, Fromplace, AGE); hash.addstring(NAME, tot); //建立姓名hash表 Insert(Root, ID, tot, flag); //建立AVL平衡二叉树,按照学号排序 tot++; } inFile.close(); puts("**********操作小提示*********"); printf( "1。输入姓名查询学生信息\n1。输入学号查询学生信息\n3。按学生学号进行排序后输出\n4。按照学生年龄排序输出\n4。输出学生年龄的平均数\n"); puts("*****************************"); puts("请输入操作"); int opr; while (1) { scanf("%d", &opr); // system("cls"); if (opr == 6) { puts("谢谢使用再见"); break; } puts("执行结果为"); if (opr == 1) { cin >> NAME; printf("基于hash表的查找结果 \n"); findstudent(NAME); } else if (opr == 2) { printf("基于平衡二叉树的查找结果 \n"); cin >> ID; AVL p = find(Root, ID); if (!p) puts("没有找到"); else student[hash.ele[p->hash_num].pos].output(); } else if (opr == 3) { printf("按学号输出所有学生\n", tot); output(Root); puts(""); } else if (opr == 4) { Sort(0, tot - 1); puts("按年龄输出所有学生") for (int i = 0; i < tot; i++) student[i].output(); } } return 0; }
9.贪吃蛇MFC游戏
本文只分享和和数据结构知识相关部分代码,完整代码见 《Windows编程》
下载 解压后即可运行游戏
下载地址 https://files.cnblogs.com/updateofsimon/Snake.zip
int POINT_X[2], POINT_Y[2]; int score = 0; int rate = 100; int change = 0; struct People { char name[20]; int num; bool operator < (const People &tmp) const { return num > tmp.num; } } people[10]; int tot; char user[20]; struct point { int x, y; }; struct Node { point data; Node *next; } top; struct Link { Node *head, *last, *pre_last; Link() { last = head = ⊤ last->next = NULL; last->data.x = 5; last->data.y = 5; } } snake; char location = 'r'; //设置初始运动方向,右 void AddList() //加入到蛇尾下面 { Node *tmp = new Node; tmp->data.x = 1000; tmp->data.y = 1000; tmp->next = NULL; snake.pre_last = snake.last; snake.pre_last->next = tmp; snake.last = tmp; } void GoAhead(int dx, int dy) { snake.pre_last->next = NULL; snake.last->data.x = snake.head->data.x + dx; snake.last->data.y = snake.head->data.y + dy; snake.last->next = snake.head; snake.head = snake.last; snake.last = snake.pre_last; snake.pre_last = snake.head; while (snake.pre_last->next != snake.last) snake.pre_last = snake.pre_last->next; }int getPoint() { if (POINT_X[0] == (snake.head->data.x) && POINT_Y[0] == (snake.head->data.y)) return 0; if (POINT_X[1] == (snake.head->data.x) && POINT_Y[1] == (snake.head->data.y)) return 1; return -1; } int check() { if (snake.head->data.x < 0||(snake.head->data.x)*11>WIDTH||snake.head->data.y < 0||(snake.head->data.y)*11>HEIGHT) return 1; for (Node *p = snake.head->next; p->next; p = p->next) if (p->data.x == snake.head->data.x && p->data.y == snake.head->data.y) return 2; return 0; } bool isOK(int x, int y) { Node *tp = snake.head; while (tp) { if(tp->data.x == x && tp->data.y == y) return 1; tp = tp->next; } return 0; }