亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

二叉樹(shù)遞歸迭代及morris層序前中后序遍歷詳解

 更新時(shí)間:2021年12月03日 09:02:35   作者:威斯布魯克.猩猩  
這篇文章主要為大家介紹了二叉樹(shù)遞歸迭代詳解及二叉樹(shù)的morris遍歷、層序遍歷、前序遍歷、中序遍歷、后序遍歷示例分析,有需要的朋友可以借鑒參考下

分析二叉樹(shù)的前序,中序,后序的遍歷步驟

1.層序遍歷

方法一:廣度優(yōu)先搜索

? (以下解釋來(lái)自leetcode官方題解)

我們可以用廣度優(yōu)先搜索解決這個(gè)問(wèn)題。

我們可以想到最樸素的方法是用一個(gè)二元組 (node, level) 來(lái)表示狀態(tài),它表示某個(gè)節(jié)點(diǎn)和它所在的層數(shù),每個(gè)新進(jìn)隊(duì)列的節(jié)點(diǎn)的 level 值都是父親節(jié)點(diǎn)的 level 值加一。最后根據(jù)每個(gè)點(diǎn)的 level 對(duì)點(diǎn)進(jìn)行分類(lèi),分類(lèi)的時(shí)候我們可以利用哈希表,維護(hù)一個(gè)以 level 為鍵,對(duì)應(yīng)節(jié)點(diǎn)值組成的數(shù)組為值,廣度優(yōu)先搜索結(jié)束以后按鍵 level 從小到大取出所有值,組成答案返回即可。

考慮如何優(yōu)化空間開(kāi)銷(xiāo):如何不用哈希映射,并且只用一個(gè)變量 node 表示狀態(tài),實(shí)現(xiàn)這個(gè)功能呢?

我們可以用一種巧妙的方法修改廣度優(yōu)先搜索:

  • ?首先根元素入隊(duì)
  • ?當(dāng)隊(duì)列不為空的時(shí)候,

求當(dāng)前隊(duì)列的長(zhǎng)度 S_i;?

依次從隊(duì)列中取 S_i?個(gè)元素進(jìn)行拓展,然后進(jìn)入下一次迭代.

它和普通廣度優(yōu)先搜索的區(qū)別在于,普通廣度優(yōu)先搜索每次只取一個(gè)元素拓展,而這里每次取 S_i個(gè)元素。在上述過(guò)程中的第 i?次迭代就得到了二叉樹(shù)的第?i 層的?S_i?個(gè)元素。

為什么這么做是對(duì)的呢?我們觀察這個(gè)算法,可以歸納出這樣的循環(huán)不變式:第 i 次迭代前,隊(duì)列中的所有元素就是第 i 層的所有元素,并且按照從左向右的順序排列。證明它的三條性質(zhì)(你也可以把它理解成數(shù)學(xué)歸納法):

初始化:i=1 的時(shí)候,隊(duì)列里面只有 root,是唯一的層數(shù)為 1 的元素,因?yàn)橹挥幸粋€(gè)元素,所以也顯然滿(mǎn)足「從左向右排列」;
保持:如果 i=k 時(shí)性質(zhì)成立,即第 k 輪中出隊(duì) S_k的元素是第 k 層的所有元素,并且順序從左到右。因?yàn)閷?duì)樹(shù)進(jìn)行廣度優(yōu)先搜索的時(shí)候由低 k 層的點(diǎn)拓展出的點(diǎn)一定也只能是 k+1 層的點(diǎn),并且 k+1 層的點(diǎn)只能由第 k 層的點(diǎn)拓展到,所以由這?S_k?個(gè)點(diǎn)能拓展到下一層所有的?S_k+1 ?個(gè)點(diǎn)。又因?yàn)殛?duì)列的先進(jìn)先出(FIFO)特性,既然第 k 層的點(diǎn)的出隊(duì)順序是從左向右,那么第 k+1 層也一定是從左向右。至此,我們已經(jīng)可以通過(guò)數(shù)學(xué)歸納法證明循環(huán)不變式的正確性。
終止:因?yàn)樵撗h(huán)不變式是正確的,所以按照這個(gè)方法迭代之后每次迭代得到的也就是當(dāng)前層的層次遍歷結(jié)果。至此,我們證明了算法是正確的。

