实例讲解——单向链表(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 + "\t") ;    // 输出节点内容
            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("\n====== 删除之后 =========") ;
        l.printNode() ;
        System.out.println("\n查询节点:" + l.contains("B")) ;
    }
};

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

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

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

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

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

总结

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

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

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

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

时间: 2024-11-03 03:29:10

实例讲解——单向链表(2)的相关文章

实例讲解-单向列表的实现(1)

实例要求 在数据结构中,经常看到一个基本概念,对于一个链表的实现基本都是基于引用数据类型的操作. 如果要想设计一个链表,则肯定要设计一个链表的节点类.在此类中必须有一个属性可以保存下一个节点的引用地址. 根据此概念,设计一个节点类.以String为数据保存内容. class Node{ // 定义节点类 private String data ; // 保存节点内容 private Node next ; // 表示保存下一个节点 public Node(String data){ // 通过构

单向链表实例:终端交互简易通讯录

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 6 typedef struct Contacts_infomation{ 7 char name[13]; 8 char work_unit[61]; 9 char phone_number[12]; 10 char E_mail[61]; 11 struct Contacts_infomation *next; 12 }con_i

单向链表排序

一.冒泡排序简述 1.概念 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法. 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越大的元素会经由交换慢慢"浮"到数列的顶端. 2.实例分析 以数组为例进行说明: 数组a[4] = {4,3,2,1} 从前向后依次比较两个元素的大小,如果顺序错误就交换它们.经过这样一轮,最大的元素就被

单向链表实现源码

单向链表实现源码public class LinkList<T>{//定义一个内部类Node,Node实例代表链表的节点private class Node{//保存节点的数据private T data;//指向下个节点的引用private Node next;//无参数的构造器public Node(){}//初始化全部属性的构造器public Node(T data , Node next){this.data = data;this.next = next;}}//保存该链表的头节点p

Java入门系列:实例讲解ArrayList用法

本文通过实例讲解Java中如何使用ArrayList类. Java.util.ArrayList类是一个动态数组类型,也就是说,ArrayList对象既有数组的特征,也有链表的特征.可以随时从链表中添加或删除一个元素.ArrayList实现了List接口. 大家知道,数组是静态的,数组被初始化之后,数组长度就不能再改变了.ArrayList是可以动态改变大小的.那么,什么时候使用Array(数组),什么时候使用ArrayList?答案是:当我们不知道到底有多少个数据元素的时候,就可使用Array

【转】单向链表(单链表)的Java实现

最近被问到链表,是一个朋友和我讨论Java的时候说的.说实话,我学习编程的近一年时间里,学到的东西还是挺少的.语言是学了Java和C#,关 于Web的学了一点Html+css+javascript.因为比较偏好,学习WinForm时比较认真,数据库操作也自己有所研究.但链表这个东西我 还真没有学习和研究过,加上最近自己在看WPF,而课程也到了JSP了,比较紧. 但是我还是抽了一个晚上加半天的时间看了一下单向链表.并且使用Java试着写了一个实例出来.没有接触过链表的朋友可以作为参考,希望大家多提

数据结构-线性表之单向链表--一点一滴

单向链表 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始. 单向链表的数据结构可以分为两部分:数据域和指针域,数据域存储数据,指针域指向下一个储存节点的地址.分为动态单向链表和静态单向链表.单向链表也可以根据是否带头节点分为带头节点结构和无带头节点结构.我们把指向单链表的指针为头指针.头指针所指的不存放数据元素的第一个节点称作头节点.存放数据元素的节点成为第一个数据元素节点. 注:第一个数据元素节点在带头节点单链表中是第二个节点:而在不带头节

(转)使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解

使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解 本文用代码简单介绍cjson的使用方法,1)创建json,从json中获取数据.2)创建json数组和解析json数组 1. 创建json,从json中获取数据 1 #include <stdio.h> 2 #include "cJSON.h" 3 4 char * makeJson() 5 { 6 cJSON * pJsonRoot = NULL; 7 8 pJsonRoot = cJSON_Create

写给过去的自己-No.1-数据结构篇-单向链表C语言的实现

过去的自己,你好.     今天我来教你单向链表,不知道你何时会看到这篇文章,也不知道你此刻对C语言的掌握,我会尽可能讲解细一点.     讲链表之前我先讲一下数组.相信你不管怎样肯定用过数组对吧,数组就是一种数据的组织形式,特点是所有的数据在逻辑上是顺序摆放的,通过数组名和数组下标 就可以找到某个元素,而且在内存中存放的物理地址也是连续的,定义数组时,一旦中括号中的数字确定了,数组中元素个数也就确定了.那么问题来了,因为数组 的大小需要提前确定,所以定义数组时必须统计好程序中用了多少元素,用多