Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
CharonChui committed Sep 14, 2024
1 parent 99dba19 commit da95ba3
Show file tree
Hide file tree
Showing 5 changed files with 378 additions and 6 deletions.
31 changes: 31 additions & 0 deletions JavaKnowledge/数据结构和算法/数据结构.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,24 @@

按照视点的不同,我们把数据结构分为逻辑结构和物理结构。

数据结构(data structure)是组织和存储数据的方式,涵盖数据内容、数据之间关系和数据操作方法,它具有以下设计目标。

- 空间占用尽量少,以节省计算机内存。
- 数据操作尽可能快速,涵盖数据访问、添加、删除、更新等。
- 提供简洁的数据表示和逻辑信息,以便算法高效运行。
- 数据结构设计是一个充满权衡的过程。如果想在某方面取得提升,往往需要在另一方面作出妥协。

下面举两个例子:

- 链表相较于数组,在数据添加和删除操作上更加便捷,但牺牲了数据访问速度。
- 图相较于链表,提供了更丰富的逻辑信息,但需要占用更大的内存空间。



#### 逻辑结构

逻辑结构:是指数据对象中数据元素之间的相互关系。其实这也是我们今后最需要关注的问题。逻辑结构分为以下四种:

- 集合结构
集合结构:集合结构中的数据元素除了同属于一个集合外,它们之间没有其他关系。各个数据元素是“平等”的,它们的共同属性是"同属于一个集合"。
数据结构中的集合关系就类似于数学中的集合
Expand All @@ -23,7 +39,9 @@
图形结构:图形结构的数据元素是多对多的关系

#### 物理结构

物理结构(也称为存储结构):是指数据的逻辑结构在计算机中的存储形式。

- 顺序存储结构
顺序存储结构:是把数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的
这种存储结构其实很简单,说白了,就是排队占位。大家都按顺序排好,每个人占一小段空间,大家谁也别插谁的队。数组就是这
Expand Down Expand Up @@ -168,8 +186,21 @@ int[] arr = new int[10];
#### 栈的应用-递归

把一个直接调用自己或通过一系列的调用语句间接地调用自己的函数,称做递归函数。

当然,写递归程序最怕的就是陷入永不结束的无穷递归中,所以,每个递归定义必须至少有一个条件,满足时递归不再进行,即不再引用自身而是返回值退出。

递归(recursion)是一种算法策略,通过函数调用自身来解决问题。它主要包含两个阶段:

- 递:程序不断深入地调用自身,通常传入更小或更简化的参数,直到达到“终止条件”。
- 归:触发“终止条件”后,程序从最深层的递归函数开始逐层返回,汇聚每一层的结果。

而从实现的角度看,递归代码主要包含三个要素:

- 终止条件:用于决定什么时候由“递”转“归”。
- 递归调用:对应“递”,函数调用自身,通常输入更小或更简化的参数。
- 返回结果:对应“归”,将当前递归层级的结果返回至上一层。


那么我们讲了这么多递归的内容,和栈有什么关系呢?这得从计算机系统的内部说起。前面我们已经看到递归是如何执行它的前行和退回阶段的。
递归过程退回的顺序是它前行顺序的逆序。在退回过程中,可能要执行某些动作,包括恢复在前行过程中存储起来的某些数据。这种存储某些数据,
并在后面又以存储的逆序恢复这些数据,以提供之后使用的需求,显然很符合栈这样的数据结构,因此,编译器使用栈实现递归就没什么好惊讶的了。
Expand Down
36 changes: 34 additions & 2 deletions JavaKnowledge/数据结构和算法/算法.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
算法
===

算法(Algorithm)是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。

算法(algorithm)是在有限时间内解决特定问题的一组指令或操作步骤,它具有以下特性:

- 问题是明确的,包含清晰的输入和输出定义。
- 具有可行性,能够在有限步骤、时间和内存空间下完成。
- 各步骤都有确定的含义,在相同的输入和运行条件下,输出始终相同。


算法具有五个基本特性:
Expand All @@ -17,6 +22,21 @@
算法的每一步都必须是可行的,也就是说,每一步都能够通过执行有限次数完成


在算法设计中,我们先后追求以下两个层面的目标。

- 找到问题解法:算法需要在规定的输入范围内可靠地求得问题的正确解。
- 寻求最优解法:同一个问题可能存在多种解法,我们希望找到尽可能高效的算法。

也就是说,在能够解决问题的前提下,算法效率已成为衡量算法优劣的主要评价指标,它包括以下两个维度:

- 时间效率:算法运行时间的长短。
- 空间效率:算法占用内存空间的大小。

简而言之,我们的目标是设计“既快又省”的数据结构与算法。而有效地评估算法效率至关重要,因为只有这样,我们才能将各种算法进行对比,进而指导算法设计与优化过程。





### 算法时间复杂度

