用java实现单链表结构与基本数据操作

链表结构

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的。链表由结点组成。每个结点的构成:元素(数据元素的映象) +引用(指示后继元素存储位置),元素就是存储数据的存储单元,引用就是连接每个结点的地址数据。

何为单链表

单链表是链式存取的结构,想要找到某个数据元素,必须先从第一个或者特指的某个元素向后查找。

代码实现

功能包括:添加数据add, 修改数据update, 删除数据remove,迭代器的实现,重写toString方法。
注意:该链表结构设计时不允许重复元素出现。

package com.it;

import java.util.Iterator;

import com.it.SingleLink.Node;

/**
 * 单链表数据结构
 * @author Administrator
 *
 */
public class SingleLink<T> implements Iterable<T>{

    class Node{//创建节点类
        private T date;
        private Node next;
        public Node(T date){
            this.date = date;
        }
    }
    private Node head;//头结点
    /**
     * 添加数据
     * @param date
     *      T数据
     * @return
     *      Boolean类型返回值,true说明添加成功
     *                      false说明添加失败
     */
    public boolean add(T date){//添加一个数据
        boolean flag = false;
        Node newNode = new Node(date);//创建新节点
        //链表是否为空
        if(head==null){//为空时,使用该数据创建节点,作为头结点
            head = newNode;
            flag = true;
        }else{//不为空,遍历找到尾节点,next节点指向该新节点
            Node tailNode = findTailNode();
            tailNode.next = newNode;
            flag = true;
        }
        return flag;

    }
    /**
     * 移除数据
     * @param date
     * @return
     */
    public boolean remove(T date){
        boolean flag = false;
        //遍历链表,找到数据所在的节点
        Node dateNode = findNode(date);
        //找到前一个节点和后一个节点
        Node prevNode = findPrevNode(date);
        Node nextNode = dateNode.next;
        if(prevNode==null){//说明该数据是头结点
            if(nextNode==null){//说明链表只有一个元素
                //将头结点置为空
                head = null;
                flag = true;
            }
            //将头结点指向下一个节点
            head = nextNode;
            flag = true;
        }else if(nextNode==null){//说明该数据是尾节点
            //将前一个节点的next节点置为null
            prevNode.next = null;
            flag = true;
        }else{//这时数据节点处在中间
            //将前一个节点的next节点指向nextNode
            prevNode.next = nextNode;
            flag = true;
        }
        return flag;
    }
    /**
     * 更新数据
     * @param old
     * @param newDate
     * @return
     */
    public boolean update(T old,T newDate){
        boolean flag = false;
        Node target = findNode(old);//找到要更新的节点(此时拿到的是节点的引用)
        if(target==null){
            throw new RuntimeException("没有此数据");
        }else{//确定节点已经存在
            Node existNode = findNode(newDate);
            if(existNode!=null){//确定数据唯一
                throw new RuntimeException("该数据已经存在,请使用不存在的数据");
            }
            //修改该数据的date值
            target.date = newDate;
            flag = true;

        }
        return flag;
    }

    /**
     * 查找前一个节点
     * @param date
     *      节点数据
     * @return
     *      Node
     */
    private Node findPrevNode(T date) {
        //从头开始遍历
        Node temp = head;
        while(temp!=null){
            if(temp.next!=null){
                T dat = temp.next.date;
                if(date.equals(dat)){
                    return temp;
                }else{
                    temp = temp.next;//找到下一个节点
                }
            }
        }
        return null;
    }
    /**
     * 根据数据内容查找节点
     * @param date
     * @return
     */
    private Node findNode(T date) {
        //从头开始遍历
        Node temp = head;
        while(temp!=null){
            T dat = temp.date;
            if(date.equals(dat)){
                return temp;
            }else{
                if(temp.next!=null){//不是最后一个节点
                    temp = temp.next;//找到下一个节点
                }else{//是最后一个节点
                    return null;
                }
            }
        }
        return null;
    }
    /**
     * 找到尾节点
     * @return
     *      尾部节点
     */
    private Node findTailNode() {
        //从头开始遍历
        Node temp = head;
        Node tailNode = null;
        while(temp!=null){
            if(temp.next!=null){//不是最后一个节点
                temp = temp.next;//找到下一个节点
            }else{//是最后一个节点
                tailNode = temp;
                break;//跳出循环,将尾节点返回
            }
        }
        return tailNode;
    }

