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<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;
       }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 樹的概述 樹是一種非常常用的數據結構,樹與前面介紹的線性表,棧,隊列等線性結構不同,樹是一種非線性結構 1.樹的定...
    Jack921閱讀 4,489評論 1 31
  • 第一章 緒論 什么是數據結構? 數據結構的定義:數據結構是相互之間存在一種或多種特定關系的數據元素的集合。 第二章...
    SeanCheney閱讀 5,822評論 0 19
  • B樹的定義 一棵m階的B樹滿足下列條件: 樹中每個結點至多有m個孩子。 除根結點和葉子結點外,其它每個結點至少有m...
    文檔隨手記閱讀 13,345評論 0 25
  • 1 序 2016年6月25日夜,帝都,天下著大雨,拖著行李箱和同學在校門口照了最后一張合照,搬離寢室打車去了提前租...
    RichardJieChen閱讀 5,165評論 0 12
  • 數據結構和算法--二叉樹的實現 幾種二叉樹 1、二叉樹 和普通的樹相比,二叉樹有如下特點: 每個結點最多只有兩棵子...
    sunhaiyu閱讀 6,529評論 0 14