树基本知识

根结点:非空树的第一个结点,也就是所有结点的曾曾曾…祖先

叶子结点:就是每个分支的终端结点。

双亲结点:孩子的父母就称为双亲结点。
(个人理解:分支的妈妈就是双亲结点,至于为什么树都称为双亲,我认为是为了二叉树的方便使用,因为二叉树只有两个孩子,两个孩子的母亲,就是双亲结点。)

兄弟结点
1、所在层次一样。
2、双亲结点一样,也就是需要是同一个妈生的才是兄弟。这些都称为兄弟结点。

堂兄弟结点
1、所在层次一样。
2、双亲结点不一样,必须是不同妈生的才是堂兄弟。这些结点称为堂兄弟结点。

结点的度:顾名思义就是每一个结点所拥有的的度,度就是该结点的孩子有多少个(分支有多少),比如叶子的度就是0,该定义和树的度结合使用。

树的度:顾名思义就是一棵树的度,并且是树中各个结点的度的最大值。
简单来说一棵树中找到分支最多的那一个结点代表树的度。

数的深度:所含层次数,即结点的最大层次,也可以称为树的高度。

二叉树的性质

二叉树顾名思义每一个结点最多有两个孩子,即左右孩子(分支)
因此结构体内的date域要有两个。

性质1:二叉树的第 i 层上至多有

2

i

1

2^i{^-}{^1}

2i−1个结点。(

i

1

i \ge 1

i≥1 )
该性质在满二叉树的情况下得出

因为每一层上都是2的次方个数,二叉树每一个结点都拥有左右孩子,每增加一层就,该层的结点都会增加两个孩子,所以是2的次方个数。
二叉树严格遵守左右之分,这是二叉树所特有的,和树不一样。

性质2:深度为 k 的二叉树至多有

2

k

2^k

2k - 1个结点。(

k

1

k \ge 1

k≥1 )
该性质在满二叉树的情况下得出

我们得知了性质1,每一层的结点数,那么我们现如今又知道了层数k,只要我们用求和公式把每一层结点数加起来即可。
又因为性质1的每一层之间是等比数列,所以只要用等比数列求和公式即可轻松得出结果。

性质3:对于任何一棵二叉树T,如果其叶子数为n

0

_0

0​,其具有左右孩子的结点数为n

2

_2

2​,
那么有:n

0

_0

0​ = n

2

_2

2​ + 1。

我的理解有两种描述:(不严谨,仅做辅助记忆)
①当只有一个根节点连着两个孩子结点,那么就是一个双亲加两片叶子,也就是根节点1+1 = 叶子数,从而得知该性质是成立。
②假如有2个双亲结点,那么对应的就会有3片叶子。为什么会这样?
原因是根节点必然会连着另一个双亲结点和一片叶子,而另一个双亲结点必然是连着两片叶子,这样才能对得上2个双亲对应三片叶子。

满二叉树

满二叉树,名如其物,每一层都是满的。
简单来说就是k层,当最后一层也是满叶子结点即称满二叉树。
利用性质2:当最后一层的叶子结点数 =

2

k

1

2^k{^-}{^1}

2k−1的时候就是满二叉树。
当最后一层k层的叶子结点数是

2

k

1

2^k{^-}{^1}

2k−1的时候,也从而得知其k层往上的结点数也都是满的,也能用

2

k

1

2^k{^-}{^1}

2k−1计算得出当前层数的结点数。

完全二叉树

完全二叉树晦涩难懂
用我的理解:
对满二叉树进行按层数进行编号(如下如图),每一层从左到右进行递增编号码,并且在完全二叉树中这些编号是确定的。
完全二叉树就是必须让这些编号是递一递增的,不能中间缺一个,但是你可以从尾部一个一个减掉,比如减掉15这个叶子结点后仍然是完全二叉树,满二叉树也是一个完全二叉树。
但是如果你跳过15,不是从15开始慢慢减1,那么就是中间缺了一块,就不是完全二叉树了。

