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


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

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

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

    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
    
    ", 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人有关信息
    ", 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。输入姓名查询学生信息
    2。对学生年龄进行排序后输出
    3。输出学生个数
    4。输出学生年龄的平均数
    5。输入ID删除学生信息
    ");
        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
    ", SHU_MIE.front->age);
                SHU_MIE.output();
                puts("");
            } else if (opr == 3) {
                printf("total number of student is %d 
    
    ", SHU_MIE.front->age);
            } else if (opr == 4) {
                printf("averge age of student is %.2lf 
    
    ",
                        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。输入姓名查询学生信息
    2。对学生年龄进行排序后输出
    3。输出学生个数
    4。输出学生年龄的平均数
    5。输入ID删除学生信息
    ");
            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>
    ");
        for (int i = 0; i <= tot_DEV; i++) {
            if (i > 0)
                printf("<unit>
    <resource>dev%d</resource>
    ", i);
            for (int j = 0; j < Ans[i].size(); j++)
                printf("<phase>%d,%d,%c</phase>
    ", 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>
    <ratio>%d</ratio>
    ", DEV_runtime[0]);
        for (int i = 1; i <= tot_DEV; i++) {
            printf("<name>dev%d</name>
    <ratio>%d</ratio>
    ", 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
    ", 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
    ", target);
                printf("缺页率: %.2lf
    ", (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 
    ", fa->data, dir);
        scanf("%d
    ", &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
    ", 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人有关信息
    ", 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。输入姓名查询学生信息
    1。输入学号查询学生信息
    3。按学生学号进行排序后输出
    4。按照学生年龄排序输出
    4。输出学生年龄的平均数
    ");
        puts("*****************************");
        puts("请输入操作");
        int opr;
        while (1) {
            scanf("%d", &opr);
    //        system("cls");
            if (opr == 6) {
                puts("谢谢使用再见");
                break;
            }
            puts("执行结果为");
            if (opr == 1) {
                cin >> NAME;
                printf("基于hash表的查找结果 
    ");
                findstudent(NAME);
            } else if (opr == 2) {
                printf("基于平衡二叉树的查找结果 
    ");
                cin >> ID;
                AVL p = find(Root, ID);
                if (!p)
                    puts("没有找到");
                else
                    student[hash.ele[p->hash_num].pos].output();
            } else if (opr == 3) {
                printf("按学号输出所有学生
    ", 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编程

    下载 解压后即可运行游戏

    下载地址 http://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;
    }
  • 相关阅读:
    docker 部署springboot
    CentOS 7 安装docker
    008自瞄原理
    007根据矩阵基地址绘制方框
    006寻找矩阵
    005分析其他人基地址
    易语言读取鼠标坐标x,y
    003获取鼠标x,y
    Oracle单机Rman笔记[0]---环境准备
    系统优化设计笔记--曹大公众号文章笔记
  • 原文地址:https://www.cnblogs.com/updateofsimon/p/3405676.html
Copyright © 2020-2023  润新知