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] << "\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氏矩阵的更多相关文章
- 算法导论 第六章 思考题6-3 Young氏矩阵
这题利用二叉堆维持堆性质的办法来维持Young氏矩阵的性质,题目提示中写得很清楚,不过确实容易转不过弯来. a,b两问很简单.直接看c小问: 按照Young氏矩阵的性质,最小值肯定在左上角取得,问题在 ...
- 十一、从头到尾彻底解析Hash 表算法
在研究MonetDB时深入的学习了hash算法,看了作者的文章很有感触,所以转发,希望能够使更多人受益! 十一.从头到尾彻底解析Hash 表算法 作者:July.wuliming.pkuoliver ...
- 第6章 堆排序,d叉堆,优先队列
#include<stdio.h> #include<stdlib.h> #include<string.h> #define leftChild(i) (2*(i ...
- Hession矩阵(整理)
二阶偏导数矩阵也就所谓的赫氏矩阵(Hessian matrix). 一元函数就是二阶导,多元函数就是二阶偏导组成的矩阵. 求向量函数最小值时用的,矩阵正定是最小值存在的充分条件. 经济学中常常遇到求最 ...
- KCF跟踪算法
参考:https://www.cnblogs.com/YiXiaoZhou/p/5925019.html 参考:https://blog.csdn.net/shenxiaolu1984/article ...
- 【杨氏矩阵+勾长公式】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 ...
- 杨氏矩阵:查找x是否在矩阵中,第K大数
参考:http://xudacheng06.blog.163.com/blog/static/4894143320127891610158/ 杨氏矩阵(Young Tableau)是一个很奇妙的数据结 ...
- 杨氏矩阵定义及其查找的实现C++
先介绍一下这个数据结构的定义,Young Tableau有一个m*n的矩阵,然后有一数组 a[k], 其中 k<=m*n ,然后把a[k]中的数填入 m*n 的矩阵中,填充规则为: 1. 每一 ...
- paper 114:Mahalanobis Distance(马氏距离)
(from:http://en.wikipedia.org/wiki/Mahalanobis_distance) Mahalanobis distance In statistics, Mahalan ...
随机推荐
- 树莓派3 Windows 10 IoT Core
下载地址:https://developer.microsoft.com/zh-cn/windows/iot/Downloads 先下载安装 Windows 10 IoT 核心版仪表板: 安装完成后运 ...
- lua中的协程
lua中的协程和线程类似: 1. 协程拥有自己的独立的栈,局部变量,和指令: 2. 所有协程都可以共享全局变量: 3. 协程不能像线程那样并行执行,协程之间需要相互协调执行,同一个时刻只能运行一个协程 ...
- <meta http-equiv="refresh" content="0; url=">是什么意思?
页面定期刷新,如果加url的,则会重新定向到指定的网页,content后面跟的是时间(单位秒),把这句话加到指定网页的<head></head>里一般也用在实时性很强的应用中, ...
- WebService到底是什么?
一.序言 大家或多或少都听过WebService(Web服务),有一段时间很多计算机期刊.书籍和网站都大肆的提及和宣传WebService技术,其中不乏很多吹嘘和做广告的成分.但是不得不承认的是Web ...
- 返回记录结构时,如果需要返回为nil时 应该怎么办。
- Oracle Database 11G R2 标准版 企业版 下载地址(转)
转自:http://blog.itpub.net/628922/viewspace-759245/ 不需要注册,直接复制到迅雷或其他下载软件中即可下载. oracle 11.2.0.3 下载地址: L ...
- 解决Nginx: [error] open() "/usr/local/Nginx/logs/Nginx.pid
重新启动服务器,访问web服务发现无法浏览啦!登陆服务器之后进到nginx使用./nginx -s reload重新读取配置文件,发现报nginx: [error] open() "/usr ...
- delphi模拟按键精灵自动控制PDF页面自动扩边的源代码
需要的环境:Adobe Acrobat 7.0 Professional 和 Quite Imposing Plus 1.5d Acrobat plugin (qi160.exe) 程序界面: ...
- mysql - 行号
1. 初始化数据 - 列唯一 DROP TABLE IF EXISTS `sales`; CREATE TABLE `sales` ( `empid` ) NOT NULL, `mgrid` ) NO ...
- swift 代码添加lable
let lable1 = UILabel(frame: CGRect(x: CGFloat(self.view.bounds.width/2-20), y: CGFloat(history.frame ...