总结结论:
因为我们如果想变化完全二叉树,必须是从后的k层的最右边开始操作,上图的15就是最尾部。
如果满二叉树,想要添加一个结点仍想要让他是完全二叉树,就得另起一层,仍旧是从左到右进行添加。
想要减少一个结点仍想要让他是完全二叉树,就从最后一层的最右边开始减。
因此我们知道完全二叉树必然是左孩子层数大于等于右孩子的层数,毕竟我们减孩子是从右边减,加孩子的时候要么层数相等,如果满叶子了,要加一层的时候,又变成了从左孩子开始加。如此一来,一直都是左孩子的层数大于等于右孩子的层数。

性质4、5的解释

性质4:具有n个结点数的完全二叉树的深度为:[

l

o

g

2

n

log_2n

log2​n ]+ 1
(log求出的数是取小于以二为底的次方数,取的就是小于该次方数的数。
求出n = 2

3

.

5

^3{^.}{^5}

3.5,我们取得是3,而不是4)

我的解释:首先拿满二叉树来作为例子,因为满二叉树也是完全二叉树。我们知道一个满二叉树的总结点数是:

2

k

2^k

2k-1,log

2

_2

2​(

2

k

2{^k}

2k-1)的结果必然小于k ,因为

2

k

2^k

2k-1取以2为低的对数后必然小于k, 性质解释了,要取小于k的数,我们就取k-1,那么完成后,性质的公式还有一个+1,k-1+1正好就是等于k, k就是该满二叉树的深度。

性质5:如果对一棵树有n个结点的完全二叉树,其深度是[

l

o

g

2

n

log_2n

log2​n] + 1,的结点按层照完全二叉树的编号排好顺序,那么对于任意一个编号为 i 的结点都有 ↓

(1)如果 i = 1, 则结点 i 是二叉树的根, 无双亲;

\qquad 如果

如果 i > 1, 则其双亲结点:[

i

2

\frac{i}{2}

2i​ ]
我的理解:因为性质4的铺垫,取小于k的数,所以在这里同样也是。
如下图,i > 1的时候,双亲结点除以2一定等于他的左孩子,所以 i / 2 的时候,
有小数点就去掉小数点,要较小值,其值就是 i 的双亲结点。

(2)如果2i > n , 则结点 i 为叶子结点, 无左孩子;

\qquad 否则

否则其左孩子为 2i。
我的理解:其实很容易理解,因为(1)中解释道,左孩子i /2 就等于双亲结点,那么我们反过来想想,双亲结点乘以2就应该等于他的左孩子,因此,假设在完全二叉树的情况下,2i 不等于总结点数n 的话,肯定就证明了 i 这个双亲结点没有左孩子,又因为是完全二叉树,该结点没有了左孩子必然没有右孩子。所以如果2i等于n的时候,利用(1)的结论可得知,结点为 i 的时候,他的叶子是2i,这里的 i 和(1)中不一样,(1)中是叶子结点为i,(2)这里 i说的是双亲结点为i ,所以2i 就是其叶子的左孩子结点。

(3)如果2i +1 > n ,则结点 i + 1 没有右孩子;

\qquad 否则

否则其右孩子结点为2i + 1。
结论(3)是由(2)得知的,如果2i = n,那么2i + 1 必然是 i 这个结点有左孩子没有右孩子。
如果 2i + 1 = n 很显然是个奇数,奇数必然是右孩子。

顺序存储结构(利用性质4、5)

这两个性质主要是应用于当二叉树是用顺序存储结构。
之所以完全二叉树可以用顺序存储结构来存储和建立,得益于他的编号是有顺序的,因此这也是为什么前面强调完全二叉树必须是从上到下从左到右依次逐1递增来编号的。

通过用一个顺序数组即可表示出完全二叉树。
通过一个顺序存储结构的数组也可以还原出一个完全二叉树。

数组大小

2

k

2^k

2k - 1

缺点:很明显,如果最后一层只有最左边的节点有一个左孩子,那么这一层剩下的空间就浪费了,因为我们知道层数深度是直接开辟

2

k

2^k

2k - 1个空间,当 k 非常大的时候就会很浪费空间,所以一般只有满二叉树的时候是刚好能用完这些空间。

