栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【恋上数据结构】 链表(手写LinkedList+练习)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【恋上数据结构】 链表(手写LinkedList+练习)

Gitee地址

文章目录
    • linkedList(链表)
      • 节点类(Node)
      • 接口设计
      • 手写linkedList
      • 练习
        • 1.删除链表中的节点
        • 2.反转链表

linkedList(链表)

动态数组有个明显的缺点:
动态数组可能会造成内存空间的大量浪费

能否用到多少内存就申请多少内存呢?链表就可以办到这一点,链表是一种链式存储的线性表,所有元素的内存地址不一定是连续的。

节点类(Node)
    private static class Node{
        
        E element;

        
        Node next;

        
        public Node(E element, Node next) {
            this.element = element;
            this.next = next;
        }
    }
接口设计

由于链表与动态数组可以抽象出共同的方法,所以我们可以实现接口来优化代码。

抽象接口之后创建对象的方法变为:

List list = new linkedList();

接口设计为:

package 链式结构;

public interface List {

	static final int ELEMENT_NOT_FOUND = -1;
	
	void clear();

	
	int size();

	
	boolean isEmpty();

	
	boolean contains(E element);

	
	void add(E element);

	
	E get(int index);

	
	E set(int index, E element);

	
	void add(int index, E element);

	
	E remove(int index);

	
	int indexOf(E element);
}
手写linkedList

linkedList

package 链式结构.linkedlist;

import org.w3c.dom.Node;
import 链式结构.List;



public class linkedList implements List {

    
    
    private int size;
    
    private Node first;



    
    
    public linkedList(){
    }


    

    
    @Override
    public void clear() {
        size = 0;
        first = null;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean contains(Object element) {
        return indexOf(element) != ELEMENT_NOT_FOUND;
    }

    @Override
    public void add(Object element) {
        add(size,element);
    }

    @Override
    public Object get(int index) {
        Node node = node(index);
        return node.element;
    }

    @Override
    public Object set(int index, Object element) {
        Node node = node(index);
        E old = node.element;;
        node.element = (E) element;
        return old;
    }

    
    @Override
    public void add(int index, Object element) {
        if (index == 0){
            first = new Node<>(element, first);
        }else {
            //前一个节点
            Node preNode = node(index - 1);
            //新节点
            Node node = (Node) new Node(element, preNode.next);
            //前一个节点指向新的
            preNode.next = node;
        }
        //长度增加
        size++;
    }
    private Node node(int index){
        rangeCheck(index);
        Node node = first;
        for (int i = 0; i < index; i++) {
            node = node.next;
        }
        return node;
    }

    
    @Override
    public Object remove(int index) {
        rangeCheck(index);
        Node node = first;
        if (index == 0){
         first = first.next;
        }else {
            Node prevNode = node(index - 1);
            prevNode.next = prevNode.next.next;
        }
        size--;
        return node.element;
    }

    @Override
    public int indexOf(Object element) {
        if (element == null){
            Node node = first;
            for (int i = 0; i < size; i++) {
                if (node.element == null){return i;}
                node = node.next;
            }
        }else {
            Node node = first;
            for (int i = 0; i < size; i++){
                if (element.equals(node.element)){return i;}
                node = node.next;
            }
        }
        return ELEMENT_NOT_FOUND;
    }

    @Override
    public String toString(){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("size=").append(size).append(",[");
        Node node = first;
        for (int i = 0; i < size; i++) {
            if(i != 0){
                stringBuilder.append(",");
            }
            stringBuilder.append(node.element);
            node = node.next;
        }
        stringBuilder.append("]");
        return stringBuilder.toString();
    }

    

    
    private void outOfBounds(int index){
        throw new IndexOutOfBoundsException("Index"+index+",Size:"+size);
    }
    
    private void rangeCheck(int index){
        if (index < 0 || index >= size){
            outOfBounds(index);
        }
    }
    
    private void rangeCheckForAdd(int index){
        if (index < 0 || index > size){
            outOfBounds(index);
        }
    }


    

    
    private static class Node{
        
        E element;

        
        Node next;

        
        public Node(E element, Node next) {
            this.element = element;
            this.next = next;
        }
    }

}
练习 1.删除链表中的节点

分析:

当前节点的值 = .next的值

当前节点的next= .next.next;

class Solution {
    public void deleteNode(ListNode node) {
        node.val = node.next.val;
        node.next = node.next.next;
    }
}
2.反转链表

递归解法

class Solution {
    public ListNode reverseList(ListNode head) {
        //返回条件
        if(head == null || head.next == null){return head;}
        
        ListNode newHead = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }
}

迭代法

class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null){return head;}
        ListNode newHead = null;
        while(head != null){
            ListNode tmp = head.next;
            head.next = newHead;
            newHead = head;
            head = tmp;
        }
        return newHead;
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/680518.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号