Java数据结构——不带头单向非循环链表

一、链表的概念

链表:采用链式存储结构存储的线性表,所谓的链式是指每个节点保存下一个节点的引用

链表的分类:

  • 单向、双向
  • 带头节点、不带头节点
  • 循环、非循环

根据以上三种分类,即可组成八种不同类型的链表

链表的特点:

链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理,但是链表失去了顺序表可以随机读取的优点,同时,链表增加了节点的指针域,空间开销比较大。

二、不带头单向非循环链表              

1.结构图 

                 

2. 节点类组成

class Node {  //内部节点类
        private int data;  //节点数据
        private Node next;  //下一个节点引用
        public Node(int data) {  //带参数的构造方法,用于实例化普通节点
            this.data = data;
            this.next = null;
        }
        //头结点
        public Node() {  //不带参数的构造方法,用于实例化头节点
            this.data = -1;
            this.next = null;
        }
    }

3. 常用的链表操作

1)遍历链表

2)头插法

3)尾插法

4) 任意位置插入

5) 删除第一次出现关键字为key的节点

6)  删除所有关键字为key的节点

7)清空链表 

4. 接口

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();
}

5. 实现类

public class MySingleList implements ILinked{
    //内部节点类
    class Node {
        private int data;//存储该节点中的元素
        public Node next;//引用下一个节点

        //节点类构造方法
        public Node(int data) {
            this.data = data;
            this.next = null;
        } 
    }

    private Node head;//头节点

    //链表类构造方法
    public MySingleList() {
        this.head = null;
    }

    @Override
    //头插法
    public void addFirst(int data) {
        Node node = new Node(data);//新建一个插入节点
        if(this.head == null) {//头节点为空,则插入节点为头节点
            this.head = node;
        }else {//头节点不为空
            node.next = this.head;
            this.head = node;
        }
    }

    @Override
    //尾插法
    public void addLast(int data) {
        Node node = new Node(data);
        Node cur = this.head;
        //如果是第一次插入
        if(cur == null) {
            this.head = node;
        }else {
            //1、找尾巴
            while(cur.next != null) {
                cur = cur.next;
            }
            //退出上面的循环,cur所指向的位置就是尾节点
            cur.next = node;
        }
    }

// 返回index位置的节点
    private Node searchIndex(int index){
        checkIndex(index);
        int count=0;
        Node cur=this.head;
        while(count<index-1){
            cur=cur.next;
            count++;
        }
        return cur;
    }
    //检验index位置合法性
    private void checkIndex(int index){
        if(index<0||index>getLength()){
            throw new UnsupportedOperationException("index位置不合法");
        }
    }

    @Override
    //任意位置插入
    public boolean addIndex(int index, int data) {
    if(index==0){
        addFirst(data);
        return true;
    }
    Node node =new Node(data);
    Node cur=searchIndex(index);
    node.next=cur.next;
    cur.next=node;
    return true;
    }

    @Override
    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key) {
        Node cur=this.head;
        while(cur!=null){
            if(cur.data==key){
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    private Node searchPrev(int key){
        Node cur=this.head;
        while(cur.next!=null){
            if(cur.next.data==key){
                return cur;
            }
           cur=cur.next;
        }
        return null;
    }
    @Override
    //删除第一次出现关键字为key的节点
    public int remove(int key) {
        if(this.head == null) {
            throw new UnsupportedOperationException("单链表为空");
        }
        int oldData = 0;
        //删除的节点是头结点
        if(this.head.data == key){
            oldData = this.head.data;
            this.head = this.head.next;
            return oldData;
        }
        Node prev = searchPrev(key);
        if(prev == null) {
            //return
            throw new UnsupportedOperationException("没有前驱");
        }
        Node del = prev.next;
        oldData = del.data;
        prev.next = del.next;
        //del = null;
        return oldData;
    }

//删除所有关键字为key的节点
    public void removeAllKey(int key) {
        if(this.head == null) {
            return;
        }
        Node prev = this.head;
        Node cur = this.head.next;
        while (cur != null) {
            if(cur.data == key){
                prev.next = cur.next;
                cur = prev.next;
            }else {
                prev = cur;
                cur = cur.next;
            }
        }
        if(this.head.data == key){
            this.head = this.head.next;
        }
    }

    @Override
    public int getLength() {
        if(this.head == null) {
            return 0;
        }
        int count = 0;
        Node cur = this.head;
        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.next != null) {
            Node del = this.head.next;
            this.head.next = del.next;
        }
        this.head = null;
    }
发布了50 篇原创文章 · 获赞 39 · 访问量 8282

猜你喜欢

转载自blog.csdn.net/Racheil/article/details/90176639