不是完全二叉树是否可以用顺序存储结构来存储一个二叉树?
答案是完全可以的,研究完全二叉树是为了抛砖引玉,解释一些有规律的,即使不是完全二叉树,我们照样可以给该二叉树进行按顺序编号,只是他中间会有缺漏,并不是完全二叉树罢了。
这时候细细想想,一般的二叉树按照满二叉树的有序编号来编写,这时候中间缺漏的东西会更多,也就意味着数组中浪费的空间更多。

链式存储结构

链式存储结构是重点,也是最常用的存储二叉树的方式。
建立二叉树、遍历二叉树、计算二叉树的结点数和叶子数都是利用递归算法的思想进行操作。

结点结构体

typedef struct _BiTree{

	char num;
struct _BiTree* right;
struct _BiTree* left; }BiTree, *to_BiTree; //链式二叉树结构体

建立二叉树

有一个细节千万不能漏掉。
因为递归算法会直接调用函数本身
当你用scanf进行录入的时候切记一定要把多余的空格吸收掉,不然会导致建立二叉树失败。
原因很简单:因为缓冲区不会把你的回车键吸收,而是自动的把回车键给下个调用函数的scanf接收。

void Create_tree(to_BiTree* Tree)
{
char n;
char temp;
scanf("%c", &n);
temp = getchar();//吸收空格 很重要
if(n =='#')
{
(*Tree) = NULL;
}
else
{
(*Tree) = (to_BiTree)malloc(sizeof(BiTree));
(*Tree)->num = n;
Create_tree(&(*Tree)->left);
Create_tree(&(*Tree)->right);
} return;
}

先序遍历

根 左 右

void First_traverse(to_BiTree Tree)
{
if(!Tree) return;
printf("%c", Tree->num);
First_traverse(Tree->left);
First_traverse(Tree->right); }

中序遍历

左 根 右

void Mid_traverse(to_BiTree Tree)
{
if(!Tree) return;
Mid_traverse(Tree->left);
printf("%c", Tree->num);
Mid_traverse(Tree->right);
}

后序遍历

左 右 根

void End_traverse(to_BiTree Tree)
{
if(!Tree) return;
End_traverse(Tree->left);
End_traverse(Tree->right);
printf("%c", Tree->num);
}

层次遍历

顾名思义就是一层一层的遍历。
该算法要用到队列的思想。
因为我们要实现一层一层的遍历必须要记录该层次的结点,然后遍历,然后用该层的结点进入下一层。
也就是先进先出的意思,第一层先入队,然后出队,然后第二层进队,然后出队

\dots

队列的结构体代码

#define MAXSIZE 50
typedef struct _SqQueue{ struct _BiTree* date[MAXSIZE];
int front;//头指针
int rear;//尾指针
}SqQueue;

层次遍历代码

void Level_traverse(to_BiTree Tree) //层次遍历
{
SqQueue Sq;
to_BiTree temp;
InitQueue(&Sq);
EnQueue(&Sq, Tree);
while(IsSqEmpty(Sq))
{
DeQueue(&Sq, &temp);
//printf("測試測試");
printf("%c",temp->num);
if(temp->left) EnQueue(&Sq, temp->left);
if(temp->right) EnQueue(&Sq, temp->right);
}
}
void InitQueue(SqQueue*Sq)//队列初始化
{
Sq->front = 0;
Sq->rear = 0;
} bool IsSqEmpty(SqQueue Sq)//判断队列是否为空
{
if(Sq.rear == Sq.front) return false;
else return true;
} void EnQueue(SqQueue*Sq, to_BiTree Tree) //进队
{
Sq->date[Sq->rear] = Tree;
Sq->rear++; } void DeQueue(SqQueue*Sq, to_BiTree* temp) //出队
{
(*temp) = Sq->date[Sq->front];
Sq->front++;
}

复制二叉树

int Copy_Tree(to_BiTree* NewT, to_BiTree Tree)
{ if(!Tree)
{
(*NewT) = NULL;
return 0;
}
else
{
(*NewT) = (to_BiTree)malloc(sizeof(BiTree));
(*NewT)->num = Tree->num;
Copy_Tree(&(*NewT)->left, Tree->left);
Copy_Tree(&(*NewT)->right, Tree->right);
}
}

计算二叉树深度

