您的位置:首页 > 理论基础 > 数据结构算法

数据结构系列教程(二)

2006-10-24 15:47 393 查看
[align=left]线性表的概念大家应该还记得,链式表是线性表的一个分类,当然也具备线性表的所有特性了,只不过它的结构方式特异而已,也就是和链子似的,和顺序表的不同之处在于链式表引入对象应用,就是其他语言中的指针,每个链子(我自己的说法)包含一个数据元素(element)和一个指针域(next),这个链子就称为节点,通俗的说有很多节点连接成的线性表就是链式表,根据其结构方式又可以分为单链表、单循环链表、双向链表,还有一种不常用的仿真链表,所有的链表都有一个共同的特征,都是由节点组成,根据前一章的思想我们很自然的会想到要构造一个节点类Node.java:[/align]
[align=left] [/align]
[align=left]public class Node {[/align]
[align=left] /**[/align]
[align=left] * @author 张钰[/align]
[align=left] */[/align]
[align=left] Object element;//数据元素[/align]
[align=left] Node next;[/align]
[align=left] Node(Node nextval){[/align]
[align=left] next=nextval;[/align]
[align=left] }[/align]
[align=left] Node(Object obj,Node nextval){[/align]
[align=left] element=obj;[/align]
[align=left] next=nextval;[/align]
[align=left] }[/align]
[align=left]public Object getElement() {[/align]
[align=left] return element;[/align]
[align=left]}[/align]
[align=left]public void setElement(Object obj) {[/align]
[align=left] element = obj;[/align]
[align=left]}[/align]
[align=left]public Node getNext() {[/align]
[align=left] return next;[/align]
[align=left]}[/align]
[align=left]public void setNext(Node nextval) {[/align]
[align=left] next = nextval;[/align]
[align=left]}[/align]
[align=left]public String toString(){[/align]
[align=left] return element.toString();[/align]
[align=left]}[/align]
[align=left] ,节点类的构造就是为了实现链表的操作,链表最常见的是单链表,单链表就是其每个节点都只有一个指向直接后继节点的指针,其中包括带头节点的和不带头节点的,根据单链表的结构我们可以设计如下的类LinList.java(注意和java中的LinkList不一样,LinkList是个线性结构容器,提供线性表、堆栈、队列等操作):[/align]
[align=left]/**[/align]
[align=left] * @author 张钰[/align]
[align=left] *[/align]
[align=left] */[/align]
[align=left]public class LinList implements List {[/align]
[align=left] [/align]
[align=left] Node head;//头指针[/align]
[align=left] Node current;//当前节点位置[/align]
[align=left] int size;//数据元素个数[/align]
[align=left] LinList(){[/align]
[align=left] head=current=new Node(null);[/align]
[align=left] size=0;[/align]
[align=left] }[/align]
[align=left] public void index(int i) throws Exception{ //定位元素[/align]
[align=left] if(i<-1||i>size-1){[/align]
[align=left] throw new Exception("参数错误");[/align]
[align=left] }[/align]
[align=left] if(i==-1) return;[/align]
[align=left] current=head.next;[/align]
[align=left] int j=0;[/align]
[align=left] while((current!=null)&&j<i){[/align]
[align=left] current=current.next;[/align]
[align=left] j++;[/align]
[align=left] }[/align]
[align=left] }[/align]
[align=left] public void insert(int i, Object obj) throws Exception {[/align]
[align=left] // 插入[/align]
[align=left] if(i<0||i>size){[/align]
[align=left] throw new Exception("参数错误");[/align]
[align=left] }[/align]
[align=left] index(i-1);[/align]
[align=left] current.setNext(new Node(obj,current.next));[/align]
[align=left] size++;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] [/align]
[align=left] public Object delete(int i) throws Exception {[/align]
[align=left] // 删除[/align]
[align=left] if (size==0){[/align]
[align=left] throw new Exception("链表已空无元素可删除!");[/align]
[align=left] }[/align]
[align=left] if(i<0||i>size-1){[/align]
[align=left] throw new Exception("参数错误");[/align]
[align=left] }[/align]
[align=left] index(i-1);[/align]
[align=left] Object obj=current.next.getElement();[/align]
[align=left] current.setNext(current.next.next);[/align]
[align=left] size--;[/align]
[align=left] return obj;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] [/align]
[align=left] public Object getData(int i) throws Exception {[/align]
[align=left] // 获取元素[/align]
[align=left] if(i<-1||i>size-1){[/align]
[align=left] throw new Exception("参数错误");[/align]
[align=left] }[/align]
[align=left] index(i);[/align]
[align=left] return current.getElement();[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] [/align]
[align=left] public int size() {[/align]
[align=left] // 获取元素个数[/align]
[align=left] return size;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left] /* (非 Javadoc)[/align]
[align=left] * @see List#isEmpty()[/align]
[align=left] */[/align]
[align=left] public boolean isEmpty() {[/align]
[align=left] // 判断是否为空[/align]
[align=left] return size==0;[/align]
[align=left] }[/align]
[align=left] [/align]
[align=left]}[/align]
[align=left],设计说明:[/align]
[align=left](1)构造函数完成三件事:创建头节点,使head和current均表示所创建的头节点,置s ize为0;[/align]
[align=left](2)定位成员函数index(int i)的实现,其设计方式是:用一个循环过程从头开始计数寻找第i个节点;[/align]
[align=left]顺序表和单链表的比较:顺序表和单链表的逻辑功能完全一样,但是两者的应用背景以及不同情况下的使用效率略有不同,顺序表的主要优点就是支持随机读取,以及内存空间利用效率高,顺序表的主要特点就是需要给出数组的最大数据元素个数,而这通常很难准确做到,另外,顺序表的插入和删除操作时需要移动较多的数据元素,单链表的缺点就是每个节点中都有个指针,所以其空间利用率略低于顺序表,单链表不支持随机读取。[/align]
[align=left]单链表另一种常见的形势就是循环单链表,其结构特点就是链表中最后一个节点的指针不再是结束标记,而是指向整个链表的第一个节点,从而使单链表形成一个环,,就是在构造函数中增加head.next=head,在定位函数index(i)中,把循环结束条件current!=null换成current!=head,这样最后一个节点就循环到第一个了!链表最常见的一个应用就是循环双链表,java中的LinkedList就是通过循环双链表来实现的,其长度可以随着数据元素的增减很容易的变化,LinkedList提供了线性表、堆栈、队列、双端队列等数据结构所要求的全部成员函数,例如addFirst()和removeFirst()就是支持堆栈所要求的成员函数,这里就不过多讲解了,回到循环双链表,双向链表中每个节点包括三个域:element、next、prior,其中element是数据元素,next是指向后继节点的对象应用,prior是指向前驱节点的对象应用,[/align]
[align=left] [/align]
[align=left]prior[/align]
[align=left]element[/align]
[align=left]next[/align]
[align=left]
[/align]
[align=left]设p为第i个节点,则p.next为第i+1个节点,p.next.prior==p,这就是双向链表的方式,结合前面的内容,双向链表类的设计留给大家,有兴趣的同学可以和我一起讨论![/align]
[align=left]最后还有仿真链表,链式储存结构中,实现元素之间的关系靠的是指针,但是也可以用数组来构造仿真链表,方法是在数祖中增加一个(或两个)int类型的变量域,这些变量用来表示后一个或前一个元素在数组中的下标,这就是仿真链表,其应用不是很多,这里就不多介绍,有兴趣的同学可以研究,下一讲:堆栈和队列![/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: