单链表Singly Linked List之JAVA实现

单链表算是一种很基础的数据结构了,下图是单链表的一般图示。

这里写图片描述

上学那会儿没怎么实际应用,对其功能和实现都是一知半解。
下面是以java来实现单链表的一些基本操作。

首先是结点类,每个结点包括数据域指针域,数据域存放数据,指针域指向下个结点,也就是存放下个结点的地址。

/**
 * 结点类
 */
class Node {
    private String data; // 数据域
    private Node next; // 指针域,指向下个结点

    public Node(String data, Node next) {
        super();
        this.data = data;
        this.next = next;
    }

    public Node(String data) {
        super();
        this.data = data;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    public void destroy() {
        this.data = null;
        this.next = null;
    }
}

接着是单链表类

/**
 * 单链表类
 */
class List {
    private Node head; // 头结点
    public int length; // 长度

    public List() {
        init();
    }

    private void init() {
        head = new Node("head", null);
    }

    public Node getHead() {
        return head;
    }

    public void setHead(Node head) {
        this.head = head;
    }

    /**
     * 头插法---插入结点
     * 
     * @param node
     */
    public boolean insertToHead(Node node) {
        Node n = head.getNext(); // 得到第一个结点
        if (n == null) { // 如果是空的话,直接插入头结点之后
            head.setNext(node);
        } else {
            node.setNext(n);
            head.setNext(node);
        }
        length++;
        return true;
    }

    /**
     * 尾插法---插入结点
     * @param node
     * @return
     */
    public boolean insertToTail(Node node) {
        Node n = head.getNext();
        if(n == null) {
            insertToHead(node);
            return true;
        }

        while(true) {
            if(n.getNext() == null){
                break;
            }
            n = n.getNext();
        }

        // insert
        n.setNext(node);
        length++;
        return true;
    }

    /**
     * 插入结点到指定位置(从0开始)
     * 
     * @param index
     */
    public boolean insertToIndex(int index, Node p) {
        if (index < 0 || index > length) {
            System.out.println("超出范围");
            return false;
        }

        if (index == 0) { // 插入到头结点之后
            insertToHead(p);
        } else if(index ==length) {
            insertToTail(p);
        } else {
            Node node = head;
            for (int i = -1; i < length - 1; i++) { // -1  to 3
                if (i + 1 == index) {
                    p.setNext(node.getNext());
                    node.setNext(p);
                    length++;
                    break;
                }
                node = node.getNext();
            }
        }

        return true;
    }

    /**
     * 结点编号是否在范围之内 (从0开始)
     * 
     * @param index
     * @return
     */
    public boolean findNode(int index) {
        if (index >= length || index < 0) {
            System.out.println("结点超出范围");
            return false;
        }
        return true;
    }

    /**
     * 删除指定编号的结点(从0开始)
     * 
     * @param index
     * @return
     */
    public boolean deleteNode(int index) {
        if (!findNode(index)) {
            return false;
        }

        Node node = head;
        // i从-1 到 length-2,判断其后的结点编号是否是待删除的结点
        for (int i = -1; i < length - 1; i++) {
            if (i + 1 == index) {
                // 如果其后的结点正是要删除的,赋值给p
                Node p = node.getNext();
                // 跳过此结点p
                node.setNext(p.getNext());
                // 销毁结点p
                p.destroy();
            }
            node = node.getNext();
        }
        length--;
        return true;
    }

    /**
     * 根据数据域删除结点
     * 
     * @param data
     * @return
     */
    public boolean deleteNode(String data) {
        boolean isExist = false;
        Node n = head;
        while (n != null) {
            if (n.getNext() != null && data.equals(n.getNext().getData())) {
                isExist = true;
                //
                n.setNext(n.getNext().getNext());
                length--;
                break;
            }
            n = n.getNext();
        }
        System.out.print(isExist ? "" : String
                .format("数据为\"%s\"的结点不存在\n", data));
        return isExist;
    }

