单链表的基本操作

package ccnu.linkList;

public class LinkList {
    private Node first; // 第一个节点
    private Node rear; // 最后一个节点
    private int size; // 当前链表的大小

    public LinkList() {
        this.first = null;
        this.rear = null;
        this.size = 0;
    }

    /**
     * 链表中的元素的个数
     * 
     * @return 返回该链表中元素的个数
     */
    public int size() {
        return size;
    }

    /**
     * 判断当前对象是否为空,如果空,当且仅当没有任何元素,{@link #size()}为0
     * 
     * @return true,如果{@link #size()}为0,否则false
     */
    public boolean isEmpty() {
        if (size == 0) {
            return true;
        }
        return false;
    }

    /**
     * 头插法,在链表的头部插入节点
     * 
     * @param data
     *            插入节点的数据
     * @see #insertAtRear(int)
     * @see #insertByIndex(int, int)
     */
    public void insertAtHead(int data) {
        Node node = new Node(data);
        size++;
        if (size == 1) { // 第一个节点采用头插法
            first = node;
            rear = node;
        } else {
            node.next = first; // 当前节点插入到最前
            first = node;
        }
    }

    /**
     * 尾插法,在链表的尾部插入节点
     * 
     * @param data
     *            插入节点的数据
     * @see #insertAtHead(int)
     * @see #insertByIndex(int, int)
     */
    public void insertAtRear(int data) {
        Node node = new Node(data);
        size++;
        if (size == 1) { // 第一个节点采用尾插法
            first = node;
            rear = node;
        } else {
            rear.next = node; // 当前节点插入到最后
            rear = node;
        }
    }

    /**
     * 指定索引位置插入节点(其后面)
     * 
     * @param index
     *            插入位置
     * @param data
     *            所要插入节点的数据
     * @see #insertAtHead(int)
     * @see #insertAtRear(int)
     */
    public void insertByIndex(int index, int data) {
        if (index < 0 || index > (size - 1)) {
            return;
        }
        int pos = 0;
        Node current = first;
        Node node = new Node(data);
        while (pos != index) {
            pos++;
            current = current.next;
        }
        node.next = current.next;
        current.next = node;
        if(node.next == null){ // 插入的位置为最后一个位置
            rear = node;
        }
        size++;
    }

    /**
     * 删除任意索引位置的节点,并返回该节点,返回null,如果位置不合法
     * 
     * @param index
     *            指定位置
     * @return 返回将要删除的节点
     * @see #deleteByData(int, boolean)
     * @see #deleteByData(int)
     */
    public Node deleteByIndex(int index) {
        Node current = first; // 当前节点
        Node previous = null; // 当前节点的前一个节点
        int pos = 0;
        if (index < 0 || index >= size) { // 超出索引范围
            return null;
        } else {
            while (pos != index) {
                pos++;
                previous = current;
                current = current.next;
            }
        }
        if (current == first) { // 删除节点为第一个节点
            first = first.next;
        } else {
            previous.next = current.next;
        }
        if (current.next == null) { // 删除节点为最后一个节点
            rear = previous;
        }
        size--;
        // current.next = null; // 仅保留数据域
        return current; // 返回指定索引的节点
    }

    /**
     * 删除链表中指定数据的节点,并返回删除的节点(集)
     * 
     * @param data
     *            数据域
     * @param flag
     *            true表示删除所有data元素,缺省为false
     * @return 表示"删除链表"的第一个节点
     * @see #deleteByData(int)
     */
    public Node deleteByData(int data, boolean flag) { // flag = true
                                                        // 表示删除所有值为data的节点,否则只删除出现的第一个值为data节点
        Node newFirst = null; // 所有删除指定data的链表的第一个节点
        Node newRear = null;
        int pos = 0;
        Node current = first;
        if (flag == false) {
            while (current != null) {
                if (current.data == data) {
                    deleteByIndex(pos);
                    // return (newFirst = current);
                    newFirst = current;
                    newFirst.next = null; // 只保留数据域
                    break;
                }
                current = current.next;
                pos++; // 记录当前索引位置
            }
        } else {
            while (current != null) {
                if (current.data == data) {
                    deleteByIndex(pos);
                    pos--; // 删除链表中一个节点后,当前最新链表元素少一个,对应的索引也要减少
                    if (newFirst == null) { // 在"删除链表"中插入第一个节点
                        newFirst = current;
                        newRear = current;
                    } else {
                        newRear.next = current;
                        newRear = current;
                    }
                }
                current = current.next;
                pos++;
            }
        }
        return newFirst;
    }

