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 ...
随机推荐
- Functional testing - python, selenium and django
Functional testing - python selenium django - Source Code : from selenium import webdriverfrom sele ...
- uploadify图片上传发生Security Error
今天在使用uploadify进行图片上传的时候出现security error.其根本原因是flash跨域问题.主要原因是因为配了两个域名www.ttyouni.com 和 ttyouni.com 在 ...
- 转:Connection: close和Connection: keep-alive有什么区别?
原文:http://www.cnblogs.com/TinyMing/p/4597136.html 一.问题现象: 一个JSP页面,居然要耗时40多秒.网页中有大量的图片的CSS问题解决: 原因也找了 ...
- C# 指定物理目录下载文件,Response.End导致“正在中止线程”异常的问题
FileHandler http://www.cnblogs.com/vipsoft/p/3627709.html UpdatePanel无法导出下载文件: http://www.cnblogs.co ...
- Qlikview 处理交叉表数据
数据来源于crossTable的时候,如何将数据做明细显示. 如图示交叉表数据 使用表格向导,选择交叉表按钮, 结果达到目的. 相关脚本. Month, 表示将要新加的字段的列明,Orders 为明细 ...
- HtmlAgilityPack下载开启压缩的页面乱码
当一个被采集的网页是开启压缩了的话,如果使用HtmlAgilityPack 的HtmlWeb默认配置去下载,下载回来的HTML代码是乱码,应该进行如下操作 HtmlWeb web = new Html ...
- c#基础-类型基础深入了解
对象类型需要动态内存,基础类型需要静态内存 动态内存分配在堆上,静态内存分配在栈上. 静态内存保存着简单的变量,如 int a=0; 值类型:把一个值类型赋值给另外一个值类型,改变其中一个另外一个不会 ...
- Web前端之html_day1
1.html结构 1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html> <html lang="en"> <head> ...
- C 数据类型 长度
----数据类型长度 C99标准并不规定具体数据类型的长度大小.计算机具有不同位数的处理器,16,32和更高位的64位处理器,在这些不同的平台上,同一种数据类型具有不同的长度. char,short, ...
- 【原】JS原型的动态性及实例与原型的关系
今天再读了<JS高程>的第六章,有了些深入的感悟和理解,总结分享一下. 创建对象的方式有很多,有一种是动态原型模式,最实用的是构造函数与原型组合的模式,原型的动态性在这两个模式里都有所体现 ...