zoukankan      html  css  js  c++  java
  • 链表的理解

     

    一、链表的基本结构

          链表程序的本质在于节点的相互引用,缺点就是数据的保存顺序就是你的添加顺序

          public class Link{
               private class  Node{
               private Object data;
               private Node next;//下一个节点;用作自身关联
               public Node(Object data){
                   this.data=data;//创建节点的时候封装数据,由于节点有序,封装的数据也就有序了
               }
            }
           
            /*----------------以下是Link的操作-------------------*/
            private Node root;
            public void add(Object data){
             ...
            }
             ...
             
         }
    
       二、链表和动态数组关系:
          1.数组的长度等于链表的长度,链表如果添加了数据,长度就发生了变化,
             间接地数组的长度也就发生了变化,即可以实现动态数组(长度可变)
           private Object[] rdata; 
           public Object[] toArray(){//将链表转化为对象数组
            //判断链表是否为空
            if(count==0 || this.root==null){
                return null;
            }
            //count:链表的长度
            this.rdata=new Object[count];
            foot=0;//foot清零,
            //用this.root去获取数据(Node类来获取数据)
            this.root.toArrayNode();
            return rdata;
    
            //在Node类中取数据
            public void toArrayNode(){
                Link_get.this.rdata[Link_get.this.foot++]=this.data;
                if(this.next!=null){
                    this.next.toArrayNode();
                }
            }
        }
     
          2.链表添加一个数据(实际是将数据封装在Node中)
            然后将封装了数据的节点添加到链表中,
            数组对应保存一个数据(采用索引foot++实现),链表         
             输出可以通过遍历数组获取数据
            private Node root;
            public void add(Object data){
                if(data==null) return ;
                Node newNode =new Node(data);//封装数据到节点中
                if(this.root==null){
                    this.root=newNode;//将一个节点赋值给根节点
                }else{
                    this.root.addNode(newNode);//交给Node类自己去完成节点的排序任务
                }
            }
          
            //第一次调用:this代表的是Link.root(根节点)
            public void addNode(Node newNode){
             if(this.next==null){
                  this.next=newNode;
              }else{
                  if(this.next!=null){
                      this.next.addNode(newNode);
                   }
              }   
           }
     
           
          3.链表删除数据
             public void delete(Object data){
                 if(this.contains(data)){//链表存在要删除的数据
                     if(this.root.data.equals(data)){//要删除的数据在根节点中
                          this.root=this.root.next;//删除根节点
                     }else{//要删除的数据不在根节点中
                          //删除其它节点的条件是:要被删除的节点的上一个节点.next=要被删除的节点.next
                          //所以传入的参数应该有:调用方法的节点的上一个节点和要被删除的数据
                          this.root.next.deleteNode(this.root,data);//this.root就是调用deleteNode方法的节点this.root.next的上一个节点
                      } 
                     //注意:删除数据之后,链表的长度会发生改变
                      count--;
                 }
             }
           
               //在Node类中
               public void deleteNode(Node previous,Object data){
                  if(this.next.data.equals(data)){
                       previous.next=this.next;
                   }else{
                       if(this.next!=null){
                           this.next.deleteNode(this,data);
                       }
                   }
    
               }
    
     
    /*
     *自定义的一个较完整的链表类
     */
    package com.petshop;
    
    public class Link {
         private class Node{
             private Object data;
             private Node next;
             public Node(Object data){
                 this.data=data;
             }
             //添加节点
             public void addNode(Node newNode){
                 if(this.next==null){
                     this.next=newNode;
                 }else{
                     this.next.addNode(newNode);
                 }
             }
             public void toArrayNode(){
                 //将取出的数据放在rdata数组中
                 Link.this.rdata[Link.this.foot++]=this.data;//取出根节点的数据
                 if(this.next!=null){
                     this.next.toArrayNode();
                 }
             }
             //判断是否包含要查询的数据
             public boolean containsNode(Object data){
                 if(this.data.equals(data)){//根节点的数据满足查询条件
                     return true;
                 }else{
                     if(this.next!=null){
                        return this.next.containsNode(data);
                     }else{
                         return false;
                     }
                 }
             }
             //根据索引查找数据
             public Object getNode(int index){
                 if(Link.this.foot++ == index){
                     return this.data;
                 }else{
                     if(this.next!=null){
                           return this.next.getNode(index);
                     }else{
                         return null;
                     }     
                 }
             }
             //根据索引修改数据
             public void setNode(int index,Object data){
                 if(Link.this.foot++ == index){
                     this.data=data;
                 }else{
                     if(this.next!=null){
                         this.next.setNode(index, data);
                     }
                 }
             }
             /*
              * 第一次调用:this:Link.root.next; previous:Link.root
              * 第二次调用:this:Link.root.next.next; previous:Link.root.next
              */
             public void removeNode(Node previous,Object data){
                 if(this.data.equals(data)){
                     previous.next=this.next;
                 }else{
                     if(this.next!=null){
                         this.next.removeNode(this, data);//this是this.next的上一个节点
                     }
                 }
                 
             }
         }
        
    /*---------------以下是Link的操作----------------------------*/ 
         
         private Node root;
         private int count;
         private int foot;
         private Object[] rdata;//用于存储链表中的数据
         
         //删除数据
         public void remove(Object data){
             if(this.contains(data)){//确保链表中包含有要删除数据
                 if(this.root.data.equals(data)){//判断删除数据是否在根节点中
                     //删除根节点
                     this.root=this.root.next;
                 }else{ //要删除的数据不在根节点中
                     //删除其它节点:删除节点的上一个节点.next=删除节点.next;
                     //所以传入参数有:删除节点的上一个节点和要删除的数据
                     this.root.next.removeNode(this.root,data);
                 }
                 //注意链表长度的改变
                   count--;
             }
             
         }
         
         //根据索引修改数据
         public void set(int index,Object data){
             if(index>=count || data==null || this.root ==null){
                 return;
             }else{
                 //Link类做一些判断,最终实现细节的操作都是由Node类来完成
                 /*
                  *this.root.containsNode()
                  *this.root.toArrayNode()
                  *this.root.getNode()
                  *...
                  */
                 this.root.setNode(index,data);
             }
         }
         
         //根据索引获取数据
         public Object get(int index){
             if(index>=count || this.root==null){
                 //索引大于了链表的长度(数组的长度)
                 return null;
             }else{
                 //从根节点(foot=0)开始查询,直到数组的索引等于要查询的索引为止
                 foot=0;
                 return this.root.getNode(index);
             }
             
         }
         
         //判断链表是否存在有要被查询的数据
         public  boolean contains(Object data){
             if(data==null || this.root==null){
                 return false;
             }else{
                 //从根节点开始查询是否存在查询的数据
                 return this.root.containsNode(data);
             }
         }
         
         public Object[] toArray(){
             if(count==0 || this.root==null){
                 return null;
             }
             //忘记写了
             rdata=new Object[count];//动态定义数组长度
             foot=0;
             this.root.toArrayNode();//采用链表去获取数据
             return this.rdata;
         }
         //获取链表数据的个数
         public int size(){
             return count;
         }
             //判断链表是否为空
         public boolean isEmpty(){
             return count==0 && this.root==null;
         }
              //链表添加数据
         public void add(Object data){
             if(data==null) return ;
             Node newNode=new Node(data);
             if(this.root==null){
                 this.root=newNode;
             }else{
                 this.root.addNode(newNode);
             }
             //记录链表长度
             count++;
         }
    }
  • 相关阅读:
    (六)静态域,静态方法和静态代码块
    (五)final修饰符
    (四)函数的参数传递——值传递
    (三)java字符串
    第二章 shell的语法
    字符串操作
    PropertyGrid—属性类别排序
    PropertyGrid—为复杂属性提供下拉式编辑框和弹出式编辑框
    PropertyGrid--为复杂属性提供编辑功能
    PropertyGrid—添加EventTab
  • 原文地址:https://www.cnblogs.com/yuefeng123/p/7460709.html
Copyright © 2011-2022 走看看