一个 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] << "\t";
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;
}

Young氏矩阵的更多相关文章

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

    这题利用二叉堆维持堆性质的办法来维持Young氏矩阵的性质,题目提示中写得很清楚,不过确实容易转不过弯来. a,b两问很简单.直接看c小问: 按照Young氏矩阵的性质,最小值肯定在左上角取得,问题在 ...

  2. 十一、从头到尾彻底解析Hash 表算法

    在研究MonetDB时深入的学习了hash算法,看了作者的文章很有感触,所以转发,希望能够使更多人受益! 十一.从头到尾彻底解析Hash 表算法 作者:July.wuliming.pkuoliver  ...

  3. 第6章 堆排序,d叉堆,优先队列

    #include<stdio.h> #include<stdlib.h> #include<string.h> #define leftChild(i) (2*(i ...

  4. Hession矩阵(整理)

    二阶偏导数矩阵也就所谓的赫氏矩阵(Hessian matrix). 一元函数就是二阶导,多元函数就是二阶偏导组成的矩阵. 求向量函数最小值时用的,矩阵正定是最小值存在的充分条件. 经济学中常常遇到求最 ...

  5. KCF跟踪算法

    参考:https://www.cnblogs.com/YiXiaoZhou/p/5925019.html 参考:https://blog.csdn.net/shenxiaolu1984/article ...

  6. 【杨氏矩阵+勾长公式】POJ 2279 Mr. Young's Picture Permutations

    Description Mr. Young wishes to take a picture of his class. The students will stand in rows with ea ...

  7. 杨氏矩阵:查找x是否在矩阵中,第K大数

    参考:http://xudacheng06.blog.163.com/blog/static/4894143320127891610158/ 杨氏矩阵(Young Tableau)是一个很奇妙的数据结 ...

  8. 杨氏矩阵定义及其查找的实现C++

    先介绍一下这个数据结构的定义,Young Tableau有一个m*n的矩阵,然后有一数组 a[k], 其中 k<=m*n ,然后把a[k]中的数填入 m*n 的矩阵中,填充规则为: 1.  每一 ...

  9. paper 114:Mahalanobis Distance(马氏距离)

    (from:http://en.wikipedia.org/wiki/Mahalanobis_distance) Mahalanobis distance In statistics, Mahalan ...

随机推荐

  1. java后台异步任务执行器TaskManager

    java后台异步任务执行器TaskManager 此方式基于MVC方式: 一,使用任务: @Resource private TaskManager taskManager; public strin ...

  2. AIDL学习

    (转自)可以参见:http://www.2cto.com/kf/201406/312244.html 1.为什么要有AIDL? 无论学什么东西,最先得弄明白为什么要有这个东西,不要说存在即是合理,存在 ...

  3. ASP.NET MVC 5 一 入门

    本系类教程将要构建ASP.NET MVC 5 Web 应用程序,使用的工具是VS2013 .现在有预览版可以下载了, 点击下载VS2013 FOR WEB ISO文件 .VS2012 还没用几天呢,2 ...

  4. 1. IOS 9.3.3描述文件没了处理方法

    1.用手机登录:https://beta.apple.com/ 2.找到"注册您的设备" 3.往下拉第二点就是,直接点击下载即可.

  5. 基于PHP生成静态页的实现方法

    t1.php 复制代码 代码如下: <?php// 方法一根据模版生成静态页面// replaceTemplateString函数用于替换模板中指定字符串function replaceTemp ...

  6. 博客的开端,找对象不再new

    今天是第一次用blog,小白开始完善了!! 希望大家多多照顾一下.

  7. JQuery Object vs. DOM element

    JQuery Object 和 DOM的区别 HTML DOM 定义了访问和操作HTML文档的标准方法.其中 document 是DOM 树的根对象 ,在浏览器宿主环境中,可以通过JS操作HTML D ...

  8. g++与c++扩栈方法

    g++: /* * Problem: * Author: SHJWUDP * Created Time: 2015/8/5 星期三 15:54:42 * File Name: tmp.cpp * St ...

  9. 【Android UI设计与开发】第05期:引导界面(五)实现应用程序只启动一次引导界面

    [Android UI设计与开发]第05期:引导界面(五)实现应用程序只启动一次引导界面 jingqing 发表于 2013-7-11 14:42:02 浏览(229501) 这篇文章算是对整个引导界 ...

  10. Hdu OJ 5884-Sort (2016 ACM/ICPC Asia Regional Qingdao Online)(二分+优化哈夫曼)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5884 题目大意:有n个有序的序列,对于第i个序列有ai个元素. 现在有一个程序每次能够归并k个序列, ...