链表常见算法

1. 奇偶链表

给定一个单链表,把所有的奇数结点偶数结点分别排在一起,重新链成一个新链表。

注意:不是操作链表中的值。

1->2->3->4,转换成1->3->2->4

解题思路:odd为奇数节点,even为偶数节点,循环遍历,当偶数节点为空时,循环结束。

public static Node oddEvenNode(Node head) {
    //如果只有一个节点
    if(head == null || head.next == null) {
        return head;
    }
    //奇数节点
    Node odd = head;
    //偶数节点
    Node even = head.next;
    //偶数节点的头
    Node eHead = even;
    while(even!=null && even.next!=null) {

        odd.next = even.next;
        odd = odd.next;

        even.next = odd.next;
        even = even.next;
    }
    //将偶数节点的头拼接到奇数节点后面
    odd.next = eHead;

    return head;
}

2. 链表逆置

1->2->3,逆置为3->2->1

我觉得最好理解的是三指针法

public static Node inversion(Node head) {

    //上一节点
    Node pre = null;
    //当前节点
    Node current = head;
    //下一节点
    Node next = null;
    while (current != null) {
        next = current.next;
        //头插
        current.next = pre;
        //上一节点变成当前节点
        pre = current;
        //当前节点变更下一节点
        current = next;
    }
    return pre;
}

3. 环型链表判断

解题思路:使用快慢指针,如果两个指针相遇,则有环。

public static Boolean cycle(Node head) {
    if(head == null || head.next == null) {
        return false;
    }
    //慢指针
    Node slow = head;
    //快指针
    Node fast = head.next;

    while (slow != null && fast.next != null) {
        if(slow.value == fast.value) {
            return true;
        }
        //慢指针走一步
        slow = slow.next;
        //快指针走两步
        fast = fast.next.next;
    }
    return false;
}

4. 两个链表的交点

C1为两个链表的交点

解题思路,循环遍历两个链表的长度,算出两个链表长度的差(gap),让长的链表先走gap步,然后再一起走,如果两个节点的值相等,就是交点。

public static String intersection(Entry node1, Entry node2) {
    if(node1 == null || node2 == null) {
        return null;
    }
    //计算node1的长度
    int node1Length = 1;
    Entry temp = node1;
    while(temp.next != null) {
        node1Length++;
        temp = temp.next;
    }

    //计算node2的长度
    int node2Length = 1;
    temp = node2;
    while(temp.next != null) {
        node2Length++;
        temp = temp.next;
    }

    System.out.println(node1Length);
    System.out.println(node2Length);

    //两个链接长度的差
    int gap = Math.abs(node1Length - node2Length);

    Entry longNode = node1;
    Entry shortNode = node2;
    if(node1Length < node2Length) {
        longNode = node2;
        shortNode = node1;
    }
    //长链表先走gap步
    if(gap > 0) {
        while (gap > 0) {
            longNode = longNode.next;
            gap--;
        }
    }
    //再一起走
    while (longNode!=null && shortNode!=null) {
        if(longNode.value == shortNode.value) {
            return longNode.value;
        }
        longNode = longNode.next;
        shortNode = shortNode.next;
    }
    return null;
}

5. 获取链表的中间节点

解题思路:使用快慢指针,定义两个从头开始的指针,一个一次走一步,另一个一次走两步,也称为快慢指针。当快指针走到空或者快指针的下下个节点为空时就会惊奇的发现慢指针的正好处在中间节点处。

