【完结】大二上课内作业与实验代码分享

大二上《数据结构》《操作系统》作业和实验代码

随着大二上学期结束,本博文完结停止更新。

完整操作系统部分代码见博文《理解操作系统相关知识

 

 

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 = &top;
        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;
}

 

posted @ 2013-11-03 23:22  匡时@下一站.info  阅读(439)  评论(0编辑  收藏  举报