数据结构-单链表

文章目录

简介

单链表在逻辑上是线性的,在存储结构是却不是连续的,单链表同其名字一样为单向,单链表在数据结构中也算一种比较基础简单的结构

Java 实现

逻辑思路

单链表只有一个方向,单链表逻辑上是线性的,链表中靠一个个的结点连接起来的,链表中存有数据和下一个结点的地址,单链表快在插入和删除上,对于从尾部添加和查找第几个元素会比较慢,对于插入的实现,将新结点指向单链表中的一个结点,然后断开链表中的这个结点和前一个结点的连接,让前一个结点指向插入的结点即可,对于删除的实现是直接让单链表中的一个结点指向下下个结点即可,新增结点的实现是遍历到最后一个再新增,对于查找的实现是直接遍历去寻找

算法图解

单链表

代码实现

// 单链表结点
class Node {
    int data;
    Node next = null;
}

// 单链表
public class SinglyLinkedList {
    // 头结点
    private Node head;

    // 初始化
    public SinglyLinkedList() {
        head = null;
    }

    // 头插法创建单链表(倒序)
    public Node createFromHead(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            Node node = new Node();
            node.data = arr[i];
            node.next = head.next;
            head.next = node;
        }
        return head;
    }
    // 尾插法创建单链表(顺序)
    public Node createFromTail(int[] arr) {
        Node h = head;
        for (int i = 0; i < arr.length; i++) {
            Node node = new Node()
            node.data = arr[i];
            node.next = null;
            h.next = node;
            h = node;
        }
        return head;
    }

    // 单链表新增数据
    public Node add(Node n) {
        Node h;
        for (h = head;  h.next != null; h = h.next);
        h.next = n;
        return head;
    }

    // 查找数据
    public int search(int num) throws Exception {
        int k = 0;
        for (Node h = head; h.next != null; k++,h = h.next);
        if (num < 1 || num > k)
            throw new Exception("数字超过范围!");
        Node h = head;
        for (int i = 1; i <= num; i++,h = h.next);
        return h.data;
    }

    // 插入数据,其他数据后移
    public Node insert(int num, Node n) throws Exception {
        int k = 0;
        for (Node h = head; h.next != null; k++,h = h.next);
        if (num < 1 || num > k)
            throw new Exception("数字超过范围!");
        Node h = head;
        for (int i = 1; i < num; i++,h = h.next);
        n.next = h.next;
        h.next = n;
        return head;
    }

    // 删除数据
    public int delete(int num) throws Exception {
        int k = 0;
        for (Node h = head; h.next != null; k++,h = h.next);
        if (num < 1 || num > k)
            throw new Exception("数字超过范围!");
        Node h = head;
        for (int i = 1; i < num; i++,h = h.next);
        int e = (h.next).data;
        h.next = (h.next).next;
        return e;
    }
}
下面是使用C语言实现的单链表原地逆转的代码: ```c #include <stdio.h> #include <stdlib.h> struct Node { int data; struct Node* next; }; void reverseList(struct Node** head) { struct Node* prev = NULL; struct Node* current = *head; struct Node* next = NULL; while (current != NULL) { next = current->next; current->next = prev; prev = current; current = next; } *head = prev; } void printList(struct Node* head) { while (head != NULL) { printf("%d ", head->data); head = head->next; } printf("\n"); } void push(struct Node** headRef, int newData) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = newData; newNode->next = *headRef; *headRef = newNode; } int main() { struct Node* head = NULL; push(&head, 3); push(&head, 2); push(&head, 1); printf("Original list: "); printList(head); reverseList(&head); printf("Reversed list: "); printList(head); return 0; } ``` 在上述代码中,我们首先定义了一个 `Node` 结构体来表示单链表中的每个节点,包括节点的值指向下一个节点的指针。然后我们定义了 `reverseList` 函数来实现原地逆转单链表的功能。该函数接受一个指向指针的指针 `head`,这是因为我们需要通过指针来修改单链表的头节点,所以我们传递指向指针的指针。在函数内部,我们使用三个指针 `prev`、`current` `next` 来依次遍历单链表,并将每个节点的指针指向前一个节点,从而实现原地逆转单链表的目的。 最后,我们定义了一个 `push` 函数来添加新节点到单链表的头部,并定义了 `printList` 函数来打印单链表中所有节点的值。在 `main` 函数中,我们创建了一个包含三个节点的单链表,并调用 `reverseList` 函数来原地逆转该单链表,最后打印出原始逆转后的单链表
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

abcnull

您的打赏是我创作的动力之一

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值