Skip to content

Commit fe44b79

Browse files
committed
2021-07-26
1 parent c0c3b99 commit fe44b79

2 files changed

Lines changed: 175 additions & 5 deletions

File tree

docs/MySQL/《MySQL必知必会》.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,6 @@ id 字段的数据类型为INT(11),注意后面的数字11,它表示的是
293293
| DOUBLE | 8 bytes | (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) | 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) |
294294
| DECIMAL | 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 | 依赖于M和D的值 | 依赖于M和D的值 |
295295

296-
297-
298296
### 3.3 日期与时间类型
299297

300298
MySQL中有多种表示日期的数据类型,主要有DATETIME、DATE、TIMESTAMP、TIME和YEAR。
@@ -355,9 +353,11 @@ MySQL中有不同种类的日期和时间的数据类型,比如`YEAR`和`TIME`
355353

356354
`BLOB`是二进制字符串,`TEXT`是非二进制字符串,两者均可存放大容量的信息。`BLOB`主要存储图片、音频信息等,而`TEXT`只能存储纯文本文件。
357355

358-
## 4. MySQL函数
356+
## 4. 查询数据
357+
358+
### 4.1 单表查询
359359

360-
MySQL提供了众多功能强大、方便易用的函数。使用这些函数,可以极大地提高用户对数据库的管理效率。MySQL中的函数包括数学函数、字符串函数、日期和时间函数、条件判断函数、系统信息函数和加密函数等其他函数。
360+
#### 4.1.1 查询所有字段
361361

362362

363363

docs/算法与数据结构/栈.md