廣度優(yōu)先搜索的簡(jiǎn)化步驟為

初始化隊(duì)列 q,并將根節(jié)點(diǎn) root 加入到隊(duì)列中;
當(dāng)隊(duì)列不為空時(shí):
隊(duì)列中彈出節(jié)點(diǎn) node,加入到結(jié)果中;
如果左子樹(shù)非空,左子樹(shù)加入隊(duì)列;
如果右子樹(shù)非空,右子樹(shù)加入隊(duì)列;
由于題目要求每一層保存在一個(gè)子數(shù)組中,所以我們額外加入了 level 保存每層的遍歷結(jié)果,并使用 for 循環(huán)來(lái)實(shí)現(xiàn)。

看個(gè)圖例用以說(shuō)明:

廣度優(yōu)先需要用隊(duì)列作為輔助結(jié)構(gòu),我們先將根節(jié)點(diǎn)放到隊(duì)列中,然后不斷遍歷隊(duì)列。

首先拿出根節(jié)點(diǎn),如果左子樹(shù)/右子樹(shù)不為空,就將他們放入隊(duì)列中。第一遍處理完后,根節(jié)點(diǎn)已經(jīng)從隊(duì)列中拿走了,而根節(jié)點(diǎn)的兩個(gè)孩子已放入隊(duì)列中了,現(xiàn)在隊(duì)列中就有兩個(gè)節(jié)點(diǎn) 2 和 5。

第二次處理,會(huì)將 2 和 5 這兩個(gè)節(jié)點(diǎn)從隊(duì)列中拿走,然后再將 2 和 5 的子節(jié)點(diǎn)放入隊(duì)列中,現(xiàn)在隊(duì)列中就有三個(gè)節(jié)點(diǎn) 3,4,6。

我們把每層遍歷到的節(jié)點(diǎn)都放入到一個(gè)結(jié)果集中,最后返回這個(gè)結(jié)果集就可以了。