int Depth_Tree(to_BiTree Tree)
{
int m, n;
if(!Tree) return 0;
else
{
m = Depth_Tree(Tree->left);
n = Depth_Tree(Tree->right);
//m>n初始化的时候是0,所以第一次搜索到叶子的孩子为NULL的时候,都会返回一个0,回到叶子就是return 1
if(m>n) return (m+1);
else return (n+1);
}
}

计算二叉树的结点总个数

int NodeCount_Tree(to_BiTree Tree)
{
if(!Tree) return 0;
else return NodeCount_Tree(Tree->left) + NodeCount_Tree(Tree->right) + 1;
}

计算二叉树的叶子结点数

int LeavesCount_Tree(to_BiTree Tree)
{
if(!Tree) return 0;
if(!Tree->left && !Tree->right) return 1;
else return LeavesCount_Tree(Tree->left) + LeavesCount_Tree(Tree->right);
//因为最后那个叶子总是没有左右孩子的,所以总会返回1,因此这里不用额外+1
}

释放申请的空间

void Free_Tree(to_BiTree* Tree)
{
to_BiTree temp = (*Tree);
if(!(*Tree)) return;
Free_Tree(&(*Tree)->left);
Free_Tree(&(*Tree)->right);
free((*Tree));
(*Tree) = NULL;
}

程序的完整代码

