美文网首页
9.17~9.18刷题总结

9.17~9.18刷题总结

作者: icecrea | 来源:发表于2017-09-20 21:34 被阅读19次

    找到中序遍历二叉树下一个节点
    分析二叉树的下一个节点,一共有以下情况:
    1.二叉树为空,则返回空;
    2.节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点即为下一个节点;
    3.节点不是根节点。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,重复之前的判断,返回结果。代码如下

        //8,6,10,5,7,9,11
        /*
         * 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。
         * 注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
         */
        public TreeLinkNode GetNext(TreeLinkNode pNode)
        {
            if(pNode==null)
                return null;
            if(pNode.right!=null){//如果有右子树,找右子树的最左节点
                TreeLinkNode p=pNode.right;
                while(p.left!=null){
                    p=p.left;
                }
                return p;
            }
            while(pNode.next!=null){//没右子树,则找第一个当前结点是父节点左孩子的节点
                if(pNode.next.left==pNode)//节点不是根节点。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历
                    return pNode.next;
                pNode=pNode.next;
            }
           return null;
        }
        
    class TreeLinkNode {
        int val;
        TreeLinkNode left = null;
        TreeLinkNode right = null;
        TreeLinkNode next = null;
    
        TreeLinkNode(int val) {
            this.val = val;
        }
    }
    

    之字形打印二叉树
    利用栈后进先出的特性,两个栈一个存奇数层节点,一个存偶数层节点

        /*
         * 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,
         * 第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
         */
        //{8,6,10,5,7,9,11}
        public static ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
            ArrayList<ArrayList<Integer>> all=new ArrayList<ArrayList<Integer>>();  
            int layer=1;
            Stack<TreeNode> s1=new Stack<TreeNode>();
            Stack<TreeNode> s2=new Stack<TreeNode>();
            s1.push(pRoot);
            while(!s1.empty()||!s2.empty()){
                if(layer%2!=0){
                    ArrayList<Integer> temp=new ArrayList<Integer>();
                    while(!s1.empty()){
                        TreeNode node=s1.pop();
                        if(node!=null){
                            temp.add(node.val);
                            System.out.print(node.val + " ");
                            s2.push(node.left);
                            s2.push(node.right);
                        }
                    }
                    if(!temp.isEmpty()){
                        all.add(temp);
                        layer++;
                        System.out.println();
                    }
                }else{
                    ArrayList<Integer> temp=new ArrayList<Integer>();
                    while(!s2.empty()){
                        TreeNode node=s2.pop();
                        if(node!=null){
                            temp.add(node.val);
                            System.out.print(node.val + " ");
                            s1.push(node.right);
                            s1.push(node.left);
                        }
                    }
                    if(!temp.isEmpty()){
                        all.add(temp);
                        layer++;
                        System.out.println();
                    }
                }
                
            }
            return all;
        }
    

    多行打印二叉树

        public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
            ArrayList<ArrayList<Integer>> result=new ArrayList<ArrayList<Integer>>();   
            if(pRoot==null)
                return result;
            Queue<TreeNode> layer=new LinkedList<>();
            ArrayList<Integer> list=new ArrayList<Integer>();
           layer.add(pRoot);
           int start=0,end=1;
           while(!layer.isEmpty()){
               TreeNode cur=layer.remove();
               list.add(cur.val);
               start++;
               if(cur.left!=null)
                   layer.add(cur.left);
               if(cur.right!=null)
                   layer.add(cur.right);
               if(start==end){
                   end=layer.size();
                   start=0;
                   result.add(list);
                   list=new ArrayList<>();
               }
           }
           return result;
        }
    

    反转链表

    方法一

    //反转链表  
        ListNode reverseNode(ListNode phead){
            ListNode preverhead=null;//保存翻转后的头结点 是原始链表的尾结点
            ListNode pnode=phead;//当前节点
            ListNode pprev=null;//当前节点的左一个节点
            while(pnode!=null){
                ListNode pnext=pnode.next;//当前节点的下一个节点
                if(pnext==null)
                    preverhead=pnode;
                pnode.next=pprev;
                pprev=pnode;
                pnode=pnext;
            }
            return preverhead;
        }
    

    方法二

    public ListNode ReverseList(ListNode head) {
            if(head==null)
                return null;
            ListNode pre=null;
            ListNode next=null;
            while(head!=null){
                next=head.next;
                head.next=pre;
                pre=head;
                head=next;
            }
            return pre;
        }
    

    合并两个有序链表

    方法一 递归

        //合并两个有序链表
        public ListNode merge(ListNode node1,ListNode node2){
            if(node1==null)
                return node2;
            else if(node2==null)
                return node1;
            ListNode p=null;
            if(node1.val<node2.val){
                p=node1;
                p.next=merge(node1.next,node2);
            }else{
                p=node2;
                p.next=merge(node2.next,node1);
            }
            return p;
        }
    

    方法二 新建一个头结点

    //新建一个头结点的方式 合并有序链表
        public ListNode Merge(ListNode list1,ListNode list2) {
               ListNode head=new ListNode(-1);
               head.next=null;
               ListNode root=head;
               while(list1!=null&&list2!=null){
                   if(list1.val<list2.val){
                       head.next=list1;
                       head=list1;
                       list1=list1.next;
                   }else{
                       head.next=list2;
                       head=list2;
                       list2=list2.next;
                   }
               }
               if(list1!=null)
                   head.next=list1;
               if(list2!=null)
                   head.next=list2;
               return root.next;
           }
    

    方法三 先赋值第一个节点

        //先赋值第一个节点
        public ListNode Merge2(ListNode list1,ListNode list2) {
               ListNode head=null;
              if(list1.val<=list2.val){
                 head=list1;
                 list1=list1.next;              
              }else{
                  head=list2;
                  list2=list2.next;
              }
              ListNode p=head;
               while(list1!=null&&list2!=null){
                   if(list1.val<list2.val){
                       p.next=list1;
                       list1=list1.next;                 
                   }else{
                       p.next=list2;
                       list2=list2.next;                 
                   }
                   p=p.next;
               }
               if(list1!=null)
                   p.next=list1;
               if(list2!=null)
                   p.next=list2;
               return head;
           }
    

    相关文章

      网友评论

          本文标题:9.17~9.18刷题总结

          本文链接:https://www.haomeiwen.com/subject/rsxasxtx.html