public List<List<Integer>> levelOrder(TreeNode root) {
        //返回的結(jié)果
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(null == root){
            return res;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        //根節(jié)點(diǎn)入隊(duì)
        queue.add(root);
        while(!queue.isEmpty()){
            //一層的結(jié)果
            List<Integer> level = new ArrayList<Integer>();
            int levelCount = queue.size();
            //添加節(jié)點(diǎn)到一層的List中去
            for(int i = 0; i < levelCount ; i ++){
                //節(jié)點(diǎn)出隊(duì)
                TreeNode node = queue.remove();
                //節(jié)點(diǎn)的左子樹(shù)入隊(duì)
                if(node.left != null){
                  queue.add(node.left);   
                }
                //節(jié)點(diǎn)的右子樹(shù)入隊(duì)   
                if(node.right != null){
                  queue.add(node.right);   
                }  
                level.add(node.val);
            }
            res.add(level);
        }
        return res;
    }

方法二:遞歸

用廣度優(yōu)先處理是很直觀的,可以想象成是一把刀橫著切割了每一層,但是深度優(yōu)先遍歷就不那么直觀了。

我們開(kāi)下腦洞,把這個(gè)二叉樹(shù)的樣子調(diào)整一下,擺成一個(gè)田字形的樣子。田字形的每一層就對(duì)應(yīng)一個(gè) list。

按照深度優(yōu)先的處理順序,會(huì)先訪問(wèn)節(jié)點(diǎn) 1,再訪問(wèn)節(jié)點(diǎn) 2,接著是節(jié)點(diǎn) 3。
之后是第二列的 4 和 5,最后是第三列的 6。

每次遞歸的時(shí)候都需要帶一個(gè) index(表示當(dāng)前的層數(shù)),也就對(duì)應(yīng)那個(gè)田字格子中的第幾行,如果當(dāng)前行對(duì)應(yīng)的 list 不存在,就加入一個(gè)空 list 進(jìn)去。

public List<List<Integer>> levelOrder(TreeNode root) {
		List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(root==null) {
			return res;
		}	
		LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
		//將根節(jié)點(diǎn)放入隊(duì)列中,然后不斷遍歷隊(duì)列
		queue.add(root);
		while(queue.size()>0) {
			//獲取當(dāng)前隊(duì)列的長(zhǎng)度,這個(gè)長(zhǎng)度相當(dāng)于 當(dāng)前這一層的節(jié)點(diǎn)個(gè)數(shù)
			int size = queue.size();
			ArrayList<Integer> tmp = new ArrayList<Integer>();
			//將隊(duì)列中的元素都拿出來(lái)(也就是獲取這一層的節(jié)點(diǎn)),放到臨時(shí)list中
			//如果節(jié)點(diǎn)的左/右子樹(shù)不為空,也放入隊(duì)列中
			for(int i=0;i<size;++i) {
				TreeNode t = queue.remove();
				tmp.add(t.val);
				if(t.left!=null) {
					queue.add(t.left);
				}
				if(t.right!=null) {
					queue.add(t.right);
				}
			}
			//將臨時(shí)list加入最終返回結(jié)果中
			res.add(tmp);
		}
		return res;
}

2.前序遍歷

2.1先輸出當(dāng)前節(jié)點(diǎn)(初始的時(shí)候是root節(jié)點(diǎn))

2.2如果左子節(jié)點(diǎn)不為空,則遞歸繼續(xù)前序遍歷

2.3如果右子節(jié)點(diǎn)不為空,則遞歸繼續(xù)前序遍歷

3.中序遍歷

3.1如果當(dāng)前節(jié)點(diǎn)的左子節(jié)點(diǎn)不為空,則遞歸中序遍歷

3.2輸出當(dāng)前節(jié)點(diǎn)

3.3如果當(dāng)前節(jié)點(diǎn)的右子節(jié)點(diǎn)不為空,則遞歸中序遍歷

4.后序遍歷

4.1如果當(dāng)前節(jié)點(diǎn)的左子節(jié)點(diǎn)不為空,則遞歸后序遍歷

4.2如果當(dāng)前節(jié)點(diǎn)的右子節(jié)點(diǎn)不為空,則遞歸后序遍歷

4.3輸出當(dāng)前節(jié)點(diǎn)

如果你按照 根節(jié)點(diǎn) -> 左孩子 -> 右孩子 的方式遍歷,即「先序遍歷」,每次先遍歷根節(jié)點(diǎn),遍歷結(jié)果為 1 2 4 5 3 6 7;

同理,如果你按照 左孩子 -> 根節(jié)點(diǎn) -> 右孩子 的方式遍歷,即「中序序遍歷」,遍歷結(jié)果為 4 2 5 1 6 3 7;

如果你按照 左孩子 -> 右孩子 -> 根節(jié)點(diǎn) 的方式遍歷,即「后序序遍歷」,遍歷結(jié)果為 4 5 2 6 7 3 1;

最后,層序遍歷就是按照每一層從左向右的方式進(jìn)行遍歷,遍歷結(jié)果為 1 2 3 4 5 6 7。

遞歸解法

由于層次遍歷的遞歸解法不是主流,因此只介紹前三種的遞歸解法

前序遍歷--遞歸

public List<Integer> preorderTraversal(TreeNode root) {
        //遞歸
        List<Integer> list = new ArrayList<>();
        preOrder(root,list);
        return list;
    }
    public void preOrder(TreeNode root,List<Integer> list){
        if(root == null){
            return;
        }
        list.add(root.val);
        preOrder(root.left,list);
        preOrder(root.right,list);
}

中序遍歷--遞歸

public List<Integer> inorderTraversal(TreeNode root) {
        //遞歸
        List<Integer> list = new LinkedList<>();
        inOrder(root,list);
        return list;
    }
    public void inOrder(TreeNode root,List<Integer> list){
        if(root == null){
            return;
        }
        inOrder(root.left,list);
        list.add(root.val);
        inOrder(root.right,list);
}

后序遍歷--遞歸

public List<Integer> postorderTraversal(TreeNode root) {
        //遞歸
        List<Integer> list = new LinkedList<>();
        postOrder(root,list);
        return list;
    }
    public void postOrder(TreeNode root,List<Integer> list){
        if(root == null){
            return;
        }
        postOrder(root.left,list);
        postOrder(root.right,list);
        list.add(root.val);
}

三種遞歸遍歷的總結(jié):遞歸終止的條件為碰到空節(jié)點(diǎn)。

迭代解法

前序遍歷--迭代

核心思想:

1.每拿到一個(gè)節(jié)點(diǎn)就把它保存在棧中

2.繼續(xù)對(duì)這個(gè)節(jié)點(diǎn)的左子樹(shù)重復(fù)過(guò)程1,直到左子樹(shù)為空

3.因?yàn)楸4嬖跅V械墓?jié)點(diǎn)都遍歷了左子樹(shù)但是沒(méi)有遍歷右子樹(shù),所以對(duì)棧中節(jié)點(diǎn)出棧并對(duì)它的右子樹(shù)重復(fù)過(guò)程1

