Young氏矩阵实现代码(C++) 算法导论 6.3

个人总结:

1.int **p和 int a[M][N]之间的区别:

1) int **指向指针的指针;而后者的类型是数组名,类型为 int (*)[N],即指向的是整个一行。

2) (a+1) 地址增加M*sizeof(int),需要注意的一点是a[i]是第i行开头的地址,&a和a的值是一样的。数组是有大小的,而指针是一个存储了地址的变量。特意去看了一下声明数组的汇编代码,其中一条指令是 mov %gs:0x14,%eax (数组大小20即0x14),最后也貌似也会检查一下数组是否溢出,溢出的话会调用一个栈函数(不是很懂,应该是保护机制)。特别是调用sizeof(数组名)的时候,汇编代码并没有增加,因为数组的大小存储在栈中某个位置。

传送参数的时候需要注意传送应该传送指针还是数组。我一开始居然以为可以这么做 int **p=a;(啊!naive!)

#include <iostream>
#include <algorithm>

using namespace std;
#define INT_MAX 100000

class Y_Matrix{
public:
    Y_Matrix(int rows, int cols);
    ~Y_Matrix();
    void YM_Build(int *a, int n);
    void PrintM() const;
    void Decrease_Key(int x, int y, int key);
    int Extract_Min();
    void Insert_Key(int key){
        if (y_matrix[R - 1][C - 1] != INT_MAX)
        {
            cout << "over flow"<<endl;
            return;
        }
        Decrease_Key(R - 1, C - 1, key);
    }
    void Sort(int *array, int n);
    bool Find(int elem);
    void Clear();
private:
    const int R, C;
    int **y_matrix;
    void YM_Heapify(int x,int y);
};

Y_Matrix::Y_Matrix(int rows, int cols):R(rows),C(cols){
    y_matrix = new int *[rows];
    for (int i = 0; i < rows; ++i){
        y_matrix[i] = new int[cols];
        for (int j = 0; j < cols; ++j){
            y_matrix[i][j] = INT_MAX;
        }
    }
}
void Y_Matrix::Clear(){
    for (int i = 0; i < R; ++i)
        for (int j = 0; j < C; ++j)
            y_matrix[i][j] = INT_MAX;

}
void Y_Matrix::YM_Build(int *a, int n){
    int temp = min(n, R*C);
    for (int i = 0; i < temp; ++i){
        Insert_Key(a[i]);
    }
}

void Y_Matrix::YM_Heapify(int x, int y){
    int r = x, c = y;
    if (x + 1 < R&&y_matrix[r][c] > y_matrix[x + 1][y])
        ++x;
    if (y + 1 < C&&y_matrix[x][y] > y_matrix[r][c + 1])
    {
        x = r;
        ++y;
    }
    if (!(r == x&&c == y)){
        swap(y_matrix[x][y], y_matrix[r][c]);
        YM_Heapify(x, y);
    }
}

void Y_Matrix::Decrease_Key(int x, int y, int key){
    if (x > R - 1 || y > C - 1)
        return;
    if (key>y_matrix[x][y]){
        cout << "new element is bigger" << endl;
        return;
    }
    while (1){
        int r = x, c = y;
        y_matrix[x][y] = key;
        if (x > 0 && key < y_matrix[x - 1][y]){
            --x;
        }
        if (y > 0 && y_matrix[x][y] < y_matrix[r][c-1]){
            x = r;
            --y;
        }
        if (!(r == x&&c == y)){
            swap(y_matrix[x][y], y_matrix[r][c]);
        }
        else{
            y_matrix[x][y] = key;
            break;
        }
    }
}
int Y_Matrix::Extract_Min(){
    int temp = y_matrix[0][0];
    y_matrix[0][0] = INT_MAX;
    YM_Heapify(0, 0);
    return temp;
}

void Y_Matrix::Sort(int *array,int n){
    Clear();
    YM_Build(array, n);
    int k = min(n, R*C);
    for (int i = 0; i < k; ++i){
        array[i] = Extract_Min();
    }
}

bool Y_Matrix::Find(int key){
    int x = R - 1;
    int y = 0;
    while (x >= 0 && y < C){
        if (y_matrix[x][y] > key)
            --x;
        else if (y_matrix[x][y] < key)
            ++y;
        else return true;
    }
    return false;
}

void Y_Matrix::PrintM() const {
    for (int i = 0; i < R; ++i){
        for (int j = 0; j < C; ++j)
            cout << y_matrix[i][j] << "\t";
        cout << endl;
    }
    cout << endl;
}
Y_Matrix::~Y_Matrix(){
    for (int i = 0; i < R; ++i)
        delete[]y_matrix[i];
    delete[]y_matrix;
}

int main(){
    int a[19] = { 4, 6, 8, 2, 1, 0, 7, 4, 2, 1, 9, 5 ,1,111,2224,23,545,134,1122};
    Y_Matrix ym(5, 5);
    ym.YM_Build(a, 19);
    ym.PrintM();
    ym.Sort(a, 19);
    for (int i = 0; i < 19; ++i)
        cout << a[i] << " ";
}
时间: 2024-08-05 21:22:59