可以试着按照该样例进行录入: ABC##DE#G##F###

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct _BiTree{
char num;
struct _BiTree* right;
struct _BiTree* left;
}BiTree, *to_BiTree; //链式二叉树结构体 #define MAXSIZE 50
typedef struct _SqQueue{
struct _BiTree* date[MAXSIZE];
int front;//头指针
int rear;//尾指针
}SqQueue; void Create_tree(to_BiTree* Tree);//生成二叉树 void First_traverse(to_BiTree);//先序遍历 void Mid_traverse(to_BiTree Tree);//中序遍历 void End_traverse(to_BiTree Tree);//后序遍历 void Level_traverse(to_BiTree Tree);//层次遍历
void InitQueue(SqQueue*);//初始化队列
bool IsSqEmpty(SqQueue Sq);//判断队列是否为空
void EnQueue(SqQueue*,to_BiTree);//入队
void DeQueue(SqQueue*, to_BiTree*);//出队 int Copy_Tree(to_BiTree*, to_BiTree);//把旧树复制到一个新树中,第一个参数是新书,第二个参数是旧树 int Depth_Tree(to_BiTree);//计算树的深度 int NodeCount_Tree(to_BiTree);//计算树的结点数 int LeavesCount_Tree(to_BiTree Tree);//计算树的叶子的节点数。注意:若一个结点有两个叶子,那就是一个结点 int main()
{ to_BiTree Tree = NULL, NewT = NULL;
/*
让用户输入数据生成二叉树
1:对二叉树进行三种不同的遍历
2:实现非递归的三种遍历方式
a:首先实现中序的非递归算法,实现成功后再实现剩下的两种非递归的遍历二叉树方式
*/
//ABC##DE#G##F###
Create_tree(&Tree);
printf("以下是三种不同的遍历方式");
printf("\n先序遍历:");
First_traverse(Tree);
printf("\n中序遍历:");
Mid_traverse(Tree);
printf("\n后序遍历:");
End_traverse(Tree);
printf("\n层次遍历:");
Level_traverse(Tree); Copy_Tree(&NewT, Tree);
printf("\n(复制)中序遍历:");
Mid_traverse(NewT); int count = Depth_Tree(Tree);
printf("\n树的深度:%d",count); count = NodeCount_Tree(Tree);
printf("\n树的总结点数:%d", count); count = LeavesCount_Tree(Tree);
printf("\n树的叶子的总结点数:%d", count);
Free_Tree(&Tree);
if(Tree)
{
printf("\n先序遍历:");//如果没有释放完全还有漏的话,用一个先序遍历测试一下情况是怎样,但很明显我是不会失败的 hhhh
First_traverse(Tree);
}
else
{
printf("\n树已被释放为空");
} return 0;
} void Create_tree(to_BiTree* Tree)
{
char n;
char temp;
scanf("%c", &n);
temp = getchar();//吸收空格 很重要
if(n =='#')
{
(*Tree) = NULL;
}
else
{
(*Tree) = (to_BiTree)malloc(sizeof(BiTree));
(*Tree)->num = n;
Create_tree(&(*Tree)->left);
Create_tree(&(*Tree)->right);
} return;
} void First_traverse(to_BiTree Tree)
{
if(!Tree) return;
printf("%c", Tree->num);
First_traverse(Tree->left);
First_traverse(Tree->right); } void Mid_traverse(to_BiTree Tree)
{
if(!Tree) return;
Mid_traverse(Tree->left);
printf("%c", Tree->num);
Mid_traverse(Tree->right);
} void End_traverse(to_BiTree Tree)
{
if(!Tree) return;
End_traverse(Tree->left);
End_traverse(Tree->right);
printf("%c", Tree->num);
} void Level_traverse(to_BiTree Tree)
{
SqQueue Sq;
to_BiTree temp;
InitQueue(&Sq);
EnQueue(&Sq, Tree);
while(IsSqEmpty(Sq))
{
DeQueue(&Sq, &temp);
//printf("測試測試");
printf("%c",temp->num);
if(temp->left) EnQueue(&Sq, temp->left);
if(temp->right) EnQueue(&Sq, temp->right);
}
} void InitQueue(SqQueue*Sq)
{
Sq->front = 0;
Sq->rear = 0;
} bool IsSqEmpty(SqQueue Sq)
{
if(Sq.rear == Sq.front) return false;
else return true;
} void EnQueue(SqQueue*Sq, to_BiTree Tree)
{
Sq->date[Sq->rear] = Tree;
Sq->rear++; } void DeQueue(SqQueue*Sq, to_BiTree* temp)
{
(*temp) = Sq->date[Sq->front];
Sq->front++;
} int Copy_Tree(to_BiTree* NewT, to_BiTree Tree)
{ if(!Tree)
{
(*NewT) = NULL;
return 0;
}
else
{
(*NewT) = (to_BiTree)malloc(sizeof(BiTree));
(*NewT)->num = Tree->num;
Copy_Tree(&(*NewT)->left, Tree->left);
Copy_Tree(&(*NewT)->right, Tree->right);
}
} int Depth_Tree(to_BiTree Tree)
{
int m, n;
if(!Tree) return 0;
else
{
m = Depth_Tree(Tree->left);
n = Depth_Tree(Tree->right);
if(m>n) return (m+1);//m>n初始化的时候是0,所以第一次搜索到叶子的孩子为NULL的时候,都会返回一个0,回到叶子就是return 1
else return (n+1);
}
} int NodeCount_Tree(to_BiTree Tree)
{
if(!Tree) return 0;
else return NodeCount_Tree(Tree->left) + NodeCount_Tree(Tree->right) + 1;
} int LeavesCount_Tree(to_BiTree Tree)
{
if(!Tree) return 0;
if(!Tree->left && !Tree->right) return 1;
else return LeavesCount_Tree(Tree->left) + LeavesCount_Tree(Tree->right);
//因为最后那个叶子总是没有左右孩子的,所以总会返回1,因此这里不用额外+1
}
void Free_Tree(to_BiTree* Tree)
{
to_BiTree temp = (*Tree);
if(!(*Tree)) return;
Free_Tree(&(*Tree)->left);
Free_Tree(&(*Tree)->right);
free((*Tree));
(*Tree) = NULL;
}

收获

二叉树整体给我的感觉就是递归递归递归,
让我对递归算法有了更好的理解,
其次是一个意外的收获,高中时期没能彻底的理解对数的概念,
反倒研究二叉树的时候茅塞顿开。
(数学渣渣想学好计算机真的难┭┮﹏┭┮)