4.直到遍歷完所有節(jié)點(diǎn)

public List<Integer> preorderTraversal(TreeNode root) {
        //迭代
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        Deque<TreeNode> stack = new LinkedList<TreeNode>();
        //臨時(shí)節(jié)點(diǎn),幫助遍歷二叉樹(shù)
        TreeNode node = root;
        //棧的作用是用來(lái)短暫的保存遍歷節(jié)點(diǎn)的值,以助于最后值的返回
        while(!stack.isEmpty() || node != null){
            while(node != null){
                list.add(node.val);
                stack.push(node);
                node = node.left;
            }
            node = stack.pop();
            node = node.right;
        }
        return list;
}

中序遍歷--迭代

public List<Integer> inorderTraversal(TreeNode root) {
        //迭代
        List<Integer> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        Deque<TreeNode> stack = new LinkedList<>();
        while(!stack.isEmpty() || root != null){
            while(root != null){
                stack.push(root);
                root = root.left;
            }
            root = stack.pop();
            list.add(root.val);//出棧的時(shí)候才將父節(jié)點(diǎn) 的值加入到結(jié)果中
            root = root.right;
        }
        return list;
}

和前序遍歷的代碼完全相同,只是在出棧的時(shí)候才將父節(jié)點(diǎn)?的值加入到結(jié)果中。

后序遍歷--迭代

public List<Integer> postorderTraversal(TreeNode root) {
        LinkedList<Integer> list = new LinkedList<>();
        Stack<TreeNode> stack = new Stack<>();
        while (root != null || !stack.isEmpty()) {
            if (root != null) {
                stack.push(root);
                list.addFirst(root.val);//addFirst():向鏈表首部添加元素
                root = root.right;
            } else {
                root = stack.pop();
                root = root.left;
            }
        }
        return list;
}

三種迭代解法的總結(jié):

前序遍歷和后序遍歷之間的關(guān)系:

前序遍歷順序?yàn)椋焊?-> 左 -> 右

后序遍歷順序?yàn)椋鹤?-> 右 -> 根

如果1: 將前序遍歷中節(jié)點(diǎn)插入結(jié)果鏈表尾部的邏輯,修改為將節(jié)點(diǎn)插入結(jié)果鏈表的頭部

那么結(jié)果鏈表就變?yōu)榱耍河?-> 左 -> 根

如果2: 將遍歷的順序由從左到右修改為從右到左,配合如果1

那么結(jié)果鏈表就變?yōu)榱耍鹤?-> 右 -> 根

這剛好是后序遍歷的順序

基于這兩個(gè)思路,想一下如何處理:

修改前序遍歷代碼中,節(jié)點(diǎn)寫(xiě)入結(jié)果鏈表的代碼,將插入隊(duì)尾修改為插入隊(duì)首

修改前序遍歷代碼中,每次先查看左節(jié)點(diǎn)再查看右節(jié)點(diǎn)的邏輯,變?yōu)橄炔榭从夜?jié)點(diǎn)再查看左節(jié)點(diǎn)

前序遍歷和中序遍歷之間的關(guān)系:

和前序遍歷的代碼完全相同,只是在出棧的時(shí)候才將父節(jié)點(diǎn)的值加入到結(jié)果中。

Morris遍歷

遍歷特點(diǎn):Morris 遍歷利用了樹(shù)中大量空閑指針的特性

當(dāng)前節(jié)點(diǎn)cur,一開(kāi)始cur來(lái)到整樹(shù)頭

1)cur無(wú)左樹(shù),cur? = cur.right(cur右移)

2)cur有左樹(shù),找到左樹(shù)最右節(jié)點(diǎn),mostright;此時(shí)我們又可以分為兩種情況,一種是葉子節(jié)點(diǎn)添加 right 指針的情況,一種是去除葉子節(jié)點(diǎn) right 指針的情況

