现在的位置: 首页 > 综合 > 正文

Matlab类与链表

2013年08月23日 ⁄ 综合 ⁄ 共 4477字 ⁄ 字号 评论关闭

      最初知道matlab可以创建链表是通过阅读博客:matlab中实现链表知道的。然后通过仔细阅读matlab帮助文档,终于自己搞明白如何利用matlab创建链表。首先介绍matlab中的类。

1 matlab中的class

      起初认为matlab是面向过程式的语言,通过编写一系列函数或者脚本完成任务,但其实matlab中也可以通过创建类的方式实现面向对象编程。其实自己早就应该发现,在File的New菜单中第三项就是class(图一),但是囿于固有思维,从来没有深究过。

图1  matlab File菜单中New选项的菜单项

1.1 类文件夹

       当要创建一个类时,我们应该将类文件放在什么位置。matlab为我们提供了两种方法:

1. 在matlab路径下创建一个文件夹,然后在文件夹中创建一个单独的自包含的类定义(图二);

2. 在matlab路径下,创建一个@+类名的文件夹,在其中创建一个类,同时我们可以将类的定义分散在多个文件中,也即该文件夹下都是该类的定义;

图2 方式一创建类

图3 方式二创建类

       和其他高级语言(java)类似,matlab还允许我们将这些类组织成包(packages)。包文件夹的父文件夹必须在matlab路径下,但是包文件夹不必。包文件夹以‘+’开头,可以包含多个类定义或者其他的包(图四)。一个包文件夹定义了一个新的命名空间,所以我们可以重用类名。引用包中的类或者函数时需要包含包名称,例如packagefld1.ClassNameA(),packagefld2.packageFunction()。

图4 包文件夹的结构

       更多细节可参考matlab帮助中的Class Folders部分(在搜索框中输入Class Folders搜索即可)。

1.2 类定义

       要创建一个类,matlab会自动帮我们生成一个类框架,一般如下:

classdef (attribute1 = value,...) classname(< superclass_name

  
properties

      PropName

   end

  
methods

      methodName

   end        

   events

      EventName

   end

end

      类名必须要与文件名相同,第一个括号中声明类的属性,类似于java中的public等关键词,更详细的解释可参考:Class Attributes。第二个括号指明类是否需要继承父类,类似于java中的extends关键字或者C++中的‘:’。matlab支持多重继承,更详细的解释可参考:Creating
Subclasses —Syntax and Techniques。在实现链表的过程中,我们需要继承handle类。完整的一个类模块如下图:

图5 一个完整的类模块

       properties类似于java或C++中的成员变量,我们也可以给其设定各种访问属性,更详细的解释可参考:Defining Properties。

       methods就是具体的函数实现。有很多种不同类型的函数,下面简要介绍:

  • 普通函数(Ordinarymethods)。我们实现的大部分都是普通函数,它负责完成该类要完成的主要任务。
  • 构造函数(Constructormethods)。和其他高级语言类似,也必须是类名,用来给属性赋值。唯一不同是它必须返回它创建的对象。更详细的解释可参考:Class Constructor Methods。
  • 析构函数(Destructormethods)。名字必须是delete,用来释放空间。更详细的解释可参考:Handle Class Delete Methods。
  • 属性访问函数(Propertyaccess methods)。类似于其他高级语言中的set、get函数。更详细的解释可参考:Controlling PropertyAccess。
  • 静态函数(Staticmethods)。类似于其他高级语言中的静态函数,通过类对象进行访问。
  • 转换函数(Conversionmethods)。是对其他类构造函数的重载,可以将自己定义类的对象转换成重载构造函数类的对象。更详细的解释可参考:Converting Objects to Another Class。
  • 抽象函数(Abstractmethods)。无需解释,用来在子类中继承的函数。

      对于events部分,自己缺乏了解,大家可以参考Defining Events and Listeners — Syntax and Techniques章节自己去研究。

1.3 普通函数

       普通函数是我们平时写程序用的最多的函数,所以对其使用做更多的介绍。

1.3.1 基本构成

       下面是一个函数演示:

classdef ClassName

   methods
(AttributeName = value,...
)

      function x =compute(obj,inc)

         x = obj.y + inc;

      end 

   end 

end 

       可以看出其定义和在matlab中编写一个函数文件很类似,就是多了一个函数属性。同时我们需要注意:非静态函数需要显示包含类对象,matlab暂时不支持隐式调用类对象。

1.3.2 调用规则

       当matlab调用一个普通函数时,它按如下规则决定该调用哪一个函数:

1. 方法的第一个参数对应类级别最高的情况下,调用该类的函数定义;

2. 上述类没有定义该函数,则从matlab路径中寻找函数。

      针对规则一,matlab帮助中有一个例子:For example, suppose classA defines classB as inferior and supposeboth classes define a method called combine. Calling the method with an objectof
classB and classA: combine(B,A),actuallycalls the combine method of classA because A is the dominant argument.

1.3.3 调用方式

     调用类的函数时,我们可以采用两种方式:

1. 可以直接调用函数,然后第一个参数是类对象,或者

2. 将第一个参数类对象提到函数前面,然后加‘.’,类似于其他高级语言中的方法调用,推荐第二种方。

     当然在极特殊的情况下,两种方式会得到不同的结果,具体可参考:Determining Which Method Is Invoked。

1.4 静态函数

       静态函数一般用在不需要创建对象就可以调用的情况下。下面是一个具体的静态函数定义:

classdef myClass

   ...

   methods(Static)

      function p = pi(tol)

         [n d] = rat(pi,tol);

         p = n/d;

      end

    end

end

       我们需要做的就是将函数的属性声明成Static,然后第一个参数也不必是类对象,调用的时候直接用类名调用。

2 matlab下链表的实现方法

       在matlab示例代码中,包含一个双向链表的例子,就是一开始博客中提到的例子。该代码实现了一个双向链表值得我们仔细研究。其代码在目录:…\help\techdoc\matlab_oop\examples\@dlnode下。我们仿照该代码实现一个单向链表。

       首先定义一个节点类node:

classdef node <handle

   
properties

       data

   
end

   
properties
(SetAccess = public)

       next

   
end

   

   
methods

       function node = node(data)

           if nargin > 0

                node.data=data;

           end

       end

      end

end

      
该类必须继承于handle,然后有一个data属性,用来保存数据,和一个next属性,用来指向下一个节点。

      
之后定义一个链表类linkedlist:

classdef linkedlist <handle

 

   
properties
(GetAccess = public, SetAccess = public)

       head

       tail

       size

end

 

methods

       %创建一个空的链表,是构造函数

       function list = linkedlist()

           list.size=0;       

       end

 

%在链表的尾部添加一个元素

       function append(list,node)

           if isempty(list.head)

                list.head=node;

                list.tail=node;

           else

                list.tail.next=node;

                list.tail=node;

           end

           list.size=list.size+1;

       end

             %从链表的头部删除一个元素

            function temp=deletefromhead(list)

                   
if
isempty(list.head)

                         %disp('The linked list is empty');

                       temp=0;

                       list.size=0;

                      return;

                   
else

                       temp=list.head;

                       list.head=list.head.next;

                       temp.next=[];

                      list.size=list.size-1;

                   
end

              end

      end

end

      从上述定义,我们可以看出matlab下的链表实现和c或java语言下很类似。这也说明了语言本身并不是非常重要,关键是要理解算法

     上面是我对matlab类和链表实现的理解,很多地方是从其帮助文档中直接翻译过来的,很多地方翻译的也不是很好,还请直接参看帮助文档。

 

抱歉!评论已关闭.