zoukankan      html  css  js  c++  java
  • 实例讲解——单向链表(2)

    深入链表的操作

    将使用内部类,完成链表的操作!

    一,链表的改进

    之前已经实现了简单的单向链表,但是因为要用手工去处理各个节点的关系,这样肯定不行。

    所以此处最好将节点的操作进行封装。这样用户操作就很方便了。

    假设现在的节点操作有以下几种:增加数据,查找数据,删除数据。

    特别强调的是,如果要删除节点的话,直接修改上一个节点就可以。

    增加节点:就是在节点最后进行增加。

    查找节点:就是依次递归的方式查找。

    删除节点:就是改变引用传递地址。

    在程序开发中,必须考虑两种情况:

    1)第一次执行的时候,第一次执行的时候,其根节点不存在,则需要将第一个数据设置成为根节点。

    class Link{        // 链表的完成类
        class Node{    // 保存每一个节点,此处为了方便直接定义成内部类
            private String data ;    // 保存节点的内容
            private Node next ;        // 保存下一个节点
            public Node(String data){
                this.data = data ;        // 通过构造方法设置节点内容
            }
            public void add(Node newNode){        // 将节点加入到合适的位置
                if(this.next==null){            // 如果下一个节点为空,则把新节点设置在next的位置上
                    this.next = newNode ;
                }else{        // 如果不为空,则表示后面还有其他节点,这里不能添加,则需要向下继续找next为空的节点,自动完成在链表的最后添加。
                    this.next.add(newNode) ;
                }
            }
            public void print(){
                System.out.print(this.data + "	") ;    // 输出节点内容
                if(this.next!=null){        // 还有下一个元素,需要继续输出
                    this.next.print() ;    // 下一个节点继续调用print
                }
            }
            public boolean search(String data){    // 内部搜索的方法
                if(data.equals(this.data)){        // 判断输入的数据是否和当前节点的数据一致
                    return true ;
                }else{    // 向下继续判断
                    if(this.next!=null){    // 下一个节点如果存在,则继续查找
                        return this.next.search(data) ;    // 返回下一个的查询结果
                    }else{
                        return false ;        // 如果所有的节点都查询完之后,没有内容相等,则返回false
                    }
                }
            }
            public void delete(Node previous,String data){
                if(data.equals(this.data)){    // 找到了匹配的节点
                    previous.next = this.next ;    // 空出当前的节点
                }else{
                    if(this.next!=null){    // 还是存在下一个节点
                        this.next.delete(this,data) ;    // 继续查找
                    }
                }
            }
        };
        private Node root ;        // 链表中必然存在一个根节点
        public void addNode(String data){    // 增加节点
            Node newNode = new Node(data) ;    // 定义新的节点
            if(this.root==null){            // 没有根节点
                this.root = newNode ;    // 将第一个节点设置成根节点
            }else{        // 不是根节点,放到最后一个节点之后
                this.root.add(newNode) ;    // 通过Node自动安排此节点放的位置,从根节点开始查找着添加节点。
            }
        }
        public void printNode(){        // 输出全部的链表内容
            if(this.root!=null){        // 如果根元素不为空
                this.root.print() ;    // 调用Node类中的输出操作
            }
        }
        public boolean contains(String name){    // 判断元素是否存在
            return this.root.search(name) ;    // 调用Node类中的查找方法
        }
        public void deleteNode(String data){        // 删除节点
            if(this.contains(data)){    // 判断节点是否存在
                // 一定要判断此元素现在是不是根元素相等的
                if(this.root.data.equals(data)){    // 内容是根节点
                    this.root = this.root.next ;    // 修改根节点,将第一个节点设置成根节点
                }else{
                    this.root.next.delete(root,data) ;    // 把下一个节点的前节点和数据一起传入进去,用this.root.next调用方法,是利用在调用方法中利用this当前对象,作为第一个判断是不是等于要删除的节点。
                }
            }
        }
    };
    public class LinkDemo02{
        public static void main(String args[]){
            Link l = new Link() ;
            l.addNode("A") ;        // 增加节点
            l.addNode("B") ;        // 增加节点
            l.addNode("C") ;        // 增加节点
            l.addNode("D") ;        // 增加节点
            l.addNode("E") ;        // 增加节点
            System.out.println("======= 删除之前 ========") ;
            l.printNode() ;
            // System.out.println(l.contains("X")) ;
            l.deleteNode("C") ;        // 删除节点
            l.deleteNode("D") ;        // 删除节点
            l.deleteNode("A") ;        // 删除节点
            System.out.println("
    ====== 删除之后 =========") ;
            l.printNode() ;
            System.out.println("
    查询节点:" + l.contains("B")) ;
        }
    };

    2)为了查看全部链表,这里定义了一个打印链表的方法。

    3)查找节点,肯定是继续使用递归的操作进行查找操作的。

    4)完成删除功能,如果要想删除节点,肯定就是改变节点的引用对象的内容。但是在删除前要确保此节点存在。否则无法删除。

    5)删除节点要判断是不是根节点,要是根节点的话,需要修改他的下一个为根节点。

    6)做删除操作,需要把删除的节点和他前面的节点一起传入删除方法,因为要修改引用对象,必须要前一个节点的存在。

    总结

    1,这个题把链表本身作为一个外部类。而节点作为内部类。

    2,这里用到的知识点包括递归,this的当前对象功能。

    3,由于增加节点不知道首节点的位置,所以需要从根节点开始查找,所以用了根节点调用添加方法,然后根据判断下一个节点来视情况添加。

    4,本程序实际上就是针对引用的扩展应用。而且在本程序中只是实现了最简单的单向链表功能。

  • 相关阅读:
    关于32位操作系统和64位操作系统对InstallShield打包的影响
    NEWS: Symantec宣布Wise Package Studio将终止
    InstallShield 2012新功能试用(2) 调用MsiGetProperty等MSI API发生变化
    Basic INFO 在命令行Build InstallShield安装包工程获得压缩安装包
    NEWS InstallShield 2012 Service Pack 1发布
    Basic INFO InstallShield Basic MSI工程中如何在SetupCompleteSuccess界面中启动Readme
    Basic INFO InstallShield的脚本编辑器中如何显示代码行号
    Basic INFO 关于在InstallShield制作的安装包界面中删除InstallShield文字的厂商回复
    Basic INFO InstallShield工程中如何让产品的快捷方式名称始终与产品名保持一致
    Basic INFO: 创建隐藏文件夹
  • 原文地址:https://www.cnblogs.com/alsf/p/5521327.html
Copyright © 2011-2022 走看看