Young氏矩阵实现代码(C++) 算法导论 6.3的相关文章

算法导论 6-3 Young氏矩阵

一.题目 二.思考 最小Young氏矩阵和最小堆的思想差不多,可以通过比较两者的同异来理解Young氏矩阵 不同点:   min-Heap min-Young 堆顶(最小值) H[1] Y[i][j] 最后一个元素的位置 H[N] Y[N][N] 最后一个元素 不一定是最大值 一定是最大值 parent H[i]的parent是H[i/2] Y[i][j]的parent是Y[i-1][j]和Y[i][j-1] child H[i]的child是H[i*2]和H[i*2+1] Y[i][j]的ch

算法导论 第六章 思考题6-3 Young氏矩阵

这题利用二叉堆维持堆性质的办法来维持Young氏矩阵的性质,题目提示中写得很清楚,不过确实容易转不过弯来. a,b两问很简单.直接看c小问: 按照Young氏矩阵的性质,最小值肯定在左上角取得,问题在于取出最小值后如何保持矩阵的性质.可以参照max_heapify中的做法,先取出最小值,然后将矩阵左上角置为最大值,这样左上角处的元素必然导致Young氏矩阵的性质违背,于是考虑该元素右边的元素和该元素下边的元素,问题是该与右边元素交换还是与下边元素交换呢?可以发现,如果与T(右)和T(下)中较小的

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,插入元素到矩阵的右下角(

Young氏矩阵类C++实现代码 算法导论6.3

个人总结: 1.int **p和 int a[M][N]之间的区别: 1) int **指向指针的指针:而后者的类型是数组名,类型为 int (*)[N],即指向的是整个一行. 2) (a+1) 表示地址增加M*sizeof(int),需要注意的一点是a[i]是第i行开头的地址,&a和a的值是一样的.数组名是附带大小属性的,而指针是一个存储了地址的变量.特意去看了一下声明数组的汇编代码,其中一条指令是mov %gs:0x14,%eax  (数组大小20即0x14),最后也貌似也会检查一下数组是否

算法导论 之 动态规划 - 矩阵链相乘

1 引言 在大学期间,我们学过高等数学中的线性规划,其中有关于矩阵相乘的章节:只有当矩阵A的列数与矩阵B的行数相等时,A×B才有意义.一个m×n的矩阵A(m,n)左乘一个n×p的矩阵B(n,p),会得到一个m×p的矩阵C(m,p).矩阵乘法满足结合律,但不满足交换律. 假设现要计算A×B×C×D的值,因矩阵乘法满足结合律,不满足交换律,即:A.B.C.D相邻成员的相乘顺序不会影响到最终的计算结果,比如: A×(B×(C×D)).A×((B×C)×D).(A×B)×(C×D).A×(B×C)×D.

算法导论------------------动态规划之矩阵链问题

[问题描述] 给定有n个连乘矩阵的维数,要求计算其采用最优计算次序时所用的乘法次数,即所要求计算的乘法次数最少.例如,给定三个连乘矩阵{A1,A2,A3}的维数分别是10*100,100*5和5*50,采用(A1A2)A3,乘法次数为10*100*5+10*5*50=7500次,而采用A1(A2A3),乘法次数为100*5*50+10*100*50=75000次乘法,显然,最好的次序是(A1A2)A3,乘法次数为7500次. 分析: 矩阵链乘法问题描述: 给定由n个矩阵构成的序列[A1,A2,.

算法导论-矩阵乘法-strassen算法

目录 1.矩阵相乘的朴素算法 2.矩阵相乘的strassen算法 3.完整测试代码c++ 4.性能分析 5.参考资料 内容 1.矩阵相乘的朴素算法 T(n) = Θ(n3) 朴素矩阵相乘算法,思想明了,编程实现简单.时间复杂度是Θ(n^3).伪码如下 1 for i ← 1 to n 2 do for j ← 1 to n 3 do c[i][j] ← 0 4 for k ← 1 to n 5 do c[i][j] ← c[i][j] + a[i][k]⋅ b[k][j] 2.矩阵相乘的stra

算法导论--动态规划(矩阵链乘法)

矩阵链乘法问题 给定一个n个矩阵的序列?A1,A2,A3...An?,我们要计算他们的乘积:A1A2A3...An.因为矩阵乘法满足结合律,加括号不会影响结果.可是不同的加括号方法.算法复杂度有非常大的区别: 考虑矩阵链:?A1,A2,A3?.三个矩阵规模分别为10×100.100×5.5×50 假设按((A1A2)A3)方式,须要做10?100?5=5000次,再与A3相乘,又须要10?5?50=2500,共须要7500次运算: 假设按(A1(A2A3))方式计算.共须要100?5?50+10

快速排序实现代码 算法导论7.1 7.2 7.4

快速排序通常是实际排序中应用最好的选择,因为平均性能很好,且是原址排序,不稳定. 书上的大部分内容在分析其运行时间,感觉看一下就好了(还是蛮喜欢数学的,可是...) #include <iostream> #include <algorithm> #include <random> using namespace std; //实际应用比较多,原址排序 typedef int index; index Partition(int *a, index p, index r