循环单链表--JAVA

来源:互联网 发布:东西海岸说唱对抗 知乎 编辑:程序博客网 时间:2024/06/05 12:41

前两章写了单链表的操作,在这里,写了一个循环单链表。为了更好地实现各操作,在此引入头结点,这里的头结点与前两章定义的头结点不同,前两章的头结点即首节点,而这里的头结点并不是首节点。这样说可能有些糊涂。那就再详细地解释一下头结点和首节点的区别,头结点是物理上的第一个节点,但是它存放的不是我们所需要的数据,而是链表的一些信息,如链表的长度等,也可以是null,当链表为空时,头结点为空,但是它存在,它的next指向自身,假设头结点声明为head,那么链表为空时的条件为head.next=head;若链表不为空,则head.next指向逻辑上的第一个节点,这个逻辑上的第一个节点就是首节点,首节点是什么呢?比如我们现在链表中存放的是教师职工的信息,第一个老师的编号是001,那么第一个节点中存放的就是编号为001的教工信息。这个存放001教工信息的节点就是首节点。首节点是逻辑上的第一个节点,是物理上的第二个节点。如果还是不明白,参照下图再看一遍:

              

在上图中,first存放的是教工001的信息,second存放的是教工002的信息。在head中,存放的是链表的信息,不存放教工信息。若该链表为空,则为下图所示,head的next指针指向自身。


下面是循环单链表的具体操作实现代码:

       

package ListLink;/* * 循环单链表的简单操作 */public class CircleLinkList {/* * first为头结点,不存放内容,若后面无内容,指向自身,若后面有内容,则指向首节点 * 这里的头结点与前面两章的头结点不一样,之前的头结点即为首节点,这里头结点是物理上的第一个节点, * 指向首节点,头结点中内容可以为空,也可以存储链表长度等数据 * 首节点指的是逻辑上存放数据的第一个节点 * 请注意区分 * 至于为什么在首节点之前使用头结点,我们不使用头结点的时候,执行插入、删除操作的时候, * 往往要考虑我们插入/删除的位置是不是位于首节点位置,以及原链表是否为空的问题 * 引入头结点,则不需要考虑这些问题 *  */public Node first=null;   int len=1;   //链表节点数int tmp=0;   //当前节点位置public CircleLinkList(){first=new Node(null);first.next=first;}//在尾部插入数据public void addNodeEnd(Teacher teacher){Node node=new Node(teacher);Node temp=first;while(temp.next!=first)temp=temp.next;temp.next=node;node.next=first;len++;}//在头部插入数据public void addNodeFirst(Teacher teacher){Node node=new Node(teacher);node.next=first.next;    first.next=node;    len++;}/* * 根据用户需求将数据插入链表中 * 此处的index最好不要传值为0,若传值为0,则将头结点覆盖,此时只有一个节点,即头结点, * 若传值为0 后继续添加节点,则继续添加,在此步骤之前链表中的节点数据则不存在了 */public void addNode(int index,Teacher teacher){Node node=new Node(teacher);Node previous=first;Node current=first;while(tmp!=index){previous=current;current=current.next;tmp++;}node.next=current;previous.next=node;len++;tmp=0;}//在尾部删除数据public void deleteNodeEnd(){Node previous=first;Node current=first;while(current.next!=first){previous=current;current=current.next;}previous.next=first;len--;}//删除头部数据public void deleteNodeFirst(){Node node=first.next;first.next=node.next;len--;}/* * 删除任意位置的数据 * 此处若写删除0节点的数据是无用的 * 另外,若此处实现的是删除0节点,该链表长度不变 * 尽量不要删除0节点 *  */public void deleteNode(int index){int temp=index%len;Node previous=first;Node current=first;while(tmp!=temp){previous=current;current=current.next;tmp++;}previous.next=current.next;len--;tmp=0;}//查询某位置的节点信息并打印出来public void getNodeIndex(int index){Node node=first;while(tmp!=index){    node=node.next;    tmp++;}tmp=0;System.out.println("查询的教工信息是:");        node.display();System.out.println("查询结束");        }//查询满足某条件的信息并打印出来public void getNodeData(Teacher teacher){int temp=0;Node node=first;for(int i=0;i<len-1;i++){node=node.next;if(node.teacher.getSno()==teacher.getSno()){System.out.println("查询的教工信息是:");        node.display();        temp++;        System.out.println("查询结束1");  }}if(temp==0){System.out.println("未查询到教工信息");        System.out.println("查询结束"); }}//将所有的数据打印出来public void PrintAll(){Node node=first.next;while(node!=first){node.display();node=node.next;}}public static void main(String[] args){CircleLinkList cll=new CircleLinkList();//cll.PrintAll();Teacher teacher=new Teacher("001","小明","男",22,"1222","wewew");cll.addNodeEnd(teacher);Teacher teacher1=new Teacher("001","小明","男",23,"1222","wewew");cll.addNodeEnd(teacher1);Teacher teacher2=new Teacher("002","小明","男",22,"1222","wewew");cll.addNodeEnd(teacher2);Teacher teacher3=new Teacher("003","小明","男",22,"1222","wewew");cll.addNodeFirst(teacher3);Teacher teacher4=new Teacher("004","小明","男",22,"1222","wewew");cll.addNode(2,teacher4); //cll.deleteNodeEnd();//cll.deleteNodeFirst();cll.deleteNode(6);//cll.getNodeIndex(2);        cll.PrintAll();//        Teacher teacher5=new Teacher("001","小红","男",22,"1222","wewew");//cll.getNodeData(teacher5);}}
使用的Node和Teacher类与上一篇的Teacher和Node类一样。