    /**
     * 仅删除链表中的第一个为指定数据的节点,并返回这个节点
     * 
     * @param data
     *            指定数据
     * @return 删除的节点
     * @see #deleteByData(int, boolean)
     */
    public Node deleteByData(int data) {
        return deleteByData(data, false);
    }

    /**
     * 根据指定数据在链表中获取其位置 (首次出现)
     * 
     * @param data
     *            数据
     * @return 数据的位置,返回-1,如果链表中木有这个数据
     */
    public int findByData(int data) {
        Node current = first;
        int pos = 0;
        while (current != null) {
            if (current.data == data) {
                return pos;
            }
            current = current.next;
            pos++;
        }
        return -1;
    }

    /**
     * 根据指定的位置获取这个节点
     * 
     * @param index
     *            索引位置
     * @return 指定位置的节点
     */
    public Node findByIndex(int index) {
        Node current = first;
        int pos = 0;
        while (current != null) {
            if (pos == index) {
                return current;
            }
            current = current.next;
            pos++;
        }
        return null;
    }

    /**
     * 用新数据替代指定数据 (修改一个,如果存在)
     * 
     * @param oldData
     *            待查数据
     * @param newData
     *            新数据
     * @see #replaceAll(int, int)
     */
    public void replace(int oldData, int newData) {
        Node current = first;
        while (current != null) {
            if (current.data == oldData) {
                current.data = newData;
                return;
            }
            current = current.next;
        }
    }

    /**
     * 用新数据替代指定数据 (修改所有,如果存在)
     * 
     * @param oldData
     *            待查数据
     * @param newData
     *            新数据
     * @see #replace(int, int)
     */
    public void replaceAll(int oldData, int newData) {
        Node current = first;
        while (current != null) {
            if (current.data == oldData) {
                current.data = newData;
            }
            current = current.next;
        }
    }

    /**
     * 显示整个链表的信息
     *
     */
    public void displayAllNodes() {
        Node current = first;
        while (current != null) {
            current.display();
            current = current.next;
        }
    }
/**
     * 
     * 反向输出单链表所有值(递归)
     */
    public void reverseOutput(Node first){
        if(first == null){
            return;
        }
        Node cur = first;
        if(cur.next == null){
            System.out.print(new Integer(cur.data).toString() + " ");
        }else{
            reverseOutput(cur.next);
            System.out.print(new Integer(cur.data).toString() + " ");

        }
    }
    /**
     * 反向输出单链表所有值(栈存储方式)
     * 
     */
    public void reverseOutput2(Node first){
        List<Node> l = new LinkedList<Node>();
        Node node = first;
        while(node != null){
            l.add(node);
            node = node.next;
        }
        while(l.size() != 0){
            System.out.print(new Integer(l.remove(l.size()-1).data).toString() + " ");
        }
    }

    /**
     * 将原单链表进行倒置
     * @param first 原单链表的头结点
     * @return 倒置后单链表的头结点
     */
    public Node reverseList(Node first){
        if(first == null){
            return null;
        }
        Node p, q;
        p = first.next;
        first.next = null;
        while(p != null){
            q = p;
            p = p.next;
            q.next = first;
            first = q;
        }
        return first;
    }

}


package ccnu.linkList;

public class Node {
    // 私有,设置getter和setter
    protected Node next; // 指针域
    protected int data; // 数据域

    public Node() {
        this(0);
    }

    public Node(int data) {
        this.data = data;
        this.next = null;
    }

    public void display() {
        if (this.next != null) {
            System.out.print(data + "-->");
        } else {
            System.out.print(data);
        }
    }

    @Override
    public String toString() {
        return "Node [data=" + data + "]";
    }


}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值