数据结构—单链表详解

1. 链表

  • 链表:逻辑上是线性关系,物理存储上不一定是线性关系。
  • 可以理解为链表的一个结点由两部分组成:
  1. 存放的数据
  2. 找到下一个结点的线索。
  • 引用{value,next}

数据结构—单链表详解_第1张图片简单理解:

@0xFF {1,@0xCC}
@0xCC {2,@0x99}
@0x99 {3,@0x33}
@0x33 {4,@0xAA}
@0xAA{5,NULL}

Node p1 = @0xFF
Node p2 = @0xAA
Node p3 = @0xCC

p1.next = p2;  //@0xFF {1,@0xAA}
p2 = p1.next;  //@0xCC
p1.next.next = p2;  //@0xCC {2,@0xAA}
p1.next.next = p3.next.next; //@0xCC {2,@0x33}
p1 = p2;  //@0xAA



2. 链表的头插,尾插,头删,尾删

2.1 头插

思想:

  • 原链表为空时:
    则新插入的结点node构成新的链表,node此时也是头结点;
    node = head
  • 原链表不为空时:

(1)在链表最前面插入一个新的结点node,要想把新结点与原链表连接起来,需要 字:node.next = head(head为链表的头结点);

(2)使node成为头结点:字:head = node;

  • 可以将两种情况按同链表不为空处理。

2.2 尾插

思想:

  • 链表为空时
    直接插入:head = node;
  • 链表不为空时:
  • 想要在最后一个结点后面插入一个新的结点node,则首先应找到最后一个结点。
    (1)定义一个方法getLast(),用来找最后一个结点并返回最后一个结点;
    (2)在getLast()方法中定义一个临时的节点变量cur;cur = head;

    (3)在链表种进行循环查找,要想找到最后一个结点,则cur.next = null;
    所以循环条件为:cur.next != null;

    (4)找到最后一个结点并返回。
  • 找到最后一个结点last后,把原链表与新插入的结点连接起来, last.next = node;

2.3 头删

思想:

  • 原链表为空时
    则抛出异常。

  • 原链表不为空时:

  • 删除头结点,则第二个结点成为新的头结点。
    head = head.next

2.4 尾删

思想:

  • 原链表为空
    抛出异常。

  • 原链表不为空

  1. 要想删除最后一个结点,首先需要找到倒数第二个结点。倒数第二个结点的next=null 时,即为删除最后一个结点。
    (1)定义一个找倒数第二个结点的方法getLastLast(),找到并返回倒数第二个结点。
    (2)在getLastLLast()方法中定义一个临时的节点变量cur;
    cur = head;

    注意:此时存在两种情况:只有1个结点 ,或者大于一个结点

    (3)原链表只有一个结点时,
    cur.next = null;
    此时只需要删除头结点:即head = null;

    (4)原链表中大于一个结点时:
    在链表种进行循环查找,要想找到倒数第二个结点,则cur.next .next= null;
    所以循环条件为:cur.next .next != null;

    (4)找到倒数第二个结点并返回
  2. 找到倒数第二个结点lastLast以后,令lastLast.next = null
    即可删除最后一个结点

2.5 遍历

思想:

  • 遍历主要是循环条件的控制。
  • 遍历是遍历所有结点,即使最后一个 结点的next 为 null,也要遍历一遍。
  • 所以循环条件为 node != null;

2. 链表插入,删除,遍历的具体代码

package www.bit.java;

/**
 * author:kelly_fanfan
 */
public class MyLinkedList {


    //内部类
    //表示链表中的一个结点
    public class Node{
        public int value;//保存的数据
        public Node next;//下一个结点的线索

        Node(int v){
            this.value = v;
            this.next = null;
        }
    }

    //头结点,保存链表中第一个结点的引用
    //如果一个结点都没有,head=null
    private Node head;

    MyLinkedList(){

        this.head = null;
    }

    //1.头插,插入的是一个数据
    //头插结点为空时 this.head = node
    void pushFront(int item) {
        Node node = new Node(item);
        node.next = this.head;
        this.head = node;
    }

    //2. 尾插
    void pushBack(int item){
        Node node = new Node(item);
        if(this.head == null){
            this.head = node;
        }else{
            Node last = getLast();
            last.next = node;
        }
    }
    //获得最后一个结点
    private Node getLast() {
        Node cur = this.head;
        while (cur.next != null) {
            cur = cur.next;
        }
        return cur;
    }

    //3.头删
    void popFront(){
        if(this.head == null){
            throw new Error();
        }else{
            this.head = this.head.next;
        }
    }

    //4. 尾删
    void popBack(){
        if(this.head == null){
            throw new Error();
        }else{
            if(this.head.next == null){
                this.head = null;
            }else{
                Node lastLast = getLastLast();
                lastLast.next = null;
            }
        }
    }
        //找到倒数第二个结点
        private Node getLastLast(){
            Node cur = this.head;
            while(cur.next.next != null){
                cur = cur.next;
            }
            return cur;
        }

        //5. 遍历
        public void disPlay(){
            Node cur = this.head;
            while(cur != null){
                System.out.format("%d-->",cur.value);
                cur = cur.next;
            }
        }

}

你可能感兴趣的:(数据结构)