9.17~9.18刷题总结

找到中序遍历二叉树下一个节点
分析二叉树的下一个节点,一共有以下情况:
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> Print(TreeNode pRoot) {
        ArrayList> all=new ArrayList>();  
        int layer=1;
        Stack s1=new Stack();
        Stack s2=new Stack();
        s1.push(pRoot);
        while(!s1.empty()||!s2.empty()){
            if(layer%2!=0){
                ArrayList temp=new ArrayList();
                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 temp=new ArrayList();
                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 > Print(TreeNode pRoot) {
        ArrayList> result=new ArrayList>();   
        if(pRoot==null)
            return result;
        Queue layer=new LinkedList<>();
        ArrayList list=new ArrayList();
       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

方法二 新建一个头结点

//新建一个头结点的方式 合并有序链表
    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

方法三 先赋值第一个节点

    //先赋值第一个节点
    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

你可能感兴趣的:(9.17~9.18刷题总结)