数据结构之链表

数组的两大缺点:

1。若改变数组的大小就要创建一个新的数组,并需要从原数组复制所有的数据到新的数组

2。数组元素在内存中依次顺序存储,这意味着向数组插入一项要移动数组中的其他元素

因此,我们使用链式结构,链式结构是存储数据的结点以及指向其他节点的指针的集合。如此一来,节点可以位于内存的任意位置,而且从一个节点到另一个节点的传递可以通过在结构中存储节点间引用来实现。

一。单向链表

1。链表:

如果一个节点包含指向另一个节点的数据值,那么多个节点可以连接成一串,只通过一个变量访问整个节点序列,这样的节点序列称为链表(linked list)

2。单向链表:

如果每个节点仅包含其指向后继节点的引用,这样的链表称为单向链表。

一个整型单向链表的实现:

 

None.gif package  com.sohu.blog.denns_zane.list;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
/** */ /**
InBlock.gif * 
@author  dennis
InBlock.gif * @Description 整型单向链表节点
ExpandedBlockEnd.gif 
*/

ExpandedBlockStart.gifContractedBlock.gif
public   class  IntSLLNode  dot.gif {
InBlock.gif    
public   int  info;  //  用户信息
InBlock.gif

InBlock.gif    
public  IntSLLNode next;  //  下一个节点,自引用
InBlock.gif

ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** */ /**
InBlock.gif     * 
@param  info
InBlock.gif     * 
@param  next
ExpandedSubBlockEnd.gif     
*/

ExpandedSubBlockStart.gifContractedSubBlock.gif    
public  IntSLLNode( int  info, IntSLLNode next)  dot.gif {
InBlock.gif        
this .info  =  info;
InBlock.gif        
this .next  =  next;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** */ /**
InBlock.gif     * 
@param  info
ExpandedSubBlockEnd.gif     
*/

ExpandedSubBlockStart.gifContractedSubBlock.gif    
public  IntSLLNode( int  info)  dot.gif {
InBlock.gif        
this (info,  null );
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
/** */ /**
InBlock.gif * 
ExpandedBlockEnd.gif 
*/

None.gif
package  com.sohu.blog.denns_zane.list;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
/** */ /**
InBlock.gif * 
@author  dennis
InBlock.gif * desc: 整型单向链表
ExpandedBlockEnd.gif 
*/

ExpandedBlockStart.gifContractedBlock.gif
public   class  IntSLList  dot.gif {
InBlock.gif    
protected  IntSLLNode head, tail;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public  IntSLList()  dot.gif {
InBlock.gif        head 
=  tail  =   null ;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public   boolean  isEmpty()  dot.gif {
InBlock.gif        
return  head  ==   null ;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** */ /**
InBlock.gif     * @description 增加新节点,并设置它的next为原head
InBlock.gif     * 
@param  el
ExpandedSubBlockEnd.gif     
*/

ExpandedSubBlockStart.gifContractedSubBlock.gif    
public   void  addToHead( int  el)  dot.gif {
InBlock.gif        head 
=   new  IntSLLNode(el, head);
InBlock.gif        
if  (tail  ==   null )
InBlock.gif            tail 
=  head;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** */ /**
InBlock.gif     * @description 增加新节点,并设置原tail的next为新节点
InBlock.gif     * 
@param  el
ExpandedSubBlockEnd.gif     
*/

ExpandedSubBlockStart.gifContractedSubBlock.gif    
public   void  addToTail( int  el)  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if  ( ! isEmpty())  dot.gif {
InBlock.gif            tail.next 
=   new  IntSLLNode(el);
InBlock.gif            tail 
=  tail.next;
ExpandedSubBlockStart.gifContractedSubBlock.gif        }
  else   dot.gif {
InBlock.gif            head 
=  tail  =   new  IntSLLNode(el);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public   int  deleteFromHead()  dot.gif {
InBlock.gif        
if  (head  ==   null )
InBlock.gif            
throw   new  NullPointerException();
InBlock.gif        
int  el  =  head.info;
InBlock.gif        
if  (head  ==  tail)
InBlock.gif            head 
=  tail  =   null ;
InBlock.gif        
else
InBlock.gif            head 
=  head.next;
InBlock.gif        
return  el;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public   int  deleteFromTail()  dot.gif {
InBlock.gif        
if  (head  ==   null )
InBlock.gif            
throw   new  NullPointerException();
InBlock.gif        
int  el  =  tail.info;
InBlock.gif        
if  (head  ==  tail)
InBlock.gif            head 
=  tail  =   null ;
ExpandedSubBlockStart.gifContractedSubBlock.gif        
else   dot.gif {
InBlock.gif            IntSLLNode temp;
InBlock.gif            
for  (temp  =  head; temp.next  !=   null   &&  temp.next  !=  tail; temp  =  temp.next)
InBlock.gif                tail 
=  temp;
InBlock.gif            System.out.println(tail.info);
InBlock.gif            tail.next 
=   null ;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
return  el;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public   void  printAll()  dot.gif {
InBlock.gif        
for  (IntSLLNode temp  =  head; temp  !=   null ; temp  =  temp.next)
InBlock.gif            System.out.print(temp.info 
+   "   " );
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public   boolean  isInList( int  el)  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif        
for  (IntSLLNode temp  =  head; temp  !=   null ; temp  =  temp.next)  dot.gif {
InBlock.gif            
if  (temp.info  ==  el)
InBlock.gif                
return   true ;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
return   false ;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/** */ /**
InBlock.gif     * 
@param  el
ExpandedSubBlockEnd.gif     
*/

ExpandedSubBlockStart.gifContractedSubBlock.gif    
public   void  delete( int  el)  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if  ( ! isEmpty())  dot.gif {
InBlock.gif            
if  (head  ==  tail  &&  head.info  ==  el)
InBlock.gif                head 
=  tail  =   null ;
InBlock.gif            
else   if  (head.info  ==  el)
InBlock.gif                head 
=  head.next;
ExpandedSubBlockStart.gifContractedSubBlock.gif            
else   dot.gif {
InBlock.gif                IntSLLNode pred, temp;
//  pred为找的节点的前一节点,temp即为找到的节点
ExpandedSubBlockStart.gifContractedSubBlock.gif
                 for  (pred  =  head, temp  =  head.next; temp  !=   null ; pred  =  pred.next, temp  =  temp.next)  dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
if  (temp.info  ==  el)  dot.gif {
InBlock.gif                        pred.next 
=  temp.next;  //  前一节点的next设置为当前节点的next
InBlock.gif
                         if  (temp  ==  tail)
InBlock.gif                            tail 
=  pred;
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif

二。双向链表

单向链表的deleteFromTail()方法指出了单向链表的固有问题,这种链表的节点仅仅包含指向后继节点的引用,所以无法立即访问它的前驱节点,不得不扫描整个链表来查找此前驱节点。因此,我们重新定义链表节点,包含两个引用,一个指向前驱节点,一个指向后驱节点,也就是——双向链表。
一个整型双向链表的实现:
ExpandedBlockStart.gif ContractedBlock.gif /** */ /**
InBlock.gif * 
ExpandedBlockEnd.gif 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值