zoukankan      html  css  js  c++  java
  • Young氏矩阵

    一个 m x n 的Young氏矩阵是指,每一行数据都是从左到右排好序,每一列的数据也都是从上到下排好序。其中也可能存在一些INF的数据,表示不存在的元素,一个mxn的Young氏矩阵最多用来存放 r <= mn个元素。

    详细见《算导》P.83

    Young氏矩阵类似于堆的结构,主要实现的API包括以下:

    1. void insert(int x)

    功能:将一个元素x插入到矩阵中,复杂度O(m+n)

    算法过程:

    1) 判断矩阵是否为Full

    2) 如果不为Full,插入元素到矩阵的右下角(row, col)位置,然后进行swim(row, col)将元素移动到合适位置。

    2. int getMin()

    功能:返回矩阵中的最小值,复杂度O(1)

    算法过程:

    1) 判断矩阵是否为Empty

    2) 直接返回mat[0][0].左上角元素,依据矩阵的性质

    3. int delMin()

    功能:返回矩阵中的最小值,并把它从矩阵中删除,复杂度O(m+n)

    算法过程:

    1) 判断矩阵是否为Empty

    2) 暂存mat[0][0]元素用于返回,把矩阵最右下角的元素放到mat[0][0],使用sink(0, 0)进行下沉调整元素到合适位置

    4. bool seach(int x)

    功能:判断矩阵是否存在元素x,复杂度O(m+n)

    算法过程:

    版本1:通过递归的方式,比较当前mat[x][y] 和 key的关系,将划分到是否需要在(m-1)x(n)子矩阵和mx(n-1)子矩阵进行递归查找

    版本2:初始位置为矩阵右上角,如果当前元素大于key,向左移动,如果当前元素小于key向下移动。

    5. void sort()

    功能:对矩阵元素进行排序,对矩阵执行元素个数次的delMin()操作就可以得到排序结果。复杂度O(n*m*(n+m))

    辅助函数:

    ==两个函数的实现与实现堆的swim和sink操作思想完全一样==

    void swim(int i, int j)

    功能:对(i, j)位置元素进行上浮操作,与(i-1, j) 和 (i, j-1)位置的元素进行比较,与他们之间的最大值进行交换

    void sink(int i, int j)

    功能:对(i, j)位置元素进行下沉操作,与(i+1, j) 和 (i, j+1)位置的元素进行比较, 与他们之间的最小值进行交换

    完整代码如下:

    const int INF = 0x3fffffff;
    
    class YoungMatrix {
    public:
        YoungMatrix(int row, int col); // constructor
        ~YoungMatrix(); // destructor
        
        void insert(int x); // insert a element
        int delMin(); // delete and return the minimal element  
        bool search(int x, int version = 1); // search a element
        int getMin(); // return the minimal element
        // sort(); // 调用 n*n delMin()得到结果n*n*(n+n) O(n^3)
    
        // print the matrix
        void printMatrix() {
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++)
                    cout << mat[i][j] << "	";
                cout << endl;
            }
            cout << endl;
        }
    
        /*** auxiliary function ***/
    private:
        void swim(int i, int j); // swim the element at (i, j), 从右下角上升到左上角
        void sink(int i, int j); // sink the element at (i, j), 从左上角下沉到右下角 
        bool searchHelp1(int x, int y, int key); // recursive function to search the element, divide the problem into sub-matrix (m, n-1) and (m-1, n)
        bool searchHelp2(int key); // init the position in (0, col-1). like go down the stairs from right to left
    
    private: 
        int **mat;
        int row, col;
        int num;
    };
    
    YoungMatrix::YoungMatrix(int row, int col) {
        this->num = 0;
        this->row = row;
        this->col = col;
        mat = new int*[row];
        for (int i = 0; i < row; i++)
            mat[i] = new int[col];
        for (int i = 0; i < row; i++)
        for (int j = 0; j < col; j++)
            mat[i][j] = INF;
    }
    
    YoungMatrix::~YoungMatrix() {
        for (int i = 0; i < row; i++)
            delete[] mat[i];
        delete[] mat;
    }
    
    void YoungMatrix::swim(int i, int j) {
        while (true) {
            int v = mat[i][j], p = -1;
            if (i - 1 >= 0 && v < mat[i - 1][j]) { v = mat[i - 1][j], p = 0; }
            if (j - 1 >= 0 && v < mat[i][j - 1]) { v = mat[i][j - 1]; p = 1; }
    
            if (p == -1) break;
    
            if (p == 0) {
                swap(mat[i - 1][j], mat[i][j]);
                i -= 1;
            }
            else {
                swap(mat[i][j - 1], mat[i][j]);
                j -= 1;
            }
        }
    }
    
    void YoungMatrix::sink(int i, int j) {
        while (true) {
            int v = mat[i][j], p = -1;
            if (i + 1 < row && v > mat[i + 1][j]) { v = mat[i + 1][j], p = 0; }
            if (j + 1 < col && v > mat[i][j + 1]) { v = mat[i][j + 1]; p = 1; }
    
            if (p == -1) break;
    
            if (p == 0) {
                swap(mat[i + 1][j], mat[i][j]);
                i += 1;
            }
            else {
                swap(mat[i][j + 1], mat[i][j]);
                j += 1;
            }
        }
    }
    
    void YoungMatrix::insert(int x) {
        // is full?
        if (num == col * row) {
            cerr << "Error: the matrix is full" << endl;
            return;
        }
        
        // put at the last position
        this->num++;
    
        int i = row - 1, j = col - 1;
        mat[i][j] = x;
        swim(i, j);
    }
    
    int YoungMatrix::getMin() {
        if (this->num > 0) return mat[0][0];
        else {
            cerr << "Error: The matrix is empty" << endl;
            return -1;
        }
    }
    
    int YoungMatrix::delMin() {
        if (this->num <= 0) {
            cerr << "Error: The matrix is empty" << endl;
            return -1;
        } else {
            int ret = mat[0][0];
            mat[0][0] = mat[row - 1][col - 1];
            this->num--;
            sink(0, 0);
            return ret;
        }
    }
    
    bool YoungMatrix::search(int x, int version) {
        if (this->num <= 0) return false;
        if (version == 1) {
            return searchHelp1(0, 0, x);
        } else {
            return searchHelp2(x);
        }
    }
    
    
    bool YoungMatrix::searchHelp1(int x, int y, int key) {
        if (x >= row || y >= col) return false;
        if (mat[x][y] < key) return searchHelp1(x + 1, y, key) || searchHelp1(x, y + 1, key);
        else if (mat[x][y] > key) return false;
        else return true;
    }
    
    bool YoungMatrix::searchHelp2(int key) {
        int i = 0, j = col - 1;
        while (true) {
            if (i >= row || j >= col) return false;
            if (mat[i][j] == key) return true;
            else if (mat[i][j] < key) i++;
            else if (mat[i][j] > key) j--;
        }
    }

    测试代码:

    #include "YoungMatrix.h"
    using namespace std;
    
    int a[] = { 9, 16, 3, 2, 4, 8, 5, 14, 12 };
    
    int main(int argc, char** argv) {
        YoungMatrix ym(4,4);
        int e;
        for (int i = 0; i < 9; i++) {
            ym.insert(a[i]);
        }
        ym.printMatrix();
        cout << "search result: " << ym.search(2, 2) << endl;
        cout << ym.delMin() << endl;
        cout << "search result: " << ym.search(2, 2) << endl;
         ym.printMatrix();
        return 0;
    }
  • 相关阅读:
    java 调用摄像头拍照
    jenkins docker sop
    springboot多环境打包
    docker构建nginx
    docker 构建jdk-tomcat基础镜像
    docker 构建jar 镜像
    docker 构建springmvc war项目
    centos 启动jar脚本
    nginx dockerfile
    Starting zookeeper ... FAILED TO START
  • 原文地址:https://www.cnblogs.com/tiny656/p/3959433.html
Copyright © 2011-2022 走看看