?A.mostright 的右指針指向null的mostright.right = cur,? cur = cur.left(cur左移)

?B.mostright 的右指針指向cur的mostright.right = null(為了防止重復(fù)執(zhí)行,則需要去掉 right 指針),? ????cur = cur.right(cur右移)

當(dāng)cur == null時(shí),整個(gè)過(guò)程結(jié)束。

遍歷特點(diǎn):有左樹(shù)節(jié)點(diǎn)必遍歷到兩次,沒(méi)有左樹(shù)的節(jié)點(diǎn)必遍歷到一次

public static void morris(Node head){
    if(head == null){
        return;
    }
    Node cur = head;
    Node mostRight = null;
    while(cur != null){
        //cur有沒(méi)有左樹(shù)
        mostRight = cur.left;
        if(mostRight != null){//有左樹(shù)的情況
            //找到cur左樹(shù)上,真實(shí)的最右節(jié)點(diǎn)
            //前者說(shuō)明是第一次來(lái)到當(dāng)前的cur,后者說(shuō)明是第二次來(lái)到當(dāng)前的cur
            while(mostRight.right != null && mostRight.right != cur){
                mostRight = mostRight.right;
            }
            //從while中出來(lái),mostRight一定是cur左樹(shù)上的最右節(jié)點(diǎn)
            if(mostRight.right == null){
                mostRight.right = cur;
                cur = cur.left;
                continue;//結(jié)束的是外層的循環(huán)?。。。。。。。。。。。?!
            }else{//走到這里意味著:mostRight.right == cur
                mostRight.right = null;
            }
        }
        //cur沒(méi)有左樹(shù)
        cur = cur.right;
    }
}

空間復(fù)雜度:利用空閑的指針,使用了兩個(gè)變量完成了遍歷,空間復(fù)雜度是常數(shù)級(jí)別的

時(shí)間復(fù)雜度:?

morris--前序遍歷

第一次來(lái)到一個(gè)節(jié)點(diǎn),就打印;第二次來(lái)到這個(gè)節(jié)點(diǎn),不打印

public static void morrisPre(Node head){
    if(head == null){
        return;
    }
    Node cur = head;
    Node mostRight = null;
    while(cur != null){
        mostRight = cur.left;
        if(mostRight != null){
            while(mostRight.right != null && mostRight.right != cur){
                mostRight = mostRight.right;
            }
            if(mostRight.right == null){
                mostRight.right = cur;
                System.out.print(cur.value + " ");
                cur = cur.left;
                continue;
            }else{
                mostRight.right = null;
            }
        }else{
            System.out.print(cur.value + " ");
        }
        cur = cur.right;
    }
    System.out.println();
}

morris--中序遍歷

對(duì)于能回到自己兩次的節(jié)點(diǎn),第二次時(shí)打印,對(duì)于只能來(lái)到自己一次的節(jié)點(diǎn),直接打印

只要一個(gè)節(jié)點(diǎn)要往右移動(dòng),就打印

public static void morrisIn(Node head){
    if(head == null){
        return;
    }
    Node cur = head;
    Node mostRight = null;
    while(cur != null){
        mostRight = cur.left;
        if(mostRight != null){
            while(mostRight.right != null && mostRight.right != cur){
                mostRight = mostRight.right;
            }
            if(mostRight.right == null){
                mostRight.right = cur;
                cur = cur.left;
                continue;
            }else{
                mostRight.right = null;
            }
        }
        System.out.print(cur.value + " ");
        cur = cur.right;
    }
    System.out.println();
}

morris--后序遍歷:

public static void morrisPos(Node head) {
		if(head == null) {
			return;
		}
		Node cur = head;
		Node mostRight = null;
		while(cur != null) {
			mostRight = cur.left;
			if(mostRight != null) {
				while(mostRight.right != null && mostRight.right != cur) {
					mostRight = mostRight.right;
				}
				if(mostRight.right == null) {
					mostRight.right = cur;
					cur = cur.left;
					continue;
				}else {
					mostRight.right = null;
					printEdge(cur.left);//逆序打印左樹(shù)的右邊界
				}
			}
			cur = cur.right;
		}
		printEdge(head);//最后打印整棵樹(shù)的右邊界
		System.out.println();
	}
 	public static void printEdge(Node head) {
		Node tail = reverseEdge(head);
		Node cur = tail;
		while(cur != null) {
			System.out.print(cur.value + " ");
			cur = cur.right;
		}
		reverseEdge(tail);
	}
	private static Node reverseEdge(Node from) {
		Node pre = null;
		Node next = null;
		while(from != null) {
			next = from.right;
			from.right = pre;
			pre = from;
			from = next;
		}
		return pre;
	}

