• 双向链表——Java实现


    双向链表

    链表是是一种重要的数据结构,有单链表和双向链表之分;本文我将重点阐述不带头结点的双向链表:

    不带头结点的带链表

    我将对双链表的增加和删除元素操作进行如下解析

    1.增加元素(采用尾插法)

    (1)链表为空

         新建结点,将头结点first和尾节点last都指向新建结点,尾节点的next指向空。

     

    空链表增加元素

    (2)链表非空

         先定义一个临时的结点temp保存当前的尾节点,将尾节点last指向新建结点,并将last的prev指向temp,temp的next指向last.

    非空链表增加元素

     

    2.删除指定下标的元素

    我将分以下三种情况进行讨论

    (1)要删除元素为头结点

     用node保存当前头结点first,并将头结点first指向first.next且将现在的first.prev置为空,将node.的next、data分别置为空。

     

     删除头结点

    (2)要删除元素为尾节点

          用节点node保存当前的尾节点,将last指向当前尾节点的前一个节点last.prev,并将现last.next置为空,将以前的last即node节点的prev和data置空。

      

    删除尾结点

    (3)要删除元素为中间节点

          用节点node保存要删除的节点,并将要删除节点的前一个节点的next指向要删除节点的下一个节点;要删除节点的下一个节点的prev指向要删除节点的还是那个一个节点;即node.prev. next = node.next;node.next.prev = node.prev。并将要删除节点的prev、next及data置为null.

    删除中间结点

     

      1 package Struct;
      2  
      3 interface Link{
      4     void add(Object obj);
      5     boolean remove(int index);
      6     boolean contain(Object obj);
      7     int indexOf(Object obj);
      8     boolean set(int index,Object obj);
      9     Object get(int index);
     10     int length();
     11     void clear();
     12     Object[] toArray();
     13     void printArray(Object[] obj);
     14     void printLink();
     15 }
     16 class Factory{
     17     private Factory(){}
     18     public static Link getLinkInstance(){
     19         return new LinkImpl();
     20     }
     21 }
     22 class LinkImpl implements Link{
     23     private Node first;
     24     private Node last;
     25     private int size;
     26     private class Node{
     27         private Node prev;
     28         private Node next;
     29         private Object data;
     30         public Node(Object data){
     31             this.data = data;
     32         }
     33     }
     34     public void add(Object obj) {
     35         //要插入元素为空
     36         if(obj == null){
     37             return;
     38         }
     39         Node node = new Node(obj);
     40         //空链表
     41         if(first == null){
     42             first = last = node;
     43             first.next = null;
     44             size++;
     45         }else{
     46         //非空链表(尾插)
     47             Node temp = this.last;
     48             temp.next = node;
     49             last = node;
     50             last.prev = temp;
     51             size++;
     52         }
     53     }
     54     //删除
     55     public boolean remove(int index) {
     56         //指定下标不合法
     57         if(index >= size){
     58             return false;
     59         }
     60         Node node = first;
     61         //要删除的节点为头结点
     62         if(index == 0){
     63             first = node.next;
     64             first.prev = null;
     65             node.prev = node.next = null;
     66             node.data = null;
     67             size--;
     68             return true;
     69         }
     70         //要删除节点为尾节点
     71         if(index == size-1){
     72             Node node1 = last;
     73             last = node1.prev;
     74             last.next = null;
     75             node1.prev = node1.next = null;
     76             node1.data = null;
     77             size--;
     78             return true;
     79         } 
     80         //要删除节点为中间节点
     81             Node node3 = get(index);
     82             node3.prev.next = node3.next;
     83             node3.next.prev = node3.prev;
     84             node3.prev = node3.next = null;
     85             node3.data = null;
     86             size--;
     87             return true;
     88     }
     89     //查看元素是否包含在链表中
     90     public boolean contain(Object obj) {
     91         //空链表
     92         if(first == null&&first.next==null){
     93             return false;
     94         }
     95         for(Node node = first;node!=null;node=node.next){
     96             if(node.data==obj){
     97                 return true;
     98             }
     99         }
    100         return false;
    101     }
    102     //求取元素obj的下标
    103     public int indexOf(Object obj) {
    104         Node node  = first;
    105         int signal = 0;
    106         //空链表
    107         if(first== null&& first.next == null){
    108             return -1;
    109         }else{
    110             for(node = first;node!=null;node=node.next){
    111                 if(node.data == obj){
    112                     return signal;
    113                 }
    114                 signal++;
    115             }
    116         }
    117         return signal;
    118     }
    119     //修改index处的值为obj
    120     public boolean set(int index, Object obj) {
    121         //指定位置不存在
    122         if(index<0||index >= size){
    123             return false;
    124         }
    125         //指定下标超过链表长度
    126         if(index >= size){
    127             return false;
    128         }
    129         Node node = first;
    130         //若链表头结点是要修改的元素
    131         if(node == get(index)){
    132             node.data = obj;
    133         }
    134         Object getObject = get(index);
    135         for(node = first;node !=null;node=node.next){
    136             if( getObject == node){
    137                 node.data = obj;
    138             }
    139         }
    140         return true;
    141     }
    142     //取得index处的元素
    143     public Node get(int index) {
    144         if(first==null&&first.next==null){
    145             return null;
    146         }
    147         //要查找下标不在范围内
    148         if(index >= size){
    149             return null;
    150         }
    151         Node node = first;
    152         //要查找元素在中间元素的左侧
    153         if(index >=0 && index <= (index<<1)){
    154             for(int i = 0;i <= index - 1;i++){
    155                 if(i == index){
    156                     return node;
    157                 }
    158                 node =node.next;
    159             }
    160         }
    161         else if(index > (index<<1)){
    162         //要查找元素在中间元素的右侧
    163             for(int i = index; i < size-1;i++){
    164                 if(i == index){
    165                     return node;
    166                 }
    167                 node = node.next;
    168             }
    169         }
    170             return node;
    171     }
    172     //求链表长度
    173     public int length() {
    174         //空链表
    175         if(first == null){
    176             return 0;
    177         }
    178         return this.size;
    179     }
    180     //清空链表
    181     public void clear() {
    182  
    183         Node node = first;
    184         if(first == null && first.next == null){
    185             return;
    186         }
    187         for(node = first.next;node!=null;){
    188             Node temp = node;
    189             node.prev = node.next = null;
    190             node.data = null;
    191             node = node.next;
    192             size--;
    193         }
    194         first.next = null;
    195         first.data = null;
    196         size--;
    197     }
    198     //将链表转换成Object数组
    199     public Object[] toArray() {
    200         //空链表
    201         if(first == null && first.next == null){
    202             return null;
    203         }else{
    204             Object[] linkObject = new Object[this.size];//向上转型
    205             Node node = first;
    206             for(int i = 0;i<size;i++){    
    207                 linkObject[i] = node.data;
    208                 node = node.next;
    209                 }
    210             return linkObject;
    211         }
    212     }
    213     //打印Object数组
    214     public void printArray(Object[] obj){
    215         for(int i = 0;i < obj.length;i++){
    216             System.out.print(obj[i]+" <-> ");
    217         }
    218     }
    219     //打印链表
    220     public void printLink() {
    221         Node node = first;
    222         for(node = first;node!=null;node=node.next){
    223             System.out.print(node.data+" <——> ");
    224         }
    225         System.out.println();
    226     }
    227     
    228 }
    229 public class DoubleLinkList {
    230     public static void main(String[] args) {
    231         Link link = Factory.getLinkInstance();
    232         System.out.println("\n"+"=================以下为add测试函数===================");
    233         link.add("我是开始位置");
    234         link.add("第一名");
    235         link.add("第二名");
    236         link.add("第三名");
    237         link.add("我是结束位置");
    238         System.out.println("\n"+"===============以下为printLink测试函数===============");
    239         link.printLink();
    240         System.out.println("\n"+"===============以下为indexOf测试函数================");
    241         System.out.println(link.indexOf("第二名"));
    242         System.out.println(link.indexOf("我是结束位置"));
    243         System.out.println("\n"+"===============以下为contain测试函数================");
    244         System.out.println(link.contain("我是结束位置"));
    245         System.out.println(link.contain("hahh"));
    246         System.out.println("\n"+"===============以下为get测试函数================");
    247         System.out.println(link.get(0));
    248         System.out.println(link.get(4));
    249         System.out.println(link.get(2));
    250         System.out.println(link.get(8));
    251         System.out.println("\n"+"===============以下为length测试函数================");
    252         System.out.println(link.length());
    253         System.out.println("\n"+"===============以下为set测试函数===================");
    254         System.out.println(link.set(0, "我是特等奖"));
    255         link.printLink();
    256         System.out.println("\n"+"===============以下为toArray测试函数===================");
    257         Object[] linkObj = link.toArray();
    258         System.out.println("\n"+"===============以下为printArray测试函数===================");
    259         link.printArray(linkObj);
    260         System.out.println("\n"+"===============以下为remove测试函数===================");
    261         //删除尾节点
    262         System.out.println(link.remove(4));
    263         link.printLink();
    264         //删除头结点
    265         System.out.println(link.remove(0));
    266         link.printLink();
    267         //删除中间节点
    268         System.out.println(link.remove(1));
    269         link.printLink();
    270         System.out.println(link.length());
    271         System.out.println("\n"+"===============以下为clear测试函数===================");
    272         link.clear();
    273         System.out.println(link.length());
    274     }
    275 }
    View Code

    测试结果:

  • 相关阅读:
    博客阅读计数优化
    博客阅读简单计数
    博客后台富文本编辑
    博客分类统计
    Django关联关系查询
    上下篇博客,按月归档
    浅谈闭包以及常见面试题
    浅谈前端缓存(转至大佬)
    post请求头的常见类型
    浅谈RegExp 对象的方法
  • 原文地址:https://www.cnblogs.com/edda/p/12595211.html
Copyright © 2020-2023  润新知