public static int centerNode(Node head) {
    Node slow = head;
    Node fast = head;

    while(fast!=null && fast.next!=null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    return slow.value;
}

6. 两个顺序链表合并

public static Node mergeNode(Node node1, Node node2) {
    Node p = new Node();
    Node current = p;
    while(node1!=null && node2!=null) {

        if (node1.value > node2.value) {
            current.next = node2;
            node2 = node2.next;
        } else {
            current.next = node1;
            node1 = node1.next;
        }
        current = current.next;
    }
    if(node1 != null) {
        current.next = node1;
    }
    if(node2 != null) {
        current.next = node2;
    }
    return p.next;
}

7. 返回倒数第K个节点

解题思路:

* 1.我们先定义一个慢指针slow和一个快指针fast;
* 2.我们先让快指针提前走K位,然后两个指针同时向后走,在走的期间两指针之间始终保持K位
* 3.当fast指针走完整个链表的时候,slow指针所在的节点里面的内容就是倒数第K个节点的值
public static Node lastIn(Node head, int k) {
    Node fast = head;
    Node slow = head;
    while (k > 0) {
        if(fast == null) {
            return null;
        }
        fast = fast.next;
        k--;
    }

    while (fast != null) {
        fast = fast.next;
        slow = slow.next;
    }
    return slow;
}

8. 回文链表

1->2->3->2->1

1->2->3->3->2->1

这种就是回文链表

public static Boolean huiwen(Node head) {
    //如果只有一个节点
    if(head==null || head.next == null) {
        return true;
    }
    //只有两个节点
    if(head.next.next == null) {
        if(head.value == head.next.value) {
            return true;
        } else {
            return false;
        }
    }
    //快慢指针
    Node slow = head;
    Node fast = head;
    while (fast.next != null && fast.next.next != null) {
        slow = slow.next;
        fast = fast.next.next;
    }
    //反转fast
    Node p = slow.next;

    //pre为逆置后的链表
    Node pre = null;
    Node current = p;
    Node next = null;
    while (current != null) {
        next = current.next;
        current.next = pre;

        pre = current;
        current = next;
    }

    //head开始,与逆置后的链表比较
     while (pre!=null && pre.next!=null) {
         if (pre.value != head.value) {
             return false;
         }
         pre = pre.next;
         head = head.next;
     }

    return true;
}

 vpn链接,13元一月

https://a.500ml.business/auth/register?code=jClQ

链表是一种常见的数据结构,常用于实现动态数组,它的每个节点包含一个值和指向下一个节点的指针。链表中的算法通常涉及到插入、删除、查找等操作。以下是一些常见链表算法示例及其简单说明: 1. **单链表** - 搜索元素(时间复杂度O(n)): ```python class Node: def __init__(self, data=None): self.data = data self.next = None def search_list(head, target): current = head while current is not None: if current.data == target: return True current = current.next return False # 示例: head = Node(1) head.next = Node(2) head.next.next = Node(3) print(search_list(head, 2)) # 输出:True ``` 2. **反转链表** (递归或迭代法,时间复杂度O(n)或O(n/2)): ```python def reverse_list_recursively(head): if head is None or head.next is None: return head rest = reverse_list_recursively(head.next) head.next.next = head head.next = None return rest def reverse_list_iteratively(head): prev, curr = None, head while curr is not None: next_temp = curr.next curr.next = prev prev = curr curr = next_temp return prev # 示例: head = Node(1, Node(2, Node(3))) reversed_head = reverse_list_iteratively(head) ``` 3. **合并两个有序链表** (时间复杂度O(m+n),其中m和n分别是两个链表的长度): ```python def merge_sorted_lists(l1, l2): dummy = Node(0) # 创建虚拟头节点 current = dummy while l1 and l2: if l1.data <= l2.data: current.next = l1 l1 = l1.next else: current.next = l2 l2 = l2.next current = current.next current.next = l1 if l1 is not None else l2 return dummy.next # 示例: l1 = Node(1, Node(3)) l2 = Node(2, Node(4)) merged_head = merge_sorted_lists(l1, l2) ``` 这些例子展示了链表的一些基础操作,实际的运行结果取决于链表的具体状态。如果你有特定的问题,比如遇到了某个算法实现上的困难,或者想了解其他类型的链表问题,请告诉我具体的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值