基于java的数据结构学习手记9--双向链表

     今天要实现的是双向链表,其优点在什么地方呢?传统链表的一个问题是沿着链表的反向遍历是和困难的。双向链表具备这个能力,允许向前和向后遍历,其秘密在于每个链结点有两个指向其他链接点的引用,而不是一个。

      它的缺点是每次插入删除一个链结点的时候,要处理四个链结点的引用,而不是两个。两个连接前一个结点,2个连接后一结点。而且占用空间也大了一些。

     具体的删除,插入过程就是对4个链接点引用的处理过程,内容有些繁琐,结合图像并且自己在纸上手画一下处理的过程会更好理解。下面显示的是加上注释的代码。对各个重要类变量函数都有说明。

      链节点 Link:

Code:
  1. package DoublyLinklist;  
  2.   
  3. public class Link {  
  4.           public int iData;  
  5.           public Link previous;  
  6.           public Link next;  
  7. //......................................................            
  8.           public Link(int d)  
  9.           {  
  10.               iData=d;  
  11.           }  
  12. //......................................................   
  13.           public void displayLink()  
  14.           {  
  15.               System.out.print(iData+" ");      
  16.           }  
  17. //......................................................             
  18. }  

双向链表类DoublyLinkedList

Code:
  1. package DoublyLinklist;  
  2.   
  3. public class DoublyLinkedList   
  4. {  
  5.     private Link first;  
  6.     private Link last;  
  7. //......................................................   
  8.    public DoublyLinkedList()//constructor  
  9.    {  
  10.        first=null;  
  11.        last=null;  
  12.    }  
  13. //......................................................   
  14.    public boolean isEmpty()//true is list is empty  
  15.    {return first==null;}  
  16. //......................................................      
  17.    public void insertFirst(int d)  
  18.    {  
  19.        Link newLink=new Link(d);//产生一个Link对象  
  20.        if(isEmpty())last=newLink;//如果链表空,newlink也为last节点  
  21.        else  
  22.            first.previous=newLink;//非空,把newlink<--old first(这个是指向)  
  23.        newLink.next=first;      //newlink-->old first(这个是指向)  
  24.        first=newLink;//first==>newlink(这个是等同)  
  25.    }  
  26. //......................................................      
  27.    public void insertLast(int d)//在链表尾插入  
  28.    {  
  29.        Link newLink=new Link(d);  
  30.        if(isEmpty())first=newLink;//考虑空的情况  
  31.        else  
  32.        {  
  33.            last.next=newLink;   //last-->newlink  
  34.            newLink.previous=last;//last<--newlink  
  35.        }  
  36.        last=newLink;//last<==newlink  
  37.    }  
  38.  //......................................................   
  39.    public Link deleteFirst()//删除首节点  
  40.    {  
  41.        Link temp=first;  
  42.        if(first.next==null)last=null;//考虑链表只有一个节点情况  
  43.        else  
  44.            first.next.previous=null;//非空则断绝old first与删除后链表的联系  
  45.        first=first.next;//首节点后移  
  46.        return temp;//返回删除节点  
  47.          
  48.    }  
  49. //......................................................    
  50.     public Link deleteLast()// 删除末节点  
  51.     {  
  52.          Link temp=last;  
  53.        if(first.next==null)first=null;//考虑链表只有一个节点情况  
  54.        else  
  55.            last.previous.next=null;//非空则断绝old last与删除后链表的联系  
  56.        last=last.previous;//末节点前移  
  57.        return temp;//返回删除节点  
  58.           
  59.     }  
  60. //......................................................    
  61.     public boolean insertAfter(int key,int d)  //查找链表中的值等于key的节点,在其后面插入数据d  
  62.     {  
  63.         Link current=first;//current"指针"指向first  
  64.         while(current.iData!=key)//匹配循环条件  
  65.         {  
  66.             current=current.next;  
  67.             if(current==null)return false;//扫描完整个链表无匹配返回false  
  68.         }  
  69.         Link newLink=new Link(d);//新的节点对象  
  70.           
  71.         if(current==last)//如果链表最后一个节点匹配key  
  72.         {  
  73.             newLink.next=null;//解决newlink的向后的指向  
  74.             last=newLink;  //  
  75.         }  
  76.         else  
  77.         {  
  78.             newLink.next=current.next;//  
  79.             current.next.previous=newLink;//一般情况下的newlink跟后一个节点之间的依赖关系  
  80.         }  
  81.         current.next=newLink;//newlink和前一个节点的依赖关系建立  
  82.         newLink.previous=current;//  
  83.         return true;  
  84.           
  85.     }  
  86. //......................................................    
  87. public Link deleteKey(int d)  
  88. {  
  89.    Link current=first;  
  90.    while(current.iData!=d)  
  91.    {  
  92.        current=current.next;  
  93.        if(current==null)return null;  
  94.    }  
  95.    if(current==first)  
  96.        first.next.previous=null;//考虑删除节点后向前依赖关系问题,首节点是特例  
  97.    else                         //  
  98.        current.next.previous=current.previous;  
  99.    if(current==last)  
  100.        last.previous.next=null;//考虑删除节点后向后依赖关系问题,末节点为特例  
  101.    else                        //  
  102.        current.previous.next=current.next;  
  103.    return current;  
  104.          
  105.      
  106.   
  107.   
  108. }  
  109. //......................................................    
  110. public void displayForward()  
  111. {  
  112. System.out.print("List(first-->last):");  
  113. Link current=first;  
  114. while(current!=null)  
  115. {  
  116.     current.displayLink();  
  117.     current=current.next;  
  118. }  
  119. System.out.println("");  
  120.   
  121. }  
  122. //......................................................   
  123. public void displayBackward()  
  124. {  
  125. System.out.print("List(last-->first):");  
  126. Link current=last;  
  127. while(current!=null)  
  128. {  
  129.     current.displayLink();  
  130.     current=current.previous;  
  131. }  
  132. System.out.println("");  
  133.   
  134. }  
  135. }  

应用类

Code:
  1. package DoublyLinklist;  
  2.   
  3. public class DoublyLinkedApp {  
  4.   
  5.     /** 
  6.      * @param args 
  7.      */  
  8.     public static void main(String[] args) {  
  9.         // TODO Auto-generated method stub  
  10.         DoublyLinkedList theList=new DoublyLinkedList();  
  11.           
  12.         theList.insertFirst(22);  
  13.         theList.insertFirst(44);  
  14.         theList.insertFirst(66);  
  15.           
  16.         theList.insertLast(11);  
  17.         theList.insertLast(33);  
  18.         theList.insertLast(55);  
  19.           
  20.         theList.displayForward();  
  21.         theList.displayBackward();  
  22.   
  23.         theList.deleteFirst();  
  24.         theList.deleteLast();  
  25.         theList.deleteKey(11);  
  26.           
  27.         theList.displayForward();  
  28.           
  29.         theList.insertAfter(2277);  
  30.         theList.insertAfter(3388);  
  31.           
  32.         theList.displayForward();  
  33.     }  
  34.   
  35. }  

结果显示:

Code:
  1. List(first-->last):66 44 22 11 33 55   
  2. List(last-->first):55 33 11 22 44 66   
  3. List(first-->last):44 22 33   
  4. List(first-->last):44 22 77 33 88   

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值