2020软件工程作业04

这个作业属于哪个课程 班级链接
这个作业要求在哪里 2020软件工程作业04
这个作业的目标 算法
其他参考文献 leetcode 教程
学号 20189602

1.区间k大数查询

解题思路

利用快速排序的partition操作来实现,因为对于一个排序好的数组其第k大数的index为数组长度减去K刚好与partition的轴点一致(partition完后轴点所在位置刚好是其排序完后最终在数组里的位置),因此当index只等于轴点时要找的这个数刚好是轴点这个数。当index在轴点左边时我们就只需要对左边数组进行partition操作,在右边时我们只需要对轴点右边的数组进行partition操作。若轴点随机分配在数量够大的情况下可以保证每一层操作需要进行循环的数减半。

对数器通过对数组排序后直接通过index来访问他的数值。

时间复杂度:o(n)

空间复杂度:o(1)

解题代码

#include <iostream>
#include <vector>
#include <time.h>
#include <algorithm>

using namespace std;


class Solution {
public:
    //leetcode
    int parition(vector<int> &nums, int l, int r) {
        int j = l;
        //随机轴点位置
        int pivot = rand() % (r - l + 1) + l;
        int val = nums[pivot];
        //将轴点扔到最右边
        swap(nums[pivot], nums[r]);
        while (j < r) {
            if (nums[j] < val) {
                swap(nums[j], nums[l]);
                l++;
            }
            j++;
        }
        //将轴点放回中间(左边<轴点;右边>轴点)
        swap(nums[l], nums[r]);
        return l;
    }

    int findKthLargest(vector<int> &nums, int k) {
        int l = 0;
        int r = nums.size() - 1;
        //第k大的index值
        int index = nums.size() - k;
        while (l < r) {
            //轴点坐标
            int p = parition(nums, l, r);
            if (p == index) {
                return nums[p];
            } else if (index < p) {
                r = p - 1;
            } else {
                l = p + 1;
            }
        }
        return nums[r];
    }
    //leetcode end

    int sorts(vector<int> vector, int k) {
        sort(vector.begin(), vector.end());
        int d = vector[vector.size() - k];
        return d;
    }
};

//对数器
bool test(int times) {
    srand((int) time(nullptr));
    Solution s = *new Solution;
    //数组大小
    int num = rand() % 1000 + 1;
    vector<int> nums(num);
    vector<int> sortResults;
    vector<int> findResults;
    sortResults.clear();
    findResults.clear();
    //填充数组
    generate(nums.begin(), nums.end(), [] { return rand() % 1000000; });
    //m l r k
    int m, l, r, k;
    m = times;
    for (int i = m; i > 0; --i) {
        srand(rand());
        r = rand() % num + 1;
        srand(rand());
        l = rand() % r;

        do {
            srand(rand());
            k = rand() % (r - l + 1) + 1;
            //k<= r-l+1
        } while (k > r - l + 1);
        vector<int> temps;
        temps.clear();
        vector<int>::const_iterator first = nums.begin() + l - 1;
        vector<int>::const_iterator last = nums.begin() + r;
        temps.assign(first, last);
        //findKthLargest
        findResults.push_back(s.findKthLargest(temps, k));
        temps.assign(first, last);
        //sort
        sortResults.push_back(s.sorts(temps, k));

        temps.clear();
    }
    //验证
    return findResults == sortResults;
}

int main() {
    Solution s = *new Solution;
    vector<int> nums;
    vector<int> results;
    int n, temp, m, l, r, k;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> temp;
        nums.push_back(temp);
    }
    cin >> m;
    for (int j = m; j > 0; --j) {
        cin >> l >> r >> k;
        vector<int> temps;
        vector<int>::const_iterator first = nums.begin() + l - 1;
        vector<int>::const_iterator last = nums.begin() + r;
        temps.assign(first, last);
        results.push_back(s.findKthLargest(temps, k));
    }
//    输出
    cout << endl;
    for (int i: results) {
        cout << i << endl;
    }
    for (int i = 0; i < 10; ++i) {
        cout << i * 10 << "-" << (i + 1) * 10 << "万次:";
        test(100000) ? cout << "验证正确" << endl : cout << "验证错误" << endl;
    }
}


因为蓝桥杯没有授权账号无法做题所以使用了leetcode


2.二叉树的先、中、后 序遍历与层级遍历

解题思路

前中后序遍历只需要用递归实现,层级遍历使用队列先讲根节点加入队列中然后递归的调用levelOrder函数分别用左右节点当参数传入并每次输出队列的队头元素。

解题代码

#include <bits/stdc++.h>

using namespace std;

class Node {
public:
    char data;
    Node *left;
    Node *right;

    Node(char d) {
        data = d;
        left = NULL;
        right = NULL;
    }
};

class Solution {
public:
    //二叉排序树
            /*  二叉树的结构
                      A 
                    /   \
                   6   	  T
                 /   \   /
                5     9 D
	      /	       / \
             4        B   N
           /     
          1        
         */
    Node *insert(Node *root, char data) {
        if (root == NULL) {
            return new Node(data);
        } else {
            Node *cur;
            if (data <= root->data) {
                cur = insert(root->left, data);
                root->left = cur;
            } else {
                cur = insert(root->right, data);
                root->right = cur;
            }

            return root;
        }
    }

    void preOrder(Node *root) {
        if (!root) {
            return;
        }
        cout << root->data << " ";
        preOrder(root->left);
        preOrder(root->right);
    }
    void inOrder(Node *root) {
        if (!root) {
            return ;
        }
        inOrder(root->left);
        cout<<root->data<<" ";
        inOrder(root->right);
    }
    void postOrder(Node *root) {
        if (!root) {
            return ;
        }
        postOrder(root->left);
        postOrder(root->right);
        cout<<root->data<<" ";
    }
    void levelOrder(Node * root) {
        queue<Node*> q;
        q.push(root);
        while (!q.empty())
        {
            Node* root = q.front();
            q.pop();
            cout << root->data << ' ';
            if (root->left) q.push(root->left);
            if (root->right) q.push(root->right);
        }
    }
};

int main() {
    Solution s = *new Solution;
    Node *root = nullptr;
    int n = 0;

    //手动输入
//    cin >> n;
//    for (int i = 0; i < n; ++i) {
//        char data;
//        cin >> data;
//
//        root = s.insert(root,data);
//    }
    root = s.insert(root,'A');
    root = s.insert(root,'T');
    root = s.insert(root,'6');
    root = s.insert(root,'D');
    root = s.insert(root,'N');
    root = s.insert(root,'5');
    root = s.insert(root,'B');
    root = s.insert(root,'4');
    root = s.insert(root,'1');
    root = s.insert(root,'9');
    cout<<"前序:";
    s.preOrder(root);
    cout << endl;
    cout<<"中序:";
    s.inOrder(root);
    cout << endl;
    cout << "后序:";
    s.postOrder(root);
    cout << endl;
    cout << "层次:";
    s.levelOrder(root);
    cout << endl;
}

posted @ 2020-10-24 14:06  C148946051  阅读(177)  评论(1编辑  收藏  举报