总结
-
框架原理真的深入某一部分具体的代码和实现方式时,要多注意到细节,不要只能写出一个框架。
-
算法方面很薄弱的,最好多刷一刷,不然影响你的工资和成功率😯
-
在投递简历之前,最好通过各种渠道找到公司内部的人,先提前了解业务,也可以帮助后期优秀 offer 的决策。
-
要勇于说不,对于某些 offer 待遇不满意、业务不喜欢,应该相信自己,不要因为当下没有更好的 offer 而投降,一份工作短则一年长则 N 年,为了幸福生活要慎重选择!!!
喜欢这篇文章文章的小伙伴们点赞+转发支持,你们的支持是我最大的动力!
private Object[] objs = new Object[16];
// 栈的大小
private int size = 0;
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void clear() {
// 将数组中的数据置为null, 方便GC进行回收
for (int i = 0; i < size; i++) {
objs[size] = null;
}
size = 0;
}
@Override
public int length() {
return size;
}
@Override
public boolean push(T data) {
// 判断是否需要进行数组扩容
if (size >= objs.length) {
resize();
}
objs[size++] = data;
return true;
}
/**
* 数组扩容
*/
private void resize() {
Object[] temp = new Object[objs.length * 3 / 2 + 1];
// 复制
for (int i = 0; i < size; i++) {
temp[i] = objs[i];
objs[i] = null;
}
// 将objs重新设置为栈空间
objs = temp;
}
@SuppressWarnings("unchecked")
@Override
public T pop() {
if (size == 0) {
return null;
}
return (T) objs[--size];
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("MyArrayStack: [");
for (int i = 0; i < size; i++) {
sb.append(objs[i].toString());
if (i != size - 1) {
sb.append(", ");
}
}
sb.append("]");
return sb.toString();
}
}
然后定义了栈的链表实现:
package cn.edu.ujn.stack;
/**
-
栈的链表实现, 底层使用链表
-
@author SHQ
-
@param
/
public class MyLinkedStack implements MyStack {
/*- 栈顶指针
/
private Node top;
/* - 栈的长度
*/
private int size;
public MyLinkedStack() {
top = null;
size = 0;
}@Override
public boolean isEmpty() {
return size == 0;
}@Override
public void clear() {
top = null;
size = 0;
}@Override
public int length() {
return size;
}@Override
public boolean push(T data) {
Node node = new Node();
node.data = data;
node.pre = top;
// 改变栈顶指针
top = node;
size++;
return true;
}@Override
public T pop() {
if (top != null) {
Node node = top;
// 改变栈顶指针
top = top.pre;
size–;
return node.data;
}
return null;
}/**
- 将数据封装成结点
*/
private final class Node {
private Node pre;
private T data;
}
}
- 栈顶指针
两种实现的比较, 主要比较数据入栈和出栈的速度:
package cn.edu.ujn.stack;
public class Test {
public static void main(String[] args) {
testSpeed();
}
private static void testSpeed() {
// 测试数组实现
//MyStack stack = new MyArrayStack();
// 测试链表实现
MyStack stack = new MyLinkedStack();
int num = 1000000;
long start = System.currentTimeMillis();
for (int i = 0; i < num; i++) {
stack.push(new Person(“xing”, 25));
}
long temp = System.currentTimeMillis();
System.out.println("push time: " + (temp - start));
while (stack.pop() != null)
;
System.out.println("pop time: " + (System.currentTimeMillis() - temp));
}
}
运行结果如下:
![](https://img-blog.csdn.net/20160807161051310?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) ![](https://img-blog.csdn.net/20160807161103685?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
可见入栈、出栈速度MyArrayStack则有明显的优势.
为什么测试结果是这样的? 可能有些朋友的想法是:数组实现的栈应该具有更快的遍历速度, 但增删速度应该比不上链表实现的栈才对。但是栈中数据的增删具有特殊性: 只在栈顶入栈和出栈。也就是说数组实现的栈在增加和删除元素时并不需要移动大量的元素, 只是在数组扩容时需要进行复制。而链表实现的栈入栈和出栈时都需要将数据包装成Node或者从Node中取出数据, 还需要维护栈顶指针和前驱指针。
### **栈的应用举例**
#### 1.将10进制正整数num转换为n进制
package cn.edu.ujn.stack;
public class StackApp {
/**
- @param args
/
public static void main(String[] args) {
//System.out.println(conversion4D2X(22, 2));
//System.out.println(isMatch(“[()]”));
System.out.println(lineEdit(“Hello #world”));
}
/*
*栈的应用举例-将10进制正整数num转换为n进制 - @param num 待转化十进制数
- @param n 转化进制
- @return
*/
private static String conversion4D2X(int num, int n) {
MyStack myStack = new MyArrayStack();
Integer result = num;
while (true) {
// 将余数入栈
myStack.push(result % n);
总结
-
框架原理真的深入某一部分具体的代码和实现方式时,要多注意到细节,不要只能写出一个框架。
-
算法方面很薄弱的,最好多刷一刷,不然影响你的工资和成功率😯
-
在投递简历之前,最好通过各种渠道找到公司内部的人,先提前了解业务,也可以帮助后期优秀 offer 的决策。
-
要勇于说不,对于某些 offer 待遇不满意、业务不喜欢,应该相信自己,不要因为当下没有更好的 offer 而投降,一份工作短则一年长则 N 年,为了幸福生活要慎重选择!!!
喜欢这篇文章文章的小伙伴们点赞+转发支持,你们的支持是我最大的动力!