算法的合并链表,双指针删除链表

        总结

                在一些问题上本人并没有去运行(返回的是Node类型的),不过与返回值类型无关,无论是方法的调用和传递参数都是可以的(本类的话,非本类的话就static)。

                当然也有其他的问题像寻找公共子节点和回文序列的问题,都有涉及栈(以及其他的问题)的知识,就不在此发表了。

合并链表问题

问题一 合并两个有序列表

逻辑:创建一个新链表(娅节点起始点),两个链表循环连接这个新建的链表(有序,判断大小),直到有一个为空的时候,另一个链表直接连接到新链表。

//合并两个有序列表
public Node mergeTwoLists(Node list1, Node list2) {
    //设置一个哑节点
    Node node = new Node(0);
    Node current = node;

    //循环节点直到某个链表为null时,跳出循环
    while (list1 != null && list2 != null) {
        if (list1.data <= list2.data) {
            current.next = list1;
            list1 = list1.next;
        } else {
            current.next = list2;
            list2 = list2.next;
        }

        current = current.next;
    }
    //把剩余的节点直接进行链接上
    current.next = list1 != null ? list1 : list2;
    return node.next;
}

问题二 合并k个链表

逻辑:就是利用循环和两链表合并,每一次产生的新链表都参与两个链表的合并。(表述不是太清除上代码)

//合并k个链表
public Node mergeLists(Node[] lists){
    //设置一个空链表
    Node res = null;
    //用增强for循环,调用两两链表连接的方法。
    for (Node list : lists) {
       res = mergeTwoLists(res, list);
    }
    return res;
}
双指针问题

问题一 寻找中间节点(懒,还是直接粘贴过来)

//双指针专题,就是同时有两个指针来进行操作。
//问题yi寻找中间节点。奇数时找的是中间节点,偶数时找的是中间后边的一个节点。
public void middleNode(){
    //先定义两个开始的指针,一快一慢
    Node slow = head,fast = head;
    //然后开始判断什么时候快的结束,慢的也就是中间节点
    while (fast != null &&fast.next != null){
        //快的一次性进两个格子,慢的一次进一个格子
        slow = slow.next;
        fast = fast.next.next;
    }
    //最后输出中间的节点的数据。
    System.out.println(slow.data);
}

寻找第k个元素,太简单(也就在遍历的基础上加上限定条件

//寻找第K个元素
public void lengthK(int  K){
    int length = 1;
    Node current = head;
    while (current != null ){
        length++;
        current = current.next;
        if (K == length){
            System.out.println(current.data);
           break ;
        }
    }
}

旋转链表(不是倒叙,是把最后一个转到第一个!)

逻辑:判断头节点,和k的值是否为空,获取链表的长度,快指针先走k个单位,之后快慢指针一起走,直到快指针到终节点,慢节点的下一节点为空,快节点的尾结点连接头节点。

不会,运行不出来!!!!!!!!!!!!出来了,可以在该方法里面进行书写遍历,调用其他遍历方法的时候遍历输出的时候就会出现问题了。(总结:遍历输出最好是调用外面输出的方法)

//链表的旋转,输入旋转的次数
public void rotateRight(int k){
    if (head ==null||k ==0){
        System.out.println("请在返回内输入");
        return;
    }
    //设置一块一慢的指针
    Node temp = head;
    Node fast = head;
    Node slow = head;
    int len = 0;
    //求链表的长度
    while (head != null){
        head =head.next;
        len++;
    }
    if (k % len ==0){
        System.out.println("链表长度和旋转次数相等");
        return;
    }
    while ((k % len) >0){
        k--;
        fast = fast.next;
    }
    while (fast.next != null){
        fast = fast.next;
        slow = slow.next;
    }
    Node newNode = slow.next;
    slow.next = null;
    fast.next = temp;
    head = newNode;
    while (head != null) {
        System.out.print(head.data + "  ");
        head = head.next;
    }
}
删除链表元素

问题,删除问题都是一摸一样的,逻辑都是循环到某个节点进行删除,也只有描述可能有些变化。

删除重复元素的话也仅仅只是删除有序的,无序的话本人也思考了一下,一下是思考的逻辑。

逻辑:两个for循环来寻找重复的节点(不要重复节点的),并记录下来,从后面往前删除。(但是本人感觉该过程还是非常的麻烦的,也仅仅只是想了一下)

删除相关的代码。

//删除链表的某个节点
public void deletePosition(int position){
    //删除节点为头结点时
    if (position == 1){
        head = head.next;
    }else {
        //删除节点为非头节点,以及有其他情况时。
        Node current = head;
        int count = 1;
        while (current != null && count < position - 1) {
            current = current.next;
            count++;
        }
        if (current != null) {
            current.next = current.next.next;
        } else {
            //在非循序范围内的其他情况
            System.out.println("请在允许范围内进行");
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值