Lines changed: 171 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,171 @@
1-
~ todo
1+
# 栈:一吃多就会吐的家伙~
2+
3+
## 前言
4+
5+
前两篇文章中我们学习了线性表中的数组和链表,数组和链表是最基础的数据结构,很多数据结构的实现都是基于数据或链表的。那么今天我们一起学习一个非常简单的数据结构—****。栈使用是非常广泛的,比如我们Java中函数的调用、浏览器中的前进与后退功能等都会用到栈。
6+
7+
## 什么是栈
8+
9+
先画张图,看看栈长什么样。如下图所示:
10+
11+
![// 配图](https://cdn.jsdelivr.net/gh/msJavaCoder/msJava@master/image/顺序栈与链式栈.png)
12+
13+
从图中看到栈是有些特殊,对于栈的操作被限制只能在栈的一端(栈顶)进行,也就是不允许在栈的中间进行数据操作,只能在栈顶进行数据操作(也就是插入和删除数据)。
14+
15+
> 思考:“受限制”的栈有什么用呢?
16+
17+
特定的数据结构肯定有其特定的使用场景,相比于数组或者链表而言,栈虽然没有怎么灵活(只能在栈的一端进行数据操作),但是对于新增或者删除数据的时候,因为栈只涉及到一端,效率肯定不低。
18+
19+
如何去理解栈呢?其实也非常简单,一句话可以概况栈的特性:**先进后出**,俗称“**吃多了吐**”。哈哈~
20+
21+
## 栈的基本操作
22+
23+
栈有不同的实现方式,基于数组实现的栈,被叫做**顺序栈**。基于链表实现的栈,被叫做**链式栈**。不管用什么方式实现的栈,其原理都是一样的,不用担心!
24+
25+
栈的操作主要就两个:入栈(push)和出栈(pop)。
26+
27+
- 顺序栈
28+
29+
下面我们先基于数组来实现一个顺序栈,代码如下:
30+
31+
```java
32+
public class MyStack<E> {
33+
private Object[] data = null; // 数组
34+
private int maxSize = 0; //栈容量
35+
private int top = -1; //栈顶指针
36+
37+
// 初始化构造方法
38+
MyStack(int initialSize) {
39+
if (initialSize >= 0) {
40+
this.maxSize = initialSize;
41+
data = new Object[initialSize];
42+
top = -1;
43+
} else {
44+
throw new RuntimeException("初始化大小不能小于0: " + initialSize);
45+
}
46+
}
47+
48+
// 初始化构造方法 默认栈容量为10
49+
public MyStack() {
50+
this(10);
51+
}
52+
53+
//入栈操作
54+
public boolean push(E e) {
55+
//首先判断一下栈是否已经满了
56+
if (top == maxSize - 1) {
57+
// 扩容
58+
resize();
59+
}
60+
data[top] = e;
61+
top++;
62+
return true;
63+
}
64+
65+
//出栈操作
66+
public E pop() {
67+
//首先查看一下栈是否为空
68+
if (top == -1) {
69+
throw new RuntimeException("栈为空");
70+
} else {
71+
//将栈顶元素返回后维护一下栈顶指针
72+
return (E) data[top--];
73+
}
74+
}
75+
76+
//查看栈顶元素
77+
public E peek() {
78+
if (top == -1) {
79+
throw new RuntimeException("栈为空");
80+
} else {
81+
// 查看栈顶元素并不移除所以说不需要维护栈顶指针
82+
return (E) data[top];
83+
}
84+
}
85+
86+
// 查看栈是否为空
87+
public boolean isEmpty() {
88+
return maxSize == 0;
89+
}
90+
91+
// 扩容操作
92+
public void resize() {
93+
// 创建一个新数组
94+
Object[] newArray = new Object[data.length * 2];
95+
System.arraycopy(data, 0, newArray, 0, data.length);
96+
data = newArray;
97+
}
98+
99+
100+
}
101+
102+
```
103+
104+
在顺序栈中,数组的第一个元素最为栈底,最后一个元素最为栈顶。当top=-1的时候,此时栈为空。
105+
106+
每当新增数据入栈push的时候,maxSize加一,同理删除元素出栈pop的时候,maxSize减一。因为是基础数组的实现,所以顺序栈会涉及一个扩容的情况。
107+
108+
- 链式栈
109+
110+
我们再来看看基于链表来实现一个链式栈,代码如下:
111+
112+
```java
113+
public class MyStack<E> {
114+
StackNode<E> top = null; //栈顶
115+
116+
private class StackNode<E>{
117+
E data;
118+
StackNode next;
119+
StackNode(E data) {
120+
this.data=data;
121+
}
122+
}
123+
124+
/**
125+
* 入栈
126+
* 首先将要push的数据的next赋值为栈顶top
127+
* 然后将栈顶指针指向新push进来的节点
128+
* @param data
129+
*/
130+
public void push(E data) {
131+
StackNode<E> newNode = new StackNode<E>(data);
132+
newNode.next = top;
133+
top = newNode;
134+
}
135+
136+
/**
137+
* 出栈
138+
* @return
139+
*/
140+
public E pop() {
141+
if(this.isEmpty()) {
142+
throw new RuntimeException("栈为空");
143+
}
144+
E data = top.data;
145+
top = top.next;
146+
return data;
147+
}
148+
149+
/**
150+
* 查看栈顶元素
151+
* @return
152+
*/
153+
public E peek() {
154+
if(isEmpty()) {
155+
throw new RuntimeException("栈为空");
156+
}
157+
return top.data;
158+
}
159+
160+
// 判断栈是否为空
161+
public boolean isEmpty() {
162+
return top == null;
163+
}
164+
}
165+
```
166+
167+
在链式栈中,单链表的头部最为栈顶,因为栈的特性是先进后出,所以不需要头节点的。每当新增数据入栈push的时候,需要让新的结点指向原栈顶,然后再让top指向新增的这个结点。同理删除元素出栈pop的时候,只需要栈顶的 top 指向栈顶元素的 next 指针即可完成删除。
168+
169+
## 总结
170+
171+
栈作为一个受限制的线性表,只允许对栈顶的数据进行操作,也就是所谓的:先进后出,后进先出。不管是顺序栈还是链式栈,新增或者删除数据时都只能在栈顶进行,故时间复杂度都是O(1),查找数据的时候都需要进行全局遍历,故时间复杂度都是O(n)。顺序栈基于数组实现,初始化时大小便已经固定,后续需要考虑扩容的情况,而链式栈基于链表实现,不需要考虑扩容。

0 commit comments

Comments
 (0)