    @Override
    /**
     * 重写toString方法
     */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append('[');
        if(head!=null){
            Node temp = head;
            while(temp!=null){
                if(temp.next!=null){//不是最后一个节点
                    sb.append(temp.date).append(',');
                    temp = temp.next;//找到下一个节点
                }else{//是最后一个节点
                    sb.append(temp.date).append(']');
                    break;
                }
            }
        }else
            sb.append(']');
        return sb.toString();
    }
    @Override
    /**
     * 迭代器的实现
     * @return
     */
    public Iterator<T> iterator() {

        return new Iterator<T>() {
            Node node = head;//从头结点开始迭代
            T date = null;//得到结点的数据
            @Override
            public boolean hasNext() {

                return node!=null;
            }

            @Override
            public T next() {
                //先获取到数据
                date = node.date;
                node = node.next;
                return date;
            }

            @Override
            public void remove() {
        SingleLink.this.remove(date);
            }
        };
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构单链表插入、删除和修改实验报告 一、实验目的 1.理解数据结构中带头结点单链表的定义和逻辑图表示方法。 2.掌握单链表中结点结构JAVA描述。 3.熟练掌握单链表的插入、删除和查询算法的设计与JAVA实现。 4.熟练掌握简单的演示菜单与人机交互设计方法。 二、实验内容 1. 编制一个演示单链表插入、删除、查找等操作的程序。 三、实验步骤 1.需求分析 本演示程序用JAVA编写,完成单链表的生成,任意位置的插入、删除,以及确定某一元素在单链表中的位置。 ① 输入的形式和输入值的范围:插入元素时需要输入插入的位置和元素的值;删除元素时输入删除元素的位置;查找操作时需要输入元素的值。在所有输入中,元素的值都是整数。 ② 输出的形式:在所有三种操作中都显示操作是否正确以及操作单链表的内容。其中删除操作后显示删除的元素的值,查找操作后显示要查找元素的位置。   ③ 程序所能达到的功能:完成单链表的生成(通过插入操作)、插入、删除、查找操作。 ④ 测试数据:  A. 插入操作中依次输入11,12,13,14,15,16,生成一个单链表    B. 查找操作中依次输入12,15,22返回这3个元素在单链表中的位置    C. 删除操作中依次输入2,5,删除位于2和5的元素 2.概要设计 1)为了实现上述程序功能,需要定义单链表的抽象数据类型:   ADT LinkList {    数据对象:D={ai|ai∈IntegerSet,i=0,1,2,…,n,n≥0}    数据关系:R={|ai,ai+1 ∈D}    基本操作: (1)insert 初始化状态:单链表可以不为空集;操作结果:插入一个空的单链表L。   (2)decelt     操作结果:删除已有的单链表的某些结点。 (3)display     操作结果:将上述输入的元素进行排列显示。    (4)modify     操作结果:将上述输入的某些元素进行修改。    (5)save     操作结果:对上述所有元素进行保存。    (6)load     操作结果:对上述元素进行重新装载。   }   2)本程序包含7个函数:   ① 主函数main()   ② 保存单链表函数save()   ③ 重载操作菜单函数load()   ④ 显示单链表内容函数display ()   ⑤ 插入元素函数insert ()   ⑥ 删除元素函数decelt ()   ⑦ 修改元素函数modify()   各函数间关系如下: 3.详细设计   实现概要设计中定义的所有的数据类型,对每个操作给出伪码算法。对主程序和其他模块也都需要写出伪码算法。   1) 结点类型和指针类型   typedef struct node {    int data;    struct node *next;   }Node,*singleLIST.java;   2) 单链表基本操作   为了方便,在单链表中设头结点,其data域没有意义。 bool insert(singleLIST) (伪码算法)   bool modify(singleLIST) (伪码算法)   void delect(singleLIST)   (伪码算法)   void display()   (伪码算法) 3) 其他模块伪码算法 4.调试分析   (略) 5.使用说明 程序名为 ,运行环境为Windows。程序执行后显示   ========================   0----EXIT   1----INSERT   2----DELETE   3----DISPLAY 4----MODIFY 5----EXIST =======================   SELECT:   在select后输入数字选择执行不同的功能。要求首先输入足够多的插入元素,才可以进行其他的操作。每执行一次功能,就会显示执行的结果(正确或错误)以及执行后单链表的内容。 选择5:退出程序   选择1:显示"INSERT =" ,   要求输入要插入的位置和元素的值(都是整数)。   选择2:显示"DELETE =" ,   要求输入要删除元素的位置,执行成功后返回元素的值。   选择3:显示"MODIFY = " , 选择要修改的对象,执行成功后返回新的元素值。 选择4:显示"DIAPLAY= "   显示所有单链表中的元素,自动进行排序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值