单链表

作者: 四喜汤圆 | 来源:发表于2018-09-09 16:33 被阅读6次

一、基本操作

二、编码思路

1,按照普适思路编写;2,注意判空保证程序健壮性(实际上判空也是考虑全面)

三、实现了上述基本操作的单链表

1,按照普适思路编写;2,注意判空

/**
     * 插入到单链表尾部
     * 【增】
     * @param data
     * @return
     */
    public boolean addNode(E data){
        Node newNode=new Node(data);
        // 找到最后一个节点
        Node p=head;
        while(p!=null && p.next!=null){
            p=p.next;
        }// 找到尾节点
        if(p==null){
            // 说明原来链表为空
            head=newNode;
        }else{
            // p.next==null;
            // 原来链表不为空
            p.next=newNode;
        }
        return true;
        
    }
    
    /*public boolean addNode2(E data){
        Node newNode=new Node(data);
        if(head==null){
            head=newNode;
        }else{
            // 找到最后一个节点
            Node p=head;
            while(p.next!=null){
                p=p.next;
            }
            p.next=newNode;
        }
        return true;
    }*/
    
    /**
     * 将数据插入后使得其索引为index
     * 链表的插入需要知道前一节点
     * @param index:[0,size]区间内
     * @param data
     * @return
     */
    public boolean add(int index,E data){
        if(index <0 || index>length()){
            throw new ArrayIndexOutOfBoundsException();
        }
        Node newNode=new Node(data);
        if(index==0){
            newNode.next=head;
            head=newNode;
        }else{
            // 找到第index-个节点
            Node p=node(index-1);
            newNode.next=p.next;
            p.next=newNode;
        }
        return true;
    }

1,按照普适思路编写;2,注意判空

/**
     * 删除元素值为data的元素
     * @param data
     * @return
     */
    public boolean removeElement(E e){
        if(e==null){
            Node pre=null;
            Node p=head;
            // 遍历整个链表
            while(p!=null){
                if(p.data==null){
                    // 找到这个元素了
                    if(pre!=null){
                        pre.next=p.next;
                    }else{
                        head=p.next;
                    }
                    return true;
                }else{
                    // 未找到
                    pre=p;
                    p=p.next;
                }
            }
        }else{
            Node pre=null;
            Node p=head;
            // 遍历整个链表
            while(p!=null){
                if(e.equals(p.data)){
                    // 删除
                    if(pre!=null){
                        pre.next=p.next;
                    }else{
                        head=head.next;
                    }
                    return true;
                }else{
                    // 未找到
                    pre=p;
                    p=p.next;
                }
            }
        }
        return false;
    }
    
    /**
     * 删除索引为index的元素
     * @param index
     * @return
     */
    public boolean removeForIndex(int index){
        checkElementIndex(index);
        if(index==0){
            head=head.next;
        }else{
            // 找出第index个元素,及其pre元素
            Node pre=head;
            Node p=head.next;
            for(int i=1;i<index;i++){
                pre=p;
                p=p.next;
            }
            // 跳出循环时:p指向第index个元素
            pre.next=p.next;
            
        }
        return true;
    }

注意其中找出第index节点的方法

/**
     * 修改索引值为index的元素值
     * @param index
     * @param e
     * @return
     */
    public boolean set(int index,E e){
        checkElementIndex(index);
        // 找出第index个元素
        Node p=head;
        for(int i=0;i<index;i++){
            p=p.next;
        }
        p.data=e;
        return true;
    }

/**
     * 得到索引值为index处的元素值
     * @param index
     * @return
     */
    public E get(int index){
        checkElementIndex(index);
        // 找到第index个元素
        Node p=head;
        for(int i=0;i<index;i++){
            p=p.next;
        }
        return p.data;
    }

源码

/**
 * 
* <p>Description: 单链表</p>  
* @author 杨丽金  
* @date 2018-9-9  
* @version 1.0
 */
public class MySingleList<E> {
    
    class Node{
        E data;
        Node next;
        Node(E data){
            this.data=data;
        }
    }
    
    // 链表头
    private Node head=null;
    
    /**
     * 插入到单链表尾部
     * 【增】
     * @param data
     * @return
     */
    public boolean addNode(E data){
        Node newNode=new Node(data);
        // 找到最后一个节点
        Node p=head;
        while(p!=null && p.next!=null){
            p=p.next;
        }// 找到尾节点
        if(p==null){
            // 说明原来链表为空
            head=newNode;
        }else{
            // p.next==null;
            // 原来链表不为空
            p.next=newNode;
        }
        return true;
        
    }
    
    /*public boolean addNode2(E data){
        Node newNode=new Node(data);
        if(head==null){
            head=newNode;
        }else{
            // 找到最后一个节点
            Node p=head;
            while(p.next!=null){
                p=p.next;
            }
            p.next=newNode;
        }
        return true;
    }*/
    
    /**
     * 将数据插入后使得其索引为index
     * 链表的插入需要知道前一节点
     * @param index:[0,size]区间内
     * @param data
     * @return
     */
    public boolean add(int index,E data){
        if(index <0 || index>length()){
            throw new ArrayIndexOutOfBoundsException();
        }
        Node newNode=new Node(data);
        if(index==0){
            newNode.next=head;
            head=newNode;
        }else{
            // 找到第index-个节点
            Node p=node(index-1);
            newNode.next=p.next;
            p.next=newNode;
        }
        return true;
    }
    