Expand Down Expand Up @@ -291,7 +311,19 @@ public static int[] merge(int[] a, int[] b) {
}
return result;
}
````
```


数据结构与算法高度相关、紧密结合,具体表现在以下三个方面:

- 数据结构是算法的基石。数据结构为算法提供了结构化存储的数据,以及操作数据的方法。
- 算法是数据结构发挥作用的舞台。数据结构本身仅存储数据信息,结合算法才能解决特定问题。
- 算法通常可以基于不同的数据结构实现,但执行效率可能相差很大,选择合适的数据结构是关键。



![Image](https://raw.githubusercontent.com/CharonChui/Pictures/master/algorithm_datasturcture.jpg?raw=true)



---
Expand Down
180 changes: 180 additions & 0 deletions Jetpack/ui/Jetpack Compose_Modifier.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# Jetpack Compose_Modifier

在传统开发中,使用XML文件来描述组件的样式,而Jetpack Compose设计了一个精妙的东西,它叫作Modifier。Modifier允许我们通过链式调用的写法来为组件应用一系列的样式设置,如边距、字体、位移等。在Compose中,每个基础的Composable组件都有一个modifier参数,通过传入自定义的Modifier来修改组件的样式。



- Modifier.size

设置被修饰组件的大小。

- Modifier.background

添加背景色,支持使用color设置纯色背景,也可以使用brush设置渐变色背景。

传统视图中View的background属性可以用来设置图片格式的背景,Compose的background修饰符只能设置颜色背景,图片背景需要使用Box布局配合Image组件实现。

- Modifier.fillMaxSize

组件在高度或宽度上填满父空间,此时可以使用fillMaxXXX系列方法:

Box(Modifier.fillMaxSize().background(Color.Red))
Box(Modifier.fillMaxWidth().height(60.dp))
Box(Modifier.fillMaxHeight().width(60.dp))


```kotlin
setContent {
Image(
painter = painterResource(id = R.drawable.ic_launcher_background),
contentDescription = null,
modifier = Modifier
.size(width = 60.dp, height = 50.dp)
.background(
brush = Brush.verticalGradient(
colors = listOf(
Color.Red,
Color.Yellow,
Color.White
)
)
)
)
}
```


- Modifier.border & Modifier.padding

border用来为组件添加边框。
边框可以指定颜色、粗细以及通过Shape指定形状,比如圆角矩形等。

padding用来为被修饰组件增加间隙,可以在border前后各插入一个padding用来为为组件增加对外和对内的间距,例如:

```kotlin
@Preview
@Composable
fun BoxTest() {
Box(
modifier = Modifier
.padding(10.dp)
.border(2.dp, Color.Red, shape = RoundedCornerShape(2.dp))
.padding(20.dp)
) {
Spacer(
modifier = Modifier
.size(10.dp, 10.dp)
.background(Color.Green)
)
}
}
```

相对于传统布局有Margin和Padding之分,Compose中只有padding这一种修饰符,根据在调用链中的位置不同发挥不同的作用。

Modifier调用顺序会影响最终UI的呈现效果。
这是因为Modifier会由于调用顺序不同而产生不同的Modifier链,Compose会按照Modifier链来顺序完成页面测量布局和渲染。


## 作用域限定

Compose充分发挥了Kotlin的语法特性,让某些Modifier修饰符只能在特定作用域中使用,有利于类型安全的调用它们。

所谓的作用域,在Kotlin中就是一个带有Receiver的代码块。

例如Box组件参数中的content就是一个Receiver类型为BoxScope的代码块,因此其子组件都处于BoxScope作用域中。

```kotlin
inline fun Box(
modifier: Modifier = Modifier,
contentAlignment: Alignment = Alignment.TopStart,
propagateMinConstraints: Boolean = false,
content: @Composable BoxScope.() -> Unit
)

Box {
// 该代码块Receiver类型即为BoxScope
}
```


- matchParentSize

matchParentSize是只能在BoxScope中使用的作用域限定修饰符。
当使用matchParentSize设置尺寸时,可以保证当前组件的尺寸与父组件相同。
而父组件默认的是wrapContent,会根据子组件的尺寸确定自身的尺寸。

而如果使用fillMaxSize取代matchParentSize,那么该组件的尺寸会被设置为父组件所允许的最大尺寸,这样会导致铺满整个屏幕。
```kotlin
@Composable
// 只把UserInfo区域设置背景
fun MatchParentModifierDemo() {
Box {
Box(modifier = Modifier
.matchParentSize()
.background(Color.RED)
)
UserInfo()
}
}


// 使用fillMaxSize取代matchParentSize,那么该组件的尺寸会被设置为父组件所允许的最大尺寸,这样会导致整个背景铺满整个屏幕
@Composable
fun MatchParentModifierDemo() {
Box {
Box(modifier = Modifier
.fillMaxSize()
.background(Color.READ)
)
UserInfo()
}
}
```


- weight

在RowScope和ColumnScope中,可以使用专属的weight修饰符来设置尺寸。

与size修饰符不同的是,weight修饰符允许组件通过百分比设置尺寸,也就是允许组件可以自适应适配各种屏幕尺寸。








































Loading

0 comments on commit da95ba3

Please sign in to comment.