一.Stack类简介
Stack栈是Vector的一个子类,它实现了一个标准的后进先出的栈。
堆栈只定义了默认构造函数,用来创建一个空栈。 堆栈除了包括由Vector定义的所有方法,也定义了自己的一些方法。
二.Stack常用方法
1.lastElement()方法
<1> 作用
获取栈顶元素。
<2> 代码
Stack<String> stack = new Stack<>();
//add方法 添加元素
stack.add("Activity1");
stack.add("Activity2");
stack.add("Activity3");
//lastElement方法获取栈顶元素
String last = stack.lastElement();
Log.d("TAG", "lastElement方法获取栈顶元素:" + last);
//遍历栈中的元素
for (String value : stack) {
Log.d("TAG", "遍历:" + value);
}
<3> 结果
D/TAG: lastElement方法获取栈顶元素:Activity3
D/TAG: 遍历:Activity1
D/TAG: 遍历:Activity2
D/TAG: 遍历:Activity3
<4> 结论
如图,Activity3是最后添加的元素,其位于栈顶。
2.pop()方法
<1> 作用
移除栈顶部的对象,并作为此函数的值返回该对象。
<2> 代码
Stack<String> stack = new Stack<>();
//add方法 添加元素
stack.add("Activity1");
stack.add("Activity2");
stack.add("Activity3");
//pop方法移除栈顶对象 返回值是栈顶对应的对象
String top = stack.pop();
Log.d("TAG", "pop方法移除栈顶对象:" + top);
//lastElement方法获取栈顶元素
String last = stack.lastElement();
Log.d("TAG", "lastElement方法获取栈顶元素:" + last);
//遍历栈中的元素
for (String value : stack) {
Log.d("TAG", "遍历:" + value);
}
<3> 结果
D/TAG: pop方法移除栈顶对象:Activity3
D/TAG: lastElement方法获取栈顶元素:Activity2
D/TAG: 遍历:Activity1
D/TAG: 遍历:Activity2
<4> 结论
如图,原本栈顶的Activity3被移除。
3.push()方法
<1> 作用
把指定元素压入栈顶部。
<2>代码
Stack<String> stack = new Stack<>();
//add方法 添加元素
stack.add("Activity1");
stack.add("Activity2");
stack.add("Activity3");
//push方法把元素压入栈顶部
String top = stack.push("Activity4");
Log.d("TAG", "push方法把元素压入栈顶部:" + top);
//lastElement方法获取栈顶元素
String last = stack.lastElement();
Log.d("TAG", "lastElement方法获取栈顶元素:" + last);
//遍历栈中的元素
for (String value : stack) {
Log.d("TAG", "遍历:" + value);
}
<3> 结果
D/TAG: push方法把元素压入栈顶部:Activity4
D/TAG: lastElement方法获取栈顶元素:Activity4
D/TAG: 遍历:Activity1
D/TAG: 遍历:Activity2
D/TAG: 遍历:Activity3
D/TAG: 遍历:Activity4
<4> 结论
如图,把Activity4压入栈顶。
4.remove(Object value)方法
<1> 作用
删除栈中指定的元素value。
<2> 代码
Stack<String> stack = new Stack<>();
//add方法 添加元素
stack.add("Activity1");
stack.add("Activity2");
stack.add("Activity3");
//remove方法删除栈指定元素
stack.remove("Activity2");
//lastElement方法获取栈顶元素
String last = stack.lastElement();
Log.d("TAG", "lastElement方法获取栈顶元素:" + last);
//遍历栈中的元素
for (String value : stack) {
Log.d("TAG", "遍历:" + value);
}
<3> 结果
D/TAG: lastElement方法获取栈顶元素:Activity3
D/TAG: 遍历:Activity1
D/TAG: 遍历:Activity3
<4> 结论
如图,原本栈中的Activity2被移除,栈内的其他元素位置不会变化。
5.search(Object value)方法
<1> 作用
找到栈内指定元素value在栈内的位置。
<2> 代码
Stack<String> stack = new Stack<>();
//add方法 添加元素
stack.add("Activity1");
stack.add("Activity2");
stack.add("Activity3");
//search方法返回元素在栈中的位置
int position = stack.search("Activity2");
Log.d("TAG", "search方法返回元素在栈中的位置:" + position);
//lastElement方法获取栈顶元素
String last = stack.lastElement();
Log.d("TAG", "lastElement方法获取栈顶元素:" + last);
//遍历栈中的元素
for (String value : stack) {
Log.d("TAG", "遍历:" + value);
}
<3> 结果
D/TAG: search方法返回元素在栈中的位置:2
D/TAG: lastElement方法获取栈顶元素:Activity3
D/TAG: 遍历:Activity1
D/TAG: 遍历:Activity2
D/TAG: 遍历:Activity3
<4> 结论
如图,Activity2在栈内的位置是2。Activity1在栈内的位置是3。Activity3在栈内的位置是1。
三.Stack应用之管理项目中的Activity
1.描述
因为Activity的栈也是符合先进后出,所以管理Activity可以使用Stack类。
2.代码(工具类)
public class ActivityStackManager {
private static Stack<Activity> activityStack;
private ActivityStackManager() {
activityStack = new Stack<>();
}
private static class ViewHolder {
private static ActivityStackManager MANAGER = new ActivityStackManager();
}
public static ActivityStackManager getInstance() {
return ViewHolder.MANAGER;
}
/**
* 普通Activity入栈 一般Activity的onCreate方法
*/
public void addActivityStack(Activity activity) {
if (null == activity) return;
activityStack.add(activity);
Log.d("TAG", "普通Activity入栈 一般Activity的onCreate方法");
}
/**
* 普通Activity出栈栈 一般Activity的中手动调用finish方法
*/
public void removeActivityStack(Activity activity) {
if (null == activity) return;
activityStack.remove(activity);
}
/**
* 获取项目中当前的Activity 即栈顶位置的Activity
*/
public Activity getCurrentActivityStack() {
return activityStack.lastElement();
}
/**
* 结束指定的Activity
*/
public void finishActivityStack(Activity activity) {
if (null == activity) return;
activityStack.remove(activity);
activity.finish();
}
/**
* 结束指定类名的Activity
*/
public void finishActivityStackByClassName(Class<?> cls) {
if (null == cls) return;
for (Activity activity : activityStack) {
if (cls.equals(activity.getClass())) {
finishActivityStack(activity);
}
}
}
/**
* 结束所有的Activity
*/
public void finishAllActivityStack() {
for (Activity activity : activityStack) {
finishActivityStack(activity);
}
activityStack.clear();
}
}
四.Stack应用之操作二叉树
1.描述
二叉树的前序遍历,中序遍历,后序遍历以及翻转都可以用递归的方式实现。具体详情
https://blog.csdn.net/weixin_37730482/article/details/70677638
那么我们能不能换一种方式实现呢?当然可以。那么我们就使用Stack类完成二叉树的操作吧。
2.代码
public class MainActivity5 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);
//首先定义9个节点
TreeNodeBean treeNodeBean1 = new TreeNodeBean(1);
TreeNodeBean treeNodeBean2 = new TreeNodeBean(2);
TreeNodeBean treeNodeBean3 = new TreeNodeBean(3);
TreeNodeBean treeNodeBean4 = new TreeNodeBean(4);
TreeNodeBean treeNodeBean5 = new TreeNodeBean(5);
TreeNodeBean treeNodeBean6 = new TreeNodeBean(6);
TreeNodeBean treeNodeBean7 = new TreeNodeBean(7);
TreeNodeBean treeNodeBean8 = new TreeNodeBean(8);
TreeNodeBean treeNodeBean9 = new TreeNodeBean(9);
//确定九个节点的位置
treeNodeBean6.left = treeNodeBean3;
treeNodeBean6.right = treeNodeBean9;
treeNodeBean3.left = treeNodeBean1;
treeNodeBean3.right = treeNodeBean5;
treeNodeBean9.left = treeNodeBean7;
treeNodeBean1.right = treeNodeBean2;
treeNodeBean5.left = treeNodeBean4;
treeNodeBean7.right = treeNodeBean8;
//Stack实现前序遍历
preOrderStack(treeNodeBean6);
//Stack实现中序遍历
midOrderStack(treeNodeBean6);
//Stack实现后续遍历
afterOrderStack(treeNodeBean6);
//Stack实现二叉树翻转
TreeNodeBean result = reverseTreeNodeStack(treeNodeBean6);
preOrderStack(result);
}
/**
* Stack实现前序遍历 根 左 右
*/
private void preOrderStack(TreeNodeBean treeNodeBean) {
if (null == treeNodeBean) return;
//1.声明一个Stack
Stack<TreeNodeBean> stack = new Stack<>();
//2.声明一个TreeNodeBean指向传入的节点
TreeNodeBean treeNode = treeNodeBean;
//3.如果treeNode的不为空 或者 Stack栈不为空
while (treeNode != null || !stack.isEmpty()) {
while (treeNode != null) {
//3.1.访问根节点
Log.d("TAG", "Stack类实现前序遍历二叉树:" + treeNode.data);
//3.2.treeNode压入栈顶
stack.push(treeNode);
//3.3.获取treeNode的左子树
treeNode = treeNode.left;
}
if (!stack.isEmpty()) {
//3.4.treeNode移出栈顶
treeNode = stack.pop();
//3.5.获取treeNode的右子树
treeNode = treeNode.right;
}
}
}
/**
* Stack实现中序遍历 左 根 右
*/
private void midOrderStack(TreeNodeBean treeNodeBean) {
if (null == treeNodeBean) return;
//1.声明一个Stack
Stack<TreeNodeBean> stack = new Stack<>();
//2.声明一个TreeNodeBean指向传入的节点
TreeNodeBean treeNode = treeNodeBean;
//3.如果treeNode的不为空 或者 Stack栈不为空
while (treeNode != null || !stack.isEmpty()) {
while (treeNode != null) {
//3.1.treeNode压入栈顶
stack.push(treeNode);
//3.2.获取treeNode的左子树
treeNode = treeNode.left;
}
if (!stack.isEmpty()) {
//3.4.treeNode移出栈顶
treeNode = stack.pop();
//3.5.访问根节点
Log.d("TAG", "Stack类实现中序遍历二叉树:" + treeNode.data);
//3.6.获取treeNode的右子树
treeNode = treeNode.right;
}
}
}
/**
* Stack实现后序遍历 左 右 根
*/
private void afterOrderStack(TreeNodeBean treeNodeBean) {
if (null == treeNodeBean) return;
//1.声明一个Stack
Stack<TreeNodeBean> stack = new Stack<>();
//2.声明一个TreeNodeBean指向传入的节点
TreeNodeBean treeNode = treeNodeBean;
//3.标记每次遍历最后一次访问的节点
TreeNodeBean lastVisit = null;
//4.如果treeNode的不为空 或者 Stack栈不为空
while (treeNode != null || !stack.isEmpty()) {
while (treeNode != null) {
//4.1.treeNode压入栈顶
stack.push(treeNode);
//4.2.获取treeNode的左子树
treeNode = treeNode.left;
}
if (!stack.isEmpty()) {
//4.3.treeNode移出栈顶
treeNode = stack.pop();
//4.4.判断treeNode是否有右子树
if (treeNode.right == null || treeNode.right == lastVisit) {
//4.5.访问根节点
Log.d("TAG", "Stack类实现后序遍历二叉树:" + treeNode.data);
//4.6.treeNode 赋值给 标记每次遍历最后一次访问的节点
lastVisit = treeNode;
//4.7.treeNode置空
treeNode = null;
} else {
//4.8.treeNode压入栈顶
stack.push(treeNode);
//4.9.获取treeNode的右子树
treeNode = treeNode.right;
}
}
}
}
/**
* Stack实现二叉树翻转
*/
private TreeNodeBean reverseTreeNodeStack(TreeNodeBean root) {
if (null == root) return null;
Stack<TreeNodeBean> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
final TreeNodeBean node = stack.pop();
//交换两个节点
final TreeNodeBean temp = node.left;
node.left = node.right;
node.right = temp;
if (node.left != null) {
stack.push(node.left);
}
if (node.right != null) {
stack.push(node.right);
}
}
return root;
}
}
3.结果
D/TAG: Stack类实现前序遍历二叉树:6
D/TAG: Stack类实现前序遍历二叉树:3
D/TAG: Stack类实现前序遍历二叉树:1
D/TAG: Stack类实现前序遍历二叉树:2
D/TAG: Stack类实现前序遍历二叉树:5
D/TAG: Stack类实现前序遍历二叉树:4
D/TAG: Stack类实现前序遍历二叉树:9
D/TAG: Stack类实现前序遍历二叉树:7
D/TAG: Stack类实现前序遍历二叉树:8
**********************************************
D/TAG: Stack类实现中序遍历二叉树:1
D/TAG: Stack类实现中序遍历二叉树:2
D/TAG: Stack类实现中序遍历二叉树:3
D/TAG: Stack类实现中序遍历二叉树:4
D/TAG: Stack类实现中序遍历二叉树:5
D/TAG: Stack类实现中序遍历二叉树:6
D/TAG: Stack类实现中序遍历二叉树:7
D/TAG: Stack类实现中序遍历二叉树:8
D/TAG: Stack类实现中序遍历二叉树:9
**********************************************
D/TAG: Stack类实现后序遍历二叉树:2
D/TAG: Stack类实现后序遍历二叉树:1
D/TAG: Stack类实现后序遍历二叉树:4
D/TAG: Stack类实现后序遍历二叉树:5
D/TAG: Stack类实现后序遍历二叉树:3
D/TAG: Stack类实现后序遍历二叉树:8
D/TAG: Stack类实现后序遍历二叉树:7
D/TAG: Stack类实现后序遍历二叉树:9
D/TAG: Stack类实现后序遍历二叉树:6
***********************************************
Stack类翻转二叉树后采用前序遍历结果
D/TAG: Stack类实现前序遍历二叉树:6
D/TAG: Stack类实现前序遍历二叉树:9
D/TAG: Stack类实现前序遍历二叉树:7
D/TAG: Stack类实现前序遍历二叉树:8
D/TAG: Stack类实现前序遍历二叉树:3
D/TAG: Stack类实现前序遍历二叉树:5
D/TAG: Stack类实现前序遍历二叉树:4
D/TAG: Stack类实现前序遍历二叉树:1
D/TAG: Stack类实现前序遍历二叉树:2
4.算法