    /**
     * 输出整个单链表
     */
    public void printList() {
        Node n = head;
        while (n != null) {
            System.out.print(n.getData());
            n = n.getNext();
            System.out.print(n == null ? "" : "-->");
        }
        System.out.println("\n长度为:" + length);
    }
}

代码中主要实现了单链表的插入(头插法,尾插法和指定位置插入),删除(根据数据和位置的删除)。

下面是头插法的算法图:
这里写图片描述

接下来是删除的图:
这里写图片描述

最后,附上测试类

/**
 * 测试类
 */
public class SinglyLinkedListDemo {
    public static void main(String[] args) {
        List list = new List();

        // 头插法插入6个结点
        list.insertToHead(new Node("1"));
        list.insertToHead(new Node("2"));
        list.insertToHead(new Node("3"));
        list.insertToHead(new Node("4"));
        list.insertToHead(new Node("5"));
        list.insertToHead(new Node("6"));
        // 输出整个单链表
        list.printList();
        System.out.println("****************************");

        // 头插法插入"99"
        System.out.println("头插法插入99");
        list.insertToHead(new Node("99"));
        list.printList();
        System.out.println("****************************");

        // 尾插法插入"77"
        System.out.println("尾插法插入77");
        list.insertToTail(new Node("77"));
        list.printList();
        System.out.println("****************************");

        // 删除编号3的结点,从0开始
        System.out.println("删除第三个结点");
        list.deleteNode(3);
        // 输出整个单链表
        list.printList();
        System.out.println("****************************");

        System.out.println("删除数据为\"111\"的结点");
        list.deleteNode("111");
        list.printList();
        System.out.println("****************************");

        // 在目标索引位置插入结点,从0开始
        System.out.println("在位置3插入数据为\"88\"的结点");
        list.insertToIndex(3, new Node("88"));
        // 输出整个单链表
        list.printList();
    }

最后是测试结果

head-->6-->5-->4-->3-->2-->1
长度为:6
****************************
头插法插入99
head-->99-->6-->5-->4-->3-->2-->1
长度为:7
****************************
尾插法插入77
head-->99-->6-->5-->4-->3-->2-->1-->77
长度为:8
****************************
删除第三个结点
head-->99-->6-->5-->3-->2-->1-->77
长度为:7
****************************
删除数据为"111"的结点
数据为"111"的结点不存在
head-->99-->6-->5-->3-->2-->1-->77
长度为:7
****************************
在位置3插入数据为"88"的结点
head-->99-->6-->5-->88-->3-->2-->1-->77
长度为:8
在已有的单链表结构基础上,实现链表的分段功能通常意味着我们需要将一个大链表分割成几个较小的、相互独立的部分,每个部分形成一个新的链表。这个过程可能会基于特定条件,比如节点值的范围、特定的索引位置或者是用户给定的长度等。下面是一个简单的Python示例,展示如何通过遍历链表并维护新的链表头节点来实现这一功能: ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def segment_list(head, segment_size): # 如果链表为空或segment_size为0,直接返回None if not head or segment_size == 0: return None dummy = ListNode(0) # 创建虚拟头节点 dummy.next = head current = dummy segment_head = ListNode() # 存储当前段的头部 for _ in range(segment_size): # 分割前几个元素 if current.next is None: break current = current.next else: segment_head.next = dummy.next # 将第一个段连接到新链表 dummy.next = None # 更新原链表的起点 while current: # 拷贝当前段到新的链表,然后移动指针 new_segment_head = ListNode(current.val) new_segment_head.next = segment_head.next segment_head.next = new_segment_head for _ in range(segment_size - 1): # 继续处理下一个段,直到无法再分 if current.next is None: break current = current.next else: # 如果还有剩余节点,更新当前段的结尾,并准备下一段 segment_head.next = current.next current.next = None return segment_head.next # 返回新的链表的头部 # 使用示例 head = ListNode(1, ListNode(2, ListNode(3, ListNode(4)))) result = segment_list(head, 2) # 将链表分为每两个节点一组 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值