杨氏矩阵搜索算法

杨氏矩阵搜索算法

个人信息:就读于燕大本科软件工程专业 目前大三;

本人博客:百度搜索“cqs_2012”即可;

个人爱好:酷爱数据结构和算法,希望将来搞科研为人民作出自己的贡献;

博客内容:杨氏矩阵搜索算法;

知识选自:面试题;

博客时间:2014-3-25;

 

  • 引言

昨天过生日,女朋友陪我过了我从生下来最好的一次生日,好开心有木有,还送我一个生日礼物,你们猜猜是啥,直接给大家爆照吧;

这是燕大食堂照的,她说我每天在里面放一个硬币,放满以后,我们就订婚,好开心有木有。

好了,谢谢大家一直以来对我的支持与关注,祝福大家事业有成,家庭美满。

  • 杨氏矩阵

杨氏矩阵的定义:杨氏矩阵是一个二维数组;每一行和每一列都严格递增.(有的版本是严格递减,其原理是一样的,即不存在重复元素)

  • 思路

我们先学习一个一般的算法,算法思路选自《编程之美》和《剑指offer》,我们逐步缩小杨氏矩阵的规模,直到查找到元素或者没有查找到元素;

举个例子,算法演示如下:

规模减少一行是吧,依次下去

规模减少了一列,直至找到元素或者规模减少至0为止;

C++代码,算法如下:

// function: yangshijuzheng 杨氏矩阵
template<typename T>
std::pair<bool,std::pair<size_t,size_t>> _yangshijuzhen(T** data,std::pair<size_t,size_t> s,std::pair<size_t,size_t> e,T keyword)
{
	pair<size_t,size_t> p ;
	if(data != NULL && s.first >= 0 && s.second >= 0 && e.first >= s.first && e.second >= s.second)
	{
		size_t i = s.first, j = e.second;
		while( i<= e.first && j >= s.first )
		{
			if( *(*(data+i)+j) == keyword )
			{
				p = std::make_pair(i,j);
				return std::make_pair(true,p);
			}
			else if( *(*(data+i)+j) < keyword )
			{
				i++ ;
			}
			else j-- ;
		}
		p = std::make_pair(0, 0);
		return std::make_pair(false,p) ;
	}
	else
	{
		cout<<"exception of function _yangshijuzhen input"<<endl;
		p = std::make_pair(0, 0);
		return std::make_pair(false,p) ;
	}
}


此算法时间复杂度O(N)

然后我就一直纠结于,杨氏矩阵是不是方阵,如果是方阵,还有没有可以优化的空间呢?我觉得是可以的,如果杨氏矩阵是方阵的情况下,可以模拟二分查找的方法,去查找,

举个例子,算法演示如下

取图中线上的元素集合作为二分查找的数据源,这时候我们没有找到,然后划分杨氏矩阵如下

这时候两个子矩阵都不是方针了,这时候我们就可以用刚才提到的算法解决了,可以并行计算; 如果得到的子阵中包含方阵,那子方阵就还可以用二分查找。

这只是我个人的想法,做的话肯定能解决问题,但是我分析不出来我的解法的时间复杂度,还请大神助小弟解答,敬请留言。

  • 实验

实验工具 vs2008

编程语言 C++

第一种算法实验,keyword : 54

  • 代码

test.cpp

// include: head file
#include<iostream>
#include<utility>
using namespace std;

// function: yangshijuzheng 杨氏矩阵
template<typename T>
std::pair<bool,std::pair<size_t,size_t>> _yangshijuzhen(T** data,std::pair<size_t,size_t> s,std::pair<size_t,size_t> e,T keyword);


// function: main
int main()
{
	size_t size = 10;
	int ** ysjz = new int*[size];
	for(size_t i=0;i<size ;i++)
	{
		ysjz[i] = new int[size];
	}
	for(size_t i=0;i<size;i++)
	{
		for(size_t j=0 ;j<size;j++)
		{
			ysjz[i][j] = i*10+j;
			cout<<ysjz[i][j]<<' ';
		}
		cout<<endl;
	}
	std::pair<bool,std::pair<size_t,size_t>>  p = _yangshijuzhen(ysjz,std::make_pair(0,0),std::make_pair(size-1,size-1),54);
	if( p.first )
		cout<<"line="<<p.second.first<<" ,row="<<p.second.second<<endl;
	else cout<<" not find "<<endl;
	system("pause");
	return 0;
}

// function: yangshijuzheng 杨氏矩阵
template<typename T>
std::pair<bool,std::pair<size_t,size_t>> _yangshijuzhen(T** data,std::pair<size_t,size_t> s,std::pair<size_t,size_t> e,T keyword)
{
	pair<size_t,size_t> p ;
	if(data != NULL && s.first >= 0 && s.second >= 0 && e.first >= s.first && e.second >= s.second)
	{
		size_t i = s.first, j = e.second;
		while( i<= e.first && j >= s.first )
		{
			if( *(*(data+i)+j) == keyword )
			{
				p = std::make_pair(i,j);
				return std::make_pair(true,p);
			}
			else if( *(*(data+i)+j) < keyword )
			{
				i++ ;
			}
			else j-- ;
		}
		p = std::make_pair(0, 0);
		return std::make_pair(false,p) ;
	}
	else
	{
		cout<<"exception of function _yangshijuzhen input"<<endl;
		p = std::make_pair(0, 0);
		return std::make_pair(false,p) ;
	}
}


 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值