JAVA中对不带头单链表的一些操作1

一.定义单链表结点

首先呢我们先得定义单链表中的每个节点,最后再定义一个头节点,作为单链表的开头。

class Node {
        public int data;
        public Node next;

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

    public class MyLinedList {
        public Node head;

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

单链表中每个节点所存储的数据,指向下个结点的引用,都需要定义出来,其中Node就是引用类型,下来用构造方法对其进行数据初始化,由于我们并不知道我们定义的引用类型到底是什么,所以不需要对其进行初始化。最后呢,我们定义表头,也是Node类型,将他置为null,这里不需要置为null也是没有什么问题的,本来就是为空。

二.头插法

定义好单链表结构后,接下来,我们就来看,单链表的第一种创建方法:头插法。

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

头插法就是每次都把要插入的节点插在已存在结点的前面。首先我们需要传入要插入的节点的数据data,接下来呢,我们需要确定当前单链表是不是为空,为空的话,说明当前结点是第一个结点,就直接让定义好的头结点head指向该结点就好了,然后返回该单链表。若不是第一次插入,则我们需要将要插入节点的next指向当前的head,然后将新的head指向当前的node就行了。

三.尾插法

创建单链表的第二种方法就是尾插法

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

        }

尾插法呢就是每次插入到已有结点的后面。依然需要传入所插结点的数据,判断是否是第一次插入结点,第一次直接把head指向node就行了,若不是第一次,则首先我们先得找到当前链表的最后一个结点,定义cur指向head然后开始遍历,循环终止条件就是curnext为空,这时cur就是最后一个结点,然后把curnext指向node就行了。

四.任意位置插入结点

      public void addIndex(int index, int data) {
            if (index < 0 || index > size()) {
                System.out.println("位置不合法");
                return;
            }
            if (index == 0) {
                addFirst(data);
                return;
            }
            if (index == size()) {
                addLast(data);
                return;
            }
            int count = 0;
            Node node = new Node(data);
            Node prev = this.head;
            while (count < index - 1) {
                prev = prev.next;
                count++;
            }
            node.next = prev.next;
            prev.next = node;
        }
  public int size() {
            Node cur = this.head;
            int count = 0;
            while (cur != null) {
                count++;
                cur = cur.next;
            }
            return count;
        }

传入参数要插入的位置和插入节点的数据。首先我们得考虑插入位置是否合法,就是说如果插入位置小于0或者超过该结点的长度,都是不合法的,直接return 就行。若等于0或者等于该链表长度,其实对应的就是头插法和尾插法。当插入位置在中间时,我们就需要在该位置的前后两个结点动手脚,首先呢我们就需要找到插入位置的前一个结点,定义prev指向head,然后遍历走index-1步,此时prev就是指向插入位置的前一个结点,此时还需要注意是先改变前面的结点还是后面的结点,如果先让prev的结点的next指向node,这时当nodenext指向prev.next结点时,prev.next已经是node,所以无法实现连接,所以我们需要将这两个步骤颠倒,就可以了。

五. 删除第一次出现关键字为key的节点

    public void remove(int key) {
            if (this.head.data == key) {
                this.head = this.head.next;
                return;
            }
            Node prev = this.head;
            // Node prev = findPrev(key);
            while (prev.next != null) {
                if (prev.next.data == key) {
                    prev.next = prev.next.next;
                    return;
                }
                prev = prev.next;
            }
            System.out.println("节点不存在");
        }

首先我们得判断头结点是不是我们要删除的结点,是的话,我们就得令head指向当前head的下一个结点,如果不是,则我们定义prev从head.next开始遍历,如果遇到要删除的结点,直接让他指向prev的下下个结点就好了,因为prev是要删除结点的前一个结点,如果还没有找到,则直接返回要删除的结点不存在。

六.删除所有值为key的节点

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

依然呢,我们需要考虑要删除的结点是头结点,这是就把head指向下一个结点就好了。此时呢我们需要设置两个prev和cur,一个指向head,一个指向head.next,prev的作用呢就是相当于每次要删除结点的前一个结点,cur是作为判断当前是否是要删除结点,这要操作起来也会方便点。这是我们需要考虑要删除的结点是不是连着的,如果是连着的,就prev的next指向cur的next,然后让cur往后走继续删除结点。如果不连着,就prev往后走一步,cur也走一步判断是否为删除结点。

今天就到这里,之后会出来一些面试题中的一些单链表题。@-@

猜你喜欢

转载自blog.csdn.net/AIJXB/article/details/105166604
今日推荐