单链表的基本操作(一)——Java语言

一、单链表的基本操作:
(不带头节点的单链表)
创建一个包:把所有待实现的方法写在这个包下的一个接口中

package Test.listclass.impl;

public interface ILinked {
    //头插法
    void addFirst(int data);
    //尾插法
    void addLast(int data);
    //任意位置插入,第一个数据节点为0号下标
    boolean addIndex(int index,int data);
    //查找是否包含关键字key是否在单链表当中
    boolean contains(int key);
    //删除第一次出现关键字为key的节点
    int remove(int key);
    //删除所有值为key的节点
    void removeAllKey(int key);
    //得到单链表的长度
    int getLength();
    void display();
    void clear();
}

重新创建一个包:此包中写一个即将实现接口中的所有方法的类

package Test.listclass.dao;

import Test.listclass.impl.ILinked;
//不带头节点的单链表
public class MySingleListImpl implements ILinked {
......
}

以下的所有代码均是在MySingleListImpl类中写的:

首先在MySingleListImpl中写一个内部类Node类,该类用于在之后的各种操作中实例化一个node对象

    //设置节点data域和next域
    public class Node {
        private int data;
        public Node next;
        public Node(int data) {
            this.data = data;
            this.next=null;
        }
        public int getData() {
            return data;
        }
        public Node getNext() {
            return next;
        }
    }

设置head为空(此处head不是头节点,它的作用是标记链表的一个节点)

private Node head;

    public MySingleListImpl() {
        this.head = null;
    }

以下为在 MySingleListImpl类中实现接口中方法的具体代码,须将以下代码放入MySingleListImpl类中

1.头插法:
第一次头插:直接将node赋给head;
之后插入:新的node的next指向原来的head,将新的node作为head;

@Override
    public void addFirst(int data) {
        Node node = new Node(data);
        if (this.head == null) {
            this.head = node;
        } else {
            node.next = head;
            this.head = node;
        }
    }

2.尾插法:
第一次插:head直接指向node;
之后插:用cur先找到链表尾,之后直接插cur.next=node;

@Override
    public void addLast(int data) {
        Node node = new Node(data);
        Node cur = this.head;
        if (cur == null) {
            this.head = node;
        } else {
            while (cur.next != null) {
                cur = cur.next;
            }
            cur.next = node;
        }
    }

3.在指定位置index处插入一个节点
首先找出要插入位置的前一个节点—— searchIndex(int index):
(前提:先检查此位置的合法性 ——checkIndex(int index))
找到后返回index-1处的节点
插入:需判断是否在第一个结点前插入

//找到index-1的位置
    private Node searchIndex(int index) {
        checkIndex(index);
        if (index == 0) {
            return null;
        }
        int count = 0;//记录走的步数
        Node cur = this.head;
        while (cur.next != null && count < index - 1) {
            cur = cur.next;
            count++;
        }
        return cur;
    }

    //检查index的合法性
    private void checkIndex(int index) {
        if (index < 0 || index > getLength()) {
            throw new IndexOutOfBoundsException("下表不合法");
        }
    }

    //在index位置插入data
    @Override
    public boolean addIndex(int index, int data) {
        Node node = new Node(data);
        //searchIndex:找到index前的节点,返回值赋给cur
        Node cur = searchIndex(index);
        //若searchIndex返回值为null,则说明index在第一个节点位置,在第一个结点this.head前插入node
        if (cur == null) {
            node.next = this.head;
            this.head = node;
        } else {
            node.next = cur.next;
            cur.next = node;
        }
        return true;
    }

4.是否包含某个节点,其data值为key——遍历查找

@Override
    public boolean contains(int key) {
        Node cur = this.head;
        while (cur != null) {
            if (cur.data == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

5.删除指定的key,若有重复,则删除第一次出现的该key

 @Override
    public int remove(int key) {
        Node cur1 = this.head;
        Node cur2 = cur1;
        //用来保存将要删除节点的data
        int oldData;
        //要删除的节点为第一个节点
        if (this.head.data == key) {
            oldData = this.head.data;
            cur1 = this.head.next;
            this.head.next = null;
            this.head = cur1;
            return oldData;
        }
        //删除中间节点,注意循环条件,不能包括删除最后一个节点的情况
        while (cur1.next != null) {
            //cur2在前,cur1在后
            cur2 = cur1;
            cur1 = cur1.next;
            if (cur1.data == key) {
                oldData = cur1.data;
                cur1 = cur1.next;
                cur2.next = cur1;
                return oldData;
            }
        }
        //删除最后一个节点
        if (cur1.data == key) {
            cur2.next = null;
            return cur1.data;
        } else
            return -1;
    }

6.删除所有指定的key

public void removeAllKey(int key) {
        Node pre = this.head;
        Node cur = this.head.next;
        while (cur != null) {
            if (cur.data != key) {
                pre = cur;
                cur = cur.next;
            } else {
                pre.next = cur.next;
                cur = cur.next;
            }
        }
        if (head.data == key) {
            head = head.next;
        }
    }

7.计算链表长度、打印链表元素、清空链表

//计算链表长度
    @Override
    public int getLength() {
        Node cur = this.head;
        int count = 0;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

    @Override
    public void display() {
        Node cur = this.head;
        while (cur != null) {
            System.out.print(cur.data + " ");
            cur = cur.next;
        }
        System.out.println();
    }

    //清空链表
    @Override
    public void clear() {
        while (this.head != null) {
            Node cur = this.head.next;
            this.head.next = null;
            this.head = cur;
              }
    }
  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值