链表实现系列(一)——简单链表Java实现

简单链表的原理在这里就不赘述了,推荐一篇比较不错的博客:链表原理

需要实现的操作包括:

  1. 在头节点之前插入节点;
  2. 在尾节点之后插入节点;
  3. 删除包含指定数据的节点;
  4. 删除尾节点;
  5. 查找包含指定数据的节点;
  6. 获取链表的长度;

辅助操作包括:

  1. 清空链表;
  2. 判断链表是否为空。

下面是简单链表的实现

/**
 * 注意:该链表实现不适合用于保存有重复元素的集合
 */

public class SingleList<Type> {

    public static class SingleNode<Type> {
        //节点作为内部静态类
        private Type data;
        private SingleNode next;

        /**
         * 三种构造方法
         */
        public SingleNode(){
            this.data = null;
            this.next = null;
        }

        public SingleNode(Type data){
            this.data = data;
            next = null;
        }

        public SingleNode(Type data, SingleNode next){
            this.data = data;
            this.next = next;
        }

        /**
         * data 的 get()和 set()方法
         */
        public Type getData(){
            return this.data;
        }

        public void setData(Type data){
            this.data = data;
        }

        /**
         * next 的 get()和 set()方法
         */
        public SingleNode getNext(){
            return this.next;
        }

        public void setNext(SingleNode next){
            this.next = next;
        }

    }

    private SingleNode head;
    private SingleNode tail;

    public SingleList(){
        head = tail = null;
    }

    public SingleNode getHead(){
        return this.head;
    }

    public SingleNode getTail() {
        return tail;
    }

    /**
     * 从头部添加节点
     * @param data:添加的节点的数据
     */
    public void addNodeBeforeHead(Type data){

        if (this.head == null)//当前链表为空,则将这个新节点设置为头节点和尾节点
            this.head = this.tail = new SingleNode(data,null);
        else {//当前链表不为空,则将这个新节点放到头节点前,让这个新节点作为头节点
            SingleNode node = new SingleNode(data,head);
            head = node;
        }

    }
    /**
     * 从尾部添加节点
     * @param data:添加的节点的数据
     */
    public void addNodeAfterTail(Type data){
        if (this.head == null){//当前链表为空,将这个新节点设置为头节点和尾节点
            this.head = this.tail = new SingleNode(data,null);
        } else {//当前链表不为空,将这个新节点放到尾节点后,让这个新节点作为尾节点
            SingleNode node = new SingleNode(data,null);
            tail.next = node;
            tail = tail.next;
        }
    }

    /**
     * 根据数据删除节点
     * @param data:需要删除的节点的数据
     *            注意:会将数据域与 data 相同的、最靠近链表头的那一个节点删除掉
     * @return 删除的节点 n
     */
    public SingleNode removeNodeByData(Type data){
        SingleNode n,before,current;
        before = head;
        if (before.getData().equals(data)){//删除的数据是链表头
            n = before;//记录下表头节点
            head = before.next;
            return n;
        }
        while (before.next != null){//没有到链表末尾
            current = before.next;//设置当前节点的值,即 before 的下一个节点
            if (current.data.equals(data)){//如果当前节点的数据即为指定的数据 data
                n = current;//保存下当前节点
                before.next = current.next;//将 before 节点的后继节点设置为 current 节点的后继节点,实现删除current节点
                return n;//删除完成
            }
            before = current;
        }
        return null;
    }

    /**
     * 删除尾节点 tail
     * @return 删除掉的原来的尾节点 tail
     */
    public SingleNode removeTail(){
        SingleNode current = head;
        SingleNode oldTail = tail;
        while (current.next.next != null){//下一个节点不是尾节点 tail
            current = current.next;
        }
        //下一个节点是尾节点
        current.next = null;//设置当前节点的后继节点为空
        tail = current;//将当前节点设置为尾节点 tail
        return oldTail;
    }

    /**
     * 根据数据查找节点
     * @param data :节点的数据
     * @return  :查找到的节点
     *    注意 :该方法只返回满足要求的、离头节点最近的节点
     */
    public SingleNode findNodeByData(Type data){
        SingleNode current = head;
        while (current.next != null) {
            if (current.data.equals(data))
                return current;
            else
                current = current.next;
        }
        return null;
    }

    /**
     * 计算链表长度
     * @return 链表的节点个数(即链表长度)
     */
    public int getListLength(){
        int count = 1;
        SingleNode current = head;
        while (current.next != null){
            current = current.next;
            count++;
        }
        return count;
    }

    /**
     * 清空链表
     */
    public void clear(){
        head = null;
    }

    /**
     * 判断链表是否为空
     * @return 链表是否为空
     */
    public boolean isEmpty(){
        if ((head == null) && (tail == null))
            return true;
        return false;
    }

    /**
     * 打印链表中的数据,仅用于测试
     */
    public void display(){
        SingleNode current = head;
        while (current != null){
            System.out.print(" " + current.data);
            current = current.next;
        }
        System.out.println("\n");
    }
}

 下面是测试代码

public class SingleTest {

    private static final int MULTI = 6;

    private int data;
    private SingleList<Integer> list = new SingleList();
    private SingleList.SingleNode node;

    public static void main(String[] args) {
        SingleTest s = new SingleTest();
        s.run();
    }

    public void run(){

        System.out.println("新建链表:");
        list.display();

        System.out.println("初始化链表:使用addNodeAfterHead()方法");
        for (int i = 0; i < 5; i++) {//初始化链表
            list.addNodeBeforeHead(i*MULTI);
        }
        list.display();//打印链表

        testAddNodeAfterHead();     //测试方法 addNodeBeforeHead()
        testAddNodeAfterTail();     //测试方法 addNodeAfterTail()
        testRemoveNodeByData();     //测试方法 removeNodeByData()
        testRemoveTail();           //测试方法 removeTail()
        testFindNodeByData();       //测试方法 findNodeByData()
        testGetListLength();        //测试方法 getListLength()

    }

    public void testAddNodeAfterHead(){
        data = -1;
        System.out.println("从链表头部添加数据:" + data);
        list.addNodeBeforeHead(data);
        list.display();
    }

    public void testAddNodeAfterTail(){
        data = 100;
        System.out.println("从链表尾部添加数据:" + data);
        list.addNodeAfterTail(data);
        list.display();
    }

    public void testRemoveNodeByData(){
        data = 24;
        System.out.println("从链表中删除数据:" + data);
        node = list.removeNodeByData(data);
        if (node == null)
            System.out.println("数据:" + data + " 不存在!");
        else
            System.out.println("删除数据:" + data + " 成功!");
        list.display();
    }

    public void testRemoveTail(){
        System.out.print("删除链表的尾部节点:");
        node = list.removeTail();
        if (node == null)
            System.out.println("链表为空!");
        else
            System.out.println(node.getData());
        list.display();
    }

    public void testFindNodeByData(){
        data = 15;
        System.out.println("查找数据:" + data);
        node = list.findNodeByData(data);
        if (node == null)
            System.out.println("数据:" + data + " 不存在!");
        else {
            System.out.println("  数据:" + node.getData());
            System.out.println("  后继节点:" + node.getNext());
        }
        list.display();
    }

    public void testGetListLength(){
        int length = list.getListLength();
        System.out.println("当前链表长度为:" + length);
    }
}

格式不够好,还望多多包涵~/bq 

猜你喜欢

转载自blog.csdn.net/weixin_42034276/article/details/86707331
今日推荐