开始前我们先看一个问题: 你是否曾经在学习 Mybatis 的时候跟我有一样的疑问,什么情况下返回 null,什么时候是空集合,为什么会是这种结果?那么你觉得上述这种回答能说服你嘛?...看完这篇你就知道查询结果为空时候为什么集合会是空集合而不是 NULL,而对象为什么会是 NULL 了。 PS:对过程不感兴趣的可以直接跳到最后看结论。...最后返回映射的结果对象,如果没有映射任何属性,则需要根据全局配置决定如何返回这个结果值,这里不同场景和配置,可能返回完整的结果对象、空结果对象或是 null。...当返回行的所有列都是空时,MyBatis 默认返回 null。当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集(如集合或关联)。...而返回值为集合对象且查为空时,selectList 会把这个存储结果的 List 对象直接返回,此时这个 List 就是个空集合。
当队列为空时(while(!QueueEmpty(&q))),就结束循环并销毁队列。...不同的是如果遇到空节点(无左孩子或右孩子便是NULL)同样要进入队列,并以队列为空(while (!QueueEmpty(&q)))作为循环结束条件(事实上此循环无法通过此条件结束)。...在循环内部,如果接收到的出队列的节点为空,同样结束循环(break)。 至于遇到空节点,为什么要结束循环?...= NULL)就直接销毁队列,并返回false;如果队列遍历到最后都没有发现空节点,那么便结束循环,销毁队列并返回true。...= NULL) { QueueDestroy(&q); return false; } } //直到队列为空,认为找到非空节点 //销毁队列并返回true QueueDestroy
删除元素接口: remove() -> 删除队列头元素并返回该元素,如果队列为空抛出NoSuchElementException异常。...E poll() -> 删除队列头元素并返回该元素,如果队列为空返回null(与remove不同)。...获取队列头元素接口: E element() -> 返回队列头部元素(没有删除),如果队列为空抛出NoSuchElementException异常。...E peek() -> 返回队列头部元素(没有删除),如果队列为空返回null。...并倒序的往PriorityQueue添加10-1。然后从PriorityQueue头部出队列并输出,输出结果是1-10升序。
实现链式结构二叉树(二叉链)下篇 前言 接上一篇 实现链式结构二叉树(二叉链)上篇 二叉树实现方法 二叉树查找值为x的结点 分为左右子树查找,依次递推即可 结束条件为空:说明在这一路径上没有找到 结束条件找到了返回结点指针即可...所以传二级指针(一级指针也可以,只不过在调用完记得把root置为空) 先销毁左右子树,最后销毁根节点 当为空时,不用销毁直接返回 void BinaryTreeDestory(BTNode** root...BTNode* 首先将指向根节点的指针入队列,保存后并打印结点的值 根节点出队列,保证每一次取到的队列的头都是新的 如果根节点左右孩子不为空就将其入队列,为空则无必要,不需要打印NULL 重复上述操作直到队列为空...front->left) QueuePush(&q, front->left); if (front->right) QueuePush(&q, front->right); } //队列为空...NULL结点 如果是非完全二叉树,跳出此循环后还有非空结点 于是第二个循环用来判断此时队列里是否有非空的指针 如果直到队列为空跳出循环说明全是空指针,返回true 反之返回false //判断二叉树是否为完全二叉树
设当前序列为pn,下一个较大的序列为pn+1,这里蕴藏的含义是再也找不到另外的序列pm,使得pn < pm < pn+1。 问题 给定任意非空序列,生成下一个较大或较小的排列。...例如,在字母表中,abcd的下一单词排列为abdc,但是,有一关键点,如何确定这个下一排列为字典序中的next,而不是next->next->next…… 若当前调用排列到达最大字典序,比如dcba,...就返回false,同时重新设置该排列为最小字典序。...要点:为什么这样就可以保证得到的为最小递增。 从位置first开始原数列与新数列不同的数据位置是PX,并且新数据为X2。...从而保证的新数列为原数列的字典序排列next。
if,说明找到了直接返回结点指针 2.6.1 示例代码: BTNode* BinaryTreeFind(BTNode* root, BTDataType x) { if (root == NULL)...实现层序遍历需要借助数据结构队列(先进先出) 先将根节点入队列, 出队列前打印根节点的数据,同时将根节点的左右孩子入队列,重复该过程,直至队列为空。...front->left) QueuePush(&q, front->left); if (front->right) QueuePush(&q, front->right); } //队列为空...某完全⼆叉树按层次输出(同⼀层从左到右)的序列为 ABCDEFGH 。...设⼀课⼆叉树的中序遍历序列: badce ,后序遍历序列: bdeca ,则⼆叉树前序遍历序列为 ____ 。
,那就打印这个结点的data,然后进入左子树进行先序遍历,如果左子树的根节点不是空指针,那就打印左子树的根结点的值,然后继续进入左子树的左子树,一直走到左子树为空,然后此时就遍历右子树,进而就实现了链式二叉树的先序遍历...两个结点都进入,空结点返回0,非空返回1,这是其中一个终止条件的意义,另一个就很明显了,就是左右结点是空就返回1,没有什么过多需要解释的,如果这个结点不符合上述两个终止条件的话,就返回他的左子树+他的右子树...12.二叉树的层序遍历 需要进行层序遍历,这里需要借助队列来实现了,首先肯定是要创建一个队列的,然后队列进行初始化,写一个循环,只要队列不为空,就一直入队列,队列是先入先出的特点,入队列之后直接打印,然后队列删除队头...,然后左子树右子树入队列接着打印,一直到队列为空,此时就实现了队列的层序遍历。...那么就进入下一个循环,循环条件是队列非空,因为如果是二叉树,在取完最后一个结点之后,队列中剩下的都是空结点,如果不是完全二叉树的话,里面就会剩下非空的,一直取到队列为空,如果取到了非空就直接返回false
---- 使用树理解深度优先和广度优先 我们上篇博文中 Algorithms_二叉树的前序遍历、中序遍历、后续遍历(深度优先) ,本质上是深度优先。 为什么这么说呢?...: 2、3、4、5、6、8 后序遍历 : 2、4、3、8、6、5 不管是前序、中序还是后序都会先把左子树遍历到没有元素,然后再遍历右子树到没有元素, 都是先顺着一个枝杈往最深的地方走。...\ 2 4 8 再遍历第2层的数据 --------------------------------------- 我们逐步来分析一下 根节点不为空的话...------> 5 3 6 2 访问 4 看下4 还有没有左右孩子,没有 ------> 5 3 6 2 4 访问 8 看下8 还有没有左右孩子,没有 ------> 5 3 6 2 4 8 整个队列为空...queue.isEmpty()) { Node currentNode = queue.remove();// 移除并返回 System.out.println(currentNode.e)
在二叉树中,通常使用队列来实现层序遍历,首先将根节点入队,然后不断从队列中出队节点并访问,同时将该节点的子节点入队,直到队列为空。...如果根节点为空,则返回NULL。如果根节点的值与x相等,则返回根节点。否则,它递归地在左子树和右子树中查找x。如果在左子树或右子树中找到x,则返回对应的节点。...如果在遍历过程中发现队列中出现了空节点,则立即销毁队列并返回false,因为完全二叉树在层序遍历中不应出现空节点。...如果遍历结束,即队列为空,且没有发现空节点,则销毁队列并返回true,说明是完全二叉树。 四、二叉树的选择练习题 某完全二叉树按层次输出(同一层从左到右)的序列为 ABCDEFGH 。...该完全二叉树的前序序列为( ) A、 ABDHECFG B、 ABCDEFGH C、 HDBEAFCG D、 HDEBFGCA 二叉树的先序遍历和中序遍历如下:先序遍历:EFHIGJK;中序遍历
接下来我们将会分别介绍手算和计算两种方式来构建二叉树; 3.2.1 由遍历序列手算构建二叉树 我们在做题时会遇到需要通过遍历序列手算构建二叉树的题目,如: 已知一棵二叉树的后序序列为DABEC,中序序列为...DEBAC,则先序序列为() A....那这个步骤具体可不可行,我们暂时还不清楚,下面我们就来通过题目来验证一下; 3.2.1.2 习题演练 已知一棵二叉树的后序序列为DABEC,中序序列为DEBAC,则先序序列为() A....return NULL;//返回空指针 } //创建根结点 BTN* p = (BTN*)calloc(1, sizeof(BTN)); if (!...可能有朋友会比较好奇,为什么今天的内容中没有介绍二叉树的删除?这个问题我们先进行保留,目前我们只需要了解并熟练掌握二叉树的遍历算法的基本思想即可。
当队列为空时,整棵树层序遍历完毕。还没明白请看下面过程。...A->出队 队列:E、B B->出队 队列:D、C、E E->出队 队列:G、D、C C->出队 队列:G、D D->出队 队列:G G->出队 队列为空,层序遍历完毕。...二叉树层序遍历算法代码 层序遍历函数 层序遍历核心代码,利用了一个自己底层封装的顺序队列。如果想知道怎么实现的呢,请看线性表:顺序队列算法实现。...//一排一排的遍历 利用队列的特性哟,将根结点入队列 然后然后出入队列,出队列后将其左右孩子结点入队列 //直到队列为空 void SeqTraverse(BiTree tree) { SeqQueue...tree->lchild); PreTraverse(tree->rchild); } //一排一排的遍历 利用队列的特性哟,将根结点入队列 然后然后出入队列,出队列后将其左右孩子结点入队列 //直到队列为空
此过程不断进行,当队列为空时,二叉树的层次遍历结束。 2. 原理解释 2.1. 二叉树图 一个二叉树,层次遍历就是每一行每一行的取出数据。 这个图的结果就是 ABCDEFGH 2.2....层次遍历过程图 就是先父节点进入队列,然后循环,出队时带入下一组子节点进队,没有就没有进入队列的,当队列为空时结束循环。 3....空-返回真,不空-返回假 if (q->front == q->rear) { return true; } return false; } // 进队列...空(取出失败)-返回假,不空(取出成功)-返回真 if (q->front == q->rear) { return false; } q->front...); // 递归,先序遍历左子树 preOrder(BT->rchild); // 递归,先序遍历右子树 } } // 中序遍历 void inOrder(BTNode
提示 从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立), [测试数据] 如输入:ABC##DE#G##F###(其中#表示空格字符) 则输出结果为 先序:ABCDEGF...CreateBiTree(BiTree *T) ///BiTNode T { char ch; ch=getchar(); if(ch=='#')(*T)=NULL;///#代表空指针...\n(Create a Binary Tree )建立一棵二叉树T:\n"); CreateBiTree(&T);///建立一棵二叉树 printf("\nThe preorder(先序序列为...)is:\n"); PreOrder(T); printf("\nThe inorder(中序序列为)is:\n"); InOrder(T); printf("\nThe...Postorder(后序序列为)is:\n"); Postorder(T); printf("\nThe levle order(层次序列为)is:\n"); LevleOrder
该完全二叉树的前序序列为( ) A ABDHECFG B ABCDEFGH C HDBEAFCG D HDEBFGCA 2.二叉树的先序遍历和中序遍历如下:先序遍历:EFHIGJK;中序遍历...:HFIEJKG.则二叉树根结点为 () A E B F C G D H 3.设一课二叉树的中序遍历序列:badce,后序遍历序列:bdeca,则二叉树前序遍历序列为____。...} 4.4前序,中序,后序(深度优先遍历) // 先序遍历二叉树 void PrevOrder(BTNode* root) { // 如果当前节点为空,则打印"NULL"并返回 if (root...即树为空),则直接返回,不执行任何操作 if (root == NULL) { return; } else // 如果根节点不为空(即树非空) { //...2、多个 if (pq->head->next == NULL) { free(pq->head);//释放队头的空间 pq->head = pq->tail = NULL; //队列为空
在左子树中访问D根结点,而D中没有左子树和右子树,返回访问B的右子树; 4. B的右子树不存在,返回访问A的右子树; 5. 在右子树中访问C根结点,进入C结点的左子树; 6....在左子树中访问E根结点,而E中没有左子树和右子树,返回访问C的右子树; 7. 在右子树中访问F根结点,F中没有左子树和右子树,遍历结束。...我们打断点调试会发现size的值是从6开始的,这是为什么呢? 很明显,size被static修饰延长了生命周期,使得该变量不再是因为栈空间的结束而销毁。因此,该做法是不可取的。...层序遍历 建议看完此篇。...删除队头元素同时将队头的左孩子和右孩子入队列(存在情况下); 如此循环下去,直到队列为空完成了层序遍历。
1.什么是层序遍历? 除了先序遍历、中序遍历、后序遍历外,还可以对二叉树进行层序遍历。...设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历...= NULL) { perror("malloc fail"); return; } newnode->data = data; newnode->pNext = NULL; //队列为空的情况入队列...pNext; count++; } return count; } // 检测队列是否为空,如果为空返回true,非空返回false bool QueueEmpty(Queue* q) { assert...QueueEmpty(q));//判断队列非空 while (q->front) { QueuePop(q); } } //队列的特点是先进先出 3.结语 层序遍历关键点在于它对于队列的使用与理解
(若队列中没有元素,deleteHead 操作返回) 2 方法 定义两个栈stackln和 stackOut:前者对应上面分析的第一个栈,只用于尾部插入;后者对应第二个栈,只用于头部删除。...尾部插入:无脑压入新数字到 stackln 头部删除: 如果stackOut不是空,弹出栈顶;如果stackOut是空,分为两种情况: 如果stackln也是空,代表队列为空,返回-1;否则就将 stackln...self.stackout: # stackOut还有数字,直接pop return self.stackout.pop() if not self.stackIn: # stackIn也没有数字,队列为空...return -1 while self.stackIn: # 将stackIn的数字倒序导入stackout中 self.stack0ut.append(self.stackIr # 弹出stackout...如果两个栈都没有数字,就返回-1。通过本次实验,证明该方法是有效的。此方法还略微有些不足,希望以后能运用更好的方法来实现。
二叉树遍历方法 二叉树的遍历方式可以有很多,如果我们限制从左到右的顺序,就主要分为四种: 前序遍历 中序遍历 后序遍历 层序遍历 1、前序遍历 若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树...2、中序遍历 若二叉树为空,则空操作返回,否则从根结点开始(注意并不是先访问根结点),中序遍历根结点左子树,然后访问根结点,最后中序遍历右子树,如下图遍历顺序为:GDHBAEICF。 ?...3、后序遍历 若二叉树为空,则空操作返回,否则从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点,如下图遍历顺序为:GHDBIEFCA。 ?...4、层序遍历 若二叉树为空,则空操作返回,否则从树的第一层开始,也就是从根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问,如下图遍历顺序为:ABCDEFGHI。 ?...三种遍历都是从根结点开始,前序遍历是先打印再递归左和右,所有前序遍历序列为ABCDEF,第一个字母A就是根结点;再由中序遍历序列CBAEDF,可以只带C和B是A的左子树上的结点,E、D、F是A的右子树上的结点
删除元素接口: remove() -> 删除队列头元素并返回该元素,如果队列为空抛出NoSuchElementException异常。...E poll() -> 删除队列头元素并返回该元素,如果队列为空返回null(与remove不同)。...获取队列头元素接口: E element() -> 返回队列头部元素(没有删除),如果队列为空抛出NoSuchElementException异常。...E peek() -> 返回队列头部元素(没有删除),如果队列为空返回null。...= 0) siftDown(0, x);//《6》 return result; } 《1》如果队列为空,返回null。 《2》队列元素总数减1。