C数据结构:二叉树的基本操作的更多相关文章

  1. C语言实现二叉树的基本操作

    二叉树是一种非常重要的数据结构.本文总结了二叉树的常见操作:二叉树的构建,查找,删除,二叉树的遍历(包括前序遍历.中序遍历.后序遍历.层次遍历),二叉搜索树的构造等. 1. 二叉树的构建 二叉树的基本 ...

  2. 二叉树的基本操作(C语言版)

    今天走进数据结构之二叉树 二叉树的基本操作(C 语言版) 1 二叉树的定义 二叉树的图长这样: 二叉树是每个结点最多有两个子树的树结构,常被用于实现二叉查找树和二叉堆.二叉树是链式存储结构,用的是二叉 ...

  3. <二叉树的基本操作(有层次遍历)>

    #include<stdio.h> #include<stdlib.h> #include<string.h> #define num 100 #define OK ...

  4. <二叉树的基本操作>

    #include<stdio.h> #include<stdlib.h> #include<string.h> #define num 100 #define OK ...

  5. 实现二叉树的基本操作(Java版)

    近期研究了一下二叉树,试着用Java语言实现了二叉树的基本操作,下面分享一下实现代码: package com.sf.test; import java.util.ArrayDeque; import ...

  6. c语言描述的二叉树的基本操作(层序遍历,递归,非递归遍历)

    #include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define ...

  7. 什么是泛型?,Set集合,TreeSet集合自然排序和比较器排序,数据结构-二叉树,数据结构-平衡二叉树

    ==知识点== 1.泛型 2.Set集合 3.TreeSet 4.数据结构-二叉树 5.数据结构-平衡二叉树 ==用到的单词== 1.element[ˈelɪmənt] 要素 元素(软) 2.key[ ...

  8. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  9. 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java

    前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...

  10. 数据结构——二叉树(Binary Trees)

    非线性数据结构 二叉搜索树(Binary Search Tree) 树的密度=结点数/高度 二叉树类 #pragma once class stnode { public: int nodeValue ...

随机推荐

  1. #分层图最短路,Dijkstra#洛谷 4568 [JLOI2011]飞行路线

    题目 一个无向图,每条边都有花费,可以有\(k\)次挑选边去除花费的机会,问从指定起点到指定终点的最小花费 分析 考虑用分层最短路完成,也就是在同一层走需要花费,不同层走不用花费,最终走到最底层,然后 ...

  2. 深入理解java的泛型

    目录 简介 泛型和协变 泛型在使用中会遇到的问题 类型擦除要注意的事项 总结 简介 泛型是JDK 5引入的概念,泛型的引入主要是为了保证java中类型的安全性,有点像C++中的模板. 但是Java为了 ...

  3. Python 注释:解释和优化代码可读性

    注释可以用来解释Python代码.注释可以用来使代码更易读.注释可以用来在测试代码时防止执行. 创建注释 注释以#开始,Python会忽略它们: 示例:获取您自己的Python注释 # 这是一个注释 ...

  4. Numpy通用函数及向量化计算

    Python(Cpython)对于较大数组的循环操作会比较慢,因为Python的动态性和解释性,在做每次循环时,必须做数据类型的检查和函数的调度. Numpy为很多类型的操作提供了非常方便的.静态类型 ...

  5. xml转voc数据集(含分享数据集)

    数据集的链接:行人检测数据集voc数据集(100张) 原始图片和.xml数据目录结构如下: . └── data ├── 003002_0.jpg ├── 003002_0.xml ├── 00300 ...

  6. python3中os.renames()和os.rename()区别

    renames源码:def renames(old, new): head, tail = path.split(new) # 作用是分割为两部分,head为路径,tail为文件名: if head ...

  7. Java中list集合深复制

    import org.apache.commons.collections.CollectionUtils; import java.util.ArrayList; import java.util. ...

  8. web开发可不可以是这样的?

    service不外乎就是数据校验,调用其它service,调用第三方api,读写数据库,既然这样,那我认为Service也可以做成可配置化的样子,配置项大致有 所需参数配置:参数列表,参数类型,参数长 ...

  9. 力扣550(MySQL)-游戏玩法分析Ⅳ(中等)

    题目: 需求:编写一个 SQL 查询,报告在首次登录的第二天再次登录的玩家的分数,四舍五入到小数点后两位.换句话说,您需要计算从首次登录日期开始至少连续两天登录的玩家的数量,然后除以玩家总数. 查询结 ...

  10. HarmonyOS NEXT应用开发案例—状态栏显隐变化

    介绍 本示例介绍使用Scroll组件的滚动事件 onScroll 实现状态栏显隐变化.该场景多用于各种软件的首页.我的等页面中. 效果预览图 使用说明 加载完成后显示状态栏显隐变化页面,上下拖动屏幕, ...