Java算法——12展开链接列表

题目描述

给定一个有序链表,其中每个结点也表示一个有序链表,结点包含两个类型的指针:

(1)指向主链表中下一个结点的指针(下面代码中称为“正确”指针)

(2)指向此结点头的链表(下面代码中称为“down”指针)

所以链表都被排序。如:

3 → 11 → 15 → 30
↓    ↓    ↓	   ↓
6   21   22	  39	
↓         ↓	   ↓	
8		 50	  40
↓          	   ↓	
31			  55

实现一个函数flatten(),该函数用来将链表扁平化成单个链表,扁平化的链表也应该被排序。例如,对于上述链表,输出链表为3→6→8→11→15→21→22→30→31→39→40→45→50。

解题思路

使用归并排序中的合并操作,使用归并的方法把这些链表来逐个归并。具体而言,可以使用递归的方法,递归地合并已经扁平化的链表与当前链表。在实现的过程可以使用down指针来存储扁平化处理后的链表。

public class Test12 {
    /** 链表结点 */
    private class Node{
        int data;
        Node right,down;
        Node(int data){
            this.data=data;
            this.right=null;
            this.down=null;
        }
    }

    private Node head;

    /** 用来合并两个有序的链表*/
    private Node merge(Node a, Node b){
        /*如果其中一个链表为空,直接返回另一个链表*/
        if(a==null){
            return b;
        }
        if(b==null){
            return a;
        }
        /*把两个链表头中较小的结点赋值给result*/
        Node result;
        if(a.data<b.data){
            result=a;
            result.down=merge(a.down,b);
        }else{
            result=b;
            result.down=merge(a,b.down);
        }
        return result;
    }

    /*把链表扁平化处理*/
    public Node flatten(Node root){
        if(root==null||root.right==null){
            return root;
        }
        /*递归处理root.right链表*/
        root.right=flatten(root.right);
        /*把root结点对应的链表与右边的链表合并*/
        root=merge(root,root.right);
        return root;
    }

    /**把data插入到链表头*/
    private Node insert(Node head_ref,int data){
        Node new_node = new Node(data);
        new_node.down=head_ref;
        head_ref=new_node;
        /*返回新的表头结点*/
        return head_ref;
    }

    public void printList(){
        Node temp=head;
        while (temp!=null){
            System.out.print(temp.data+" ");
            temp=temp.down;
        }
        System.out.println();
    }

    public static void main(String[] args){
        Test12 L = new Test12();
        /* 构造链表 */
        L.head=L.insert(L.head,31);
        L.head=L.insert(L.head,8);
        L.head=L.insert(L.head,6);
        L.head=L.insert(L.head,3);
        
        L.head.right=L.insert(L.head.right,21);
        L.head.right=L.insert(L.head.right,11);

        L.head.right.right=L.insert(L.head.right.right,50);
        L.head.right.right=L.insert(L.head.right.right,20);
        L.head.right.right=L.insert(L.head.right.right,15);

        L.head.right.right.right=L.insert(L.head.right.right.right,55);
        L.head.right.right.right=L.insert(L.head.right.right.right,40);
        L.head.right.right.right=L.insert(L.head.right.right.right,39);
        L.head.right.right.right=L.insert(L.head.right.right.right,30);

        /* 扁平化链表 */
        L.head=L.flatten(L.head);
        L.printList();
    }
}

程序运行结果:

3 6 8 11 15 20 21 30 31 39 40 50 55 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值