数据结构之链表

单向链表反转

复制代码
// 通过递归的方式找到最后的节点
// 指向前面的节点,这样可以不破坏之前的指向回溯回去
public static Node reverseLinkedNode(Node head) {
    if (head == null || head.next == null) {
        // 返回最后的节点
        return head;
    }
    Node nextNode = reverseLinkedNode(head.next);
    nextNode.next = head;
    head.next = null;
    return head;
}

// 直接反转

复制代码
public static Node reverse(Node head) {
    Node next = null;
    Node pre = null;
    while (head != null) {
        next = head.next;
        head.next = pre;
        pre = head;
        head = next;
    }
    return pre;
}

题目中nextNode永远会返回head的下一个节点

双向链表反转

用两个node记录下来当前节点的前后环境

复制代码
public static DDNode reverse(DDNode head) {
    DDNode pre = null;
    DDNode next = null;
    while(head != null) {
        next = head.next;
        head.next = pre;
        head.pre = next;
        pre = head;
        head = next;
    }
    return pre;
}

打印两个有序列表的公共部分

主要思想和归并排序有些像,因为是有序的链表

所以同时从头开始对比大小,小的一方就next,直到相等后同时记录后,next

有任何一方遍历到结束就返回结果

复制代码
public static List<Integer> getOverlap(Node n1, Node n22) {
    if (n1 == null || n22 == null) {
        return null;
    }
    List<Integer> result = new ArrayList<>();
    int v1, v2;
    while(n1 != null && n22 != null) {
        v1 = n1.value;
        v2 = n22.value;
        if (v1 == v2) {
            result.add(v1);
            n1 = n1.next;
            n22 = n22.next;
        } else if (v1 > v2) {
            n22 = n22.next;
        } else {
            n1 = n1.next;
        }
    }
    return result;
}

判断是不是回文链表

回文链表:1->2->3->2->1

思路:用栈记录后出站和原来列表对比,因为栈是逆序,如果逆序和链表仍然相等

则是回文链表

复制代码
public static boolean isMirror(Node head) {
    Stack<Node> stack = new Stack<>();
    Node node = head;
    while (head != null) {
        stack.push(head);
        head = head.next;
    }
    boolean result = true;
    while (node != null) {
        if (node.value != stack.pop().value) {
            System.out.println(node.value);
            result = false;
            return result;
        }
        node = node.next;
    }
    return result;
}

链表排序

把链表转换为数组,然后进行快速排序,再转换为链表

复制代码
public static Node nodeSort(Node head) {
    List<Node> nodes = new ArrayList<>();
    while (head != null) {
        nodes.add(head);
        head = head.next;
    }
    if (nodes.size() <= 1) {
        return head;
    }
    return qs(nodes, 0, nodes.size() - 1);
}
// 返回头节点
public static Node qs(List<Node> nodes, int low, int high) {
    if (high <= low) {
        return null;
    }
    int partition = partition(nodes, low, high);
    qs(nodes, low, partition - 1);
    qs(nodes, partition + 1, high);
    for(int i = 0; i< nodes.size();i++) {
        if (i + 1 < nodes.size()) {
            nodes.get(i).next = nodes.get(i + 1);
        } else {
            nodes.get(i).next = null;
        }
    }
    return nodes.get(0);
}
public static int partition(List<Node> nodes, int low, int high) {
    Node standard = nodes.get(low);
    while (low < high) {
        while (low < high && nodes.get(high).value >= standard.value) {
            high --;
        }
        swap(nodes, low, high);
        while (low < high && nodes.get(low).value <= standard.value) {
            low ++;
        }
        swap(nodes, high, low);
    }
    nodes.set(low, standard);
    return low;
}

判断链表是否有环,并返回入环节点

一. 使用HashSet存储如果存在重复存储元素则有环

复制代码
public static Node getCycleNode(Node head) {
    HashSet<Node> hashSet = new HashSet<>();
    while (head != null) {
        if (!hashSet.contains(head)) {
            hashSet.add(head);
        } else {
            return head;
        }
        head = head.next;
    }
    return null;
}

二. 使用快慢指针

快指针一次走两个,慢指针一次一步,

当快慢指针相遇时说明有环,此时让快指针回到原点,再相遇时就是入环节点

复制代码
public static Node getCycleNode2(Node head) {
    if (head == null || head.next == null || head.next.next == null) {
        return null;
    }
    Node quick = head.next;
    Node slow = head.next.next;
    while (quick != slow) {
        quick = quick.next;
        slow = slow.next.next;
    }
    quick = head;
    while (quick != slow) {
        quick = quick.next;
        slow = slow.next;
    }
    return quick;
}
相关推荐
2401_8414956443 分钟前
【Python高级编程】单词统计与查找分析工具
数据结构·python·算法·gui·排序·单词统计·查找
-To be number.wan1 小时前
【数据结构真题解析】哈希表高级挑战:懒惰删除、探测链断裂与查找正确性陷阱
数据结构·算法·哈希算法
Qhumaing2 小时前
数据结构——例子求算法时间复杂度&&空间复杂度
数据结构·算法
鱼跃鹰飞2 小时前
Leetcode1027:最长等差数列
java·数据结构·算法
Stardep2 小时前
算法入门20——二分查找算法——搜索插入位置
数据结构·算法·leetcode
老鼠只爱大米2 小时前
LeetCode经典算法面试题 #141:环形链表(快慢指针、标记节点等多种方法详细解析)
算法·leetcode·链表·快慢指针·floyd算法·环形链表
浅念-3 小时前
C语言——单链表
c语言·开发语言·数据结构·经验分享·笔记·算法·leetcode
夏乌_Wx3 小时前
练题100天——DAY40:合并两个有序链表
数据结构
hans汉斯4 小时前
建模与仿真|基于GWO-BP的晶圆机器人大臂疲劳寿命研究
大数据·数据结构·算法·yolo·机器人·云计算·汉斯出版社
IT陈图图4 小时前
Flutter × OpenHarmony 文件管家:数据结构设计与实现
数据结构·flutter