    /**
     * 得到第index个节点
     * @param index:[0,size-1],index从0开始
     * @return
     */
    private Node node(int index) {
        Node p=head;
        for(int i=0;i<index;i++){
            p=p.next;
        }
        return p;
    }
    
    
    /**
     * 删除元素值为data的元素
     * @param data
     * @return
     */
    public boolean removeElement(E e){
        if(e==null){
            Node pre=null;
            Node p=head;
            // 遍历整个链表
            while(p!=null){
                if(p.data==null){
                    // 找到这个元素了
                    if(pre!=null){
                        pre.next=p.next;
                    }else{
                        head=p.next;
                    }
                    return true;
                }else{
                    // 未找到
                    pre=p;
                    p=p.next;
                }
            }
        }else{
            Node pre=null;
            Node p=head;
            // 遍历整个链表
            while(p!=null){
                if(e.equals(p.data)){
                    // 删除
                    if(pre!=null){
                        pre.next=p.next;
                    }else{
                        head=head.next;
                    }
                    return true;
                }else{
                    // 未找到
                    pre=p;
                    p=p.next;
                }
            }
        }
        return false;
    }
    
    /**
     * 删除索引为index的元素
     * @param index
     * @return
     */
    public boolean removeForIndex(int index){
        checkElementIndex(index);
        if(index==0){
            head=head.next;
        }else{
            // 找出第index个元素,及其pre元素
            Node pre=head;
            Node p=head.next;
            for(int i=1;i<index;i++){
                pre=p;
                p=p.next;
            }
            // 跳出循环时:p指向第index个元素
            pre.next=p.next;
            
        }
        return true;
    }
    
    // 必须为[0,size-1]范围内
    private void checkElementIndex(int index){
        if(index <0 || index >= length()){
            throw new IndexOutOfBoundsException();
        }
    }

    /**
     * 返回链表长度
     * @return
     */
    public int length(){
        if(head==null){
            return 0;
        }
        Node p=head;
        int len=1;
        while(p.next!=null){
            p=p.next;
            len++;
        }
        return len;
    }
    
    public void print(){
        if(head==null){
            return ;
        }
        Node p=head;
        while(p!=null){
            System.out.print(p.data+",");
            p=p.next;
        }
        System.out.println();
    }
    
    /**
     * 修改索引值为index的元素值
     * @param index
     * @param e
     * @return
     */
    public boolean set(int index,E e){
        checkElementIndex(index);
        // 找出第index个元素
        Node p=head;
        for(int i=0;i<index;i++){
            p=p.next;
        }
        p.data=e;
        return true;
    }
    
    /**
     * 得到索引值为index处的元素值
     * @param index
     * @return
     */
    public E get(int index){
        checkElementIndex(index);
        // 找到第index个元素
        Node p=head;
        for(int i=0;i<index;i++){
            p=p.next;
        }
        return p.data;
    }
    
    public static void main(String[] args) {
        MySingleList<Integer> list=new MySingleList<Integer>();
        System.out.println("链表长度:"+list.length());
        list.addNode(2);
        list.addNode(3);
        list.addNode(5);
        list.addNode(-1);
        list.print();
        System.out.println("链表长度:"+list.length());
        list.add(0, 0);
        list.add(1,1);
        list.add(6,99);
        list.print();
        System.out.println("链表长度:"+list.length());
        list.removeElement(0);
        list.print();
        System.out.println("链表长度:"+list.length());
        list.removeElement(3);
        list.print();
        System.out.println("链表长度:"+list.length());
        list.removeElement(99);
        list.print();
        System.out.println("链表长度:"+list.length());
        list.removeForIndex(0);
        list.print();
        System.out.println("链表长度:"+list.length());
        list.removeForIndex(1);
        list.print();
        System.out.println("链表长度:"+list.length());
        list.removeForIndex(1);
        list.print();
        System.out.println("链表长度:"+list.length());
        list.set(0, 100);
        list.print();
        System.out.println("链表长度:"+list.length());
        System.out.println("第0个元素:"+list.get(0));
    }

}

相关文章

  • 单链表 C++

    单链表 C++ 题目 1、创建单链表2、初始化单链表3、释放单链表4、获取单链表中元素的数量5、输出单链表中的所有...

  • 线性表:顺序表和链表

    顺序表(数组)优缺点 链表优点 单链表使用 单链表结构 单链表初始化 单链表初始化 单链表建立: 头插法 尾插法 ...

  • 单向链表算法

    单向链表 反转单向链表 单链表查找倒数第k个节点 单链表递归倒序打印 单链表排序 单链表删除重复节点

  • 链表基本操作

    1、删除单链表节点 2、插入单链表结点 单链表具体实现

  • 25_静态单链表的实现

    关键词: 单链表的一个缺点、静态单链表设计思路、静态单链表的继承层次结构、静态单链表的实现思路、静态单链表的实现 ...

  • 线性表的链式存储-单链表

    单链表操作 [x] 单链表的创建(尾插法、头插法) [x] 单链表的查找操作 [x] 单链表的删除操作 [x] 单...

  • Algorithm小白入门 -- 单链表

    单链表递归反转链表k个一组反转链表回文链表 1. 递归反转链表 单链表节点的结构如下: 1.1 递归反转整个单链表...

  • 单链表反转

    单链表 单链表反转 递归方法

  • JavaScript数据结构2——单链表

    以下的代码包括了以下几部分 单链表初始化 单链表的插入 单链表的删除 单链表的创建(头插法) 单链表的创建(尾插法...

  • 链表

    链表:通过“指针”将零散的内存块联系起来。常见链表结构:单链表、循环链表和双链表。 单链表 对比数组学习单链表 循...

网友评论

      本文标题:单链表

      本文链接:https://www.haomeiwen.com/subject/ryhdgftx.html