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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HeadingAlong/article/details/54783264

链表结构

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

何为单链表

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

代码实现

功能包括:添加数据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);
            }
        };
    }
}

猜你喜欢

转载自blog.csdn.net/HeadingAlong/article/details/54783264