Morris后序遍歷比較復(fù)雜,可以看看相關(guān)的視頻講解--左神算法系列。

以上就是二叉樹(shù)遞歸迭代及morris層序前中后序遍歷詳解的詳細(xì)內(nèi)容,更多關(guān)于二叉樹(shù)遞歸迭代遍歷詳解的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java全面細(xì)致講解類(lèi)與對(duì)象

    Java全面細(xì)致講解類(lèi)與對(duì)象

    類(lèi)和對(duì)象是兩種以計(jì)算機(jī)為載體的計(jì)算機(jī)語(yǔ)言的合稱(chēng)。對(duì)象是對(duì)客觀事物的抽象,類(lèi)是對(duì)對(duì)象的抽象。類(lèi)是一種抽象的數(shù)據(jù)類(lèi)型;變量就是可以變化的量,存儲(chǔ)在內(nèi)存中—個(gè)可以擁有在某個(gè)范圍內(nèi)的可變存儲(chǔ)區(qū)域
    2022-05-05
  • IDEA連接mysql報(bào)錯(cuò)的問(wèn)題及解決方法

    IDEA連接mysql報(bào)錯(cuò)的問(wèn)題及解決方法

    這篇文章主要介紹了IDEA連接mysql報(bào)錯(cuò)的問(wèn)題及解決方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java?JSON處理庫(kù)之Gson的用法詳解

    Java?JSON處理庫(kù)之Gson的用法詳解

    Gson是Google開(kāi)發(fā)的一款Java?JSON處理庫(kù),旨在簡(jiǎn)化Java開(kāi)發(fā)人員操作JSON數(shù)據(jù)的過(guò)程,本文就來(lái)和大家簡(jiǎn)單聊聊Gson的原理與具體使用吧
    2023-05-05
  • Java class文件格式之方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java class文件格式之方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要為大家詳細(xì)介紹了Java class文件格式之方法的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • SpringCloud之監(jiān)控?cái)?shù)據(jù)聚合Turbine的實(shí)現(xiàn)

    SpringCloud之監(jiān)控?cái)?shù)據(jù)聚合Turbine的實(shí)現(xiàn)

    這篇文章主要介紹了SpringCloud之監(jiān)控?cái)?shù)據(jù)聚合Turbine的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 詳解WebSocket+spring示例demo(已使用sockJs庫(kù))

    詳解WebSocket+spring示例demo(已使用sockJs庫(kù))

    本篇文章主要介紹了WebSocket spring示例demo(已使用sockJs庫(kù)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-01-01
  • 深入淺出MappedByteBuffer(推薦)

    深入淺出MappedByteBuffer(推薦)

    MappedByteBuffer使用虛擬內(nèi)存,因此分配(map)的內(nèi)存大小不受JVM的-Xmx參數(shù)限制,但是也是有大小限制的,這篇文章主要介紹了MappedByteBuffer的基本知識(shí),需要的朋友可以參考下
    2022-12-12
  • 如何解決線程太多導(dǎo)致java socket連接池出現(xiàn)的問(wèn)題

    如何解決線程太多導(dǎo)致java socket連接池出現(xiàn)的問(wèn)題

    這篇文章主要介紹了如何解決線程太多導(dǎo)致socket連接池出現(xiàn)的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • MybatisPlus查詢(xún)條件為空字符串或null問(wèn)題及解決

    MybatisPlus查詢(xún)條件為空字符串或null問(wèn)題及解決

    這篇文章主要介紹了MybatisPlus查詢(xún)條件為空字符串或null問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • JAVA中的for循環(huán)幾種使用方法講解

    JAVA中的for循環(huán)幾種使用方法講解

    這篇文章主要介紹了JAVA中的for循環(huán)幾種使用方法講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09

最新評(píng)論