提示:以下是本篇文章正文内容,下面案例可供参考
一、栈的简介
1)栈的英文为(stack)
2)栈是一个先入后出(FILO-First In Last Out)的有序列表。
3)栈(stack)是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。允许插入和删除的
一端,为变化的一端,称为栈顶(Top),另一端为固定的一端,称为栈底(Bottom)。
4)根据栈的定义可知,最先放入栈中元素在栈底,最后放入的元素在栈顶,而删除元素刚好相反,最后放入的元
素最先删除,最先放入的元素最后删除
5)图解方式说明出栈(pop)和入栈(push)的概念
Stack继承了Vector,而Vector类底层使用数组存储数据,那么Stack对象中存储的数据也是存储在数组中的。
Strack用数组实现了栈的先进后出功能。
栈也可以用Vector里的方法例如add()、size()
Stack的继承体系
Stack的兄弟arrayList的继承体系
自己的构造方法跟普通方法
二、代码演示
import java.util.Stack;
public class StackDemo {
public static void main(String[] args) {
Stack <String> stack2 = new Stack<>();
stack2.push("aaa");
stack2.push("bbb");
stack2.push("ccc");
System.out.println("当前栈中的元素为:"+stack2);
System.out.println("栈结构中的个数:"+stack2.size());
System.out.println("此时栈顶的元素是:"+stack2.peek());
System.out.println(stack2.pop()+"已出栈");
System.out.println("此时栈顶的元素是:"+stack2.peek());
System.out.println("此时栈中的个数为:"+stack2.size());
System.out.println("此时栈中的元素为:"+stack2);
System.out.println("----------------------------------------------------");
Stack <String> stack = new Stack<>();
stack.add("aaa");
stack.add("bbb");
stack.add("ccc");
System.out.println("当前栈中的元素为:"+stack);
while (stack.size()>0){
System.out.println(stack.pop()+"已出栈");
}
System.out.println("此时栈中的元素为:"+stack2);
}
}
三、用栈将单项链表进行逆序输出
import java.util.Stack;
/**
* 单向链表(带头结点)
* 第一种方法在添加英雄时,直接添加到链表的尾部、按顺序编号(没有考虑编号)
* 第二种方式在添加英雄时,根据排名将英雄插入到指定位置 (如果有这个排名,则添加失败,并给出提示)
*
* @author 罗汉 QQ;1072344372
* @date 2022/11/16
*/
public class SingLinkListDemo {
public static void main(String[] args) {
// 先创建节点
HeroNode hero1 = new HeroNode(1, "宋江", "及时雨");
HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟");
HeroNode hero3 = new HeroNode(3, "吴用", "智多星");
HeroNode hero4 = new HeroNode(4, "林冲", "豹子头");
// 创建单向链表
SingLinkList singLinkList = new SingLinkList();
// 测试第一种添加
// singLinkList.add1(hero1);
// singLinkList.add1(hero2);
// singLinkList.add1(hero3);
// singLinkList.add1(hero4);
// singLinkList.getSLList();
// 测试第二种添加
singLinkList.addByOrder(hero1);
singLinkList.addByOrder(hero3);
singLinkList.addByOrder(hero2);
singLinkList.addByOrder(hero4);
// singLinkList.addByOrder(hero3);
// 测试修改节点的代码
HeroNode heroN = new HeroNode(2, "张三", "路人甲");
singLinkList.getSLList();
System.out.println("----------------------");
System.out.println("测试修改节点的代码");
singLinkList.update(heroN);
singLinkList.getSLList();
System.out.println("----------------");
// 测试删除节点
System.out.println("测试删除节点");
singLinkList.deleteByNo(4);
// 显示
System.out.println("删除后的链表情况为:-----------------------------");
singLinkList.getSLList();
// 1)求单链表中有效节点的个数
System.out.println("链表的有效长度为:" + singLinkList.getLength(singLinkList.getHead()));
// 2)查找单链表中的倒数第k个节点
// 3)单链表的反转
// 4)从头到尾打印单链表【百度要求方式1:反向遍历。方式2:Stack栈】
//测试逆序打印
System.out.println("测试逆序打印单链表");
SingLinkList.reverePrint(singLinkList.getHead());
// 5)合并2个有序的单链表,合并之后的链表依然有序
}
}
/**
* 单向链表
* 定义SingLinkList 管理我们的英雄
*
* @author 罗汉 QQ;1072344372
* @date 2022/11/16
*/
class SingLinkList {
// 先初始化一个头结点,头结点不要动
private HeroNode head = new HeroNode(0, "", "");
public HeroNode getHead() {
return head;
}
/**
* 添加节点到单向链表
* 思路,当不考虑编号顺序时
* 1.找到当前链表的最后节点
* 2.将最后这个节点的next 指向 新的节点
*
* @param heroNode 英雄节点
*/
public void add1(HeroNode heroNode) {
// 因为head节点不能动,因此我们需要一个辅助变量temp
HeroNode temp = head;
/**
*遍历链表,找到最后。
* 如果没有找到就将temp后移
*/
while (temp.next != null) {
temp = temp.next;
}
// 当退出while循环时,temp就指向了链表的最后
// 将最后这个节点的next指向新的节点
temp.next = heroNode;
}
/**
* 第二种添加英雄的方法
* 第二种方式在添加英雄时,根据排名将英雄插入到指定位置 (如果有这个排名,则添加失败,并给出提示)
*
* @param heroNode 英雄节点
*/
public void addByOrder(HeroNode heroNode) {
// 因为头结点不能动,因此我们任然通过一个辅助指针(变量)来帮助找到添加的位置
// 因为单链表,因为我们找的temp是位于添加位置的前一个节点,否则插入不了
HeroNode temp = head;
// flag表示添加的编号是否存在,默认不存在
boolean flag = false;
while (true) {
if (temp.next == null) {
break;
}
if (temp.next.no > heroNode.no) {// 位置找到,就在temp的后面插入
break;
} else if (temp.next.no == heroNode.no) {
// 说明希望添加的heroNode已经存在
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
// 说明编号存在,不能添加
System.out.println("编号已经存在");
} else {
heroNode.next = temp.next;
temp.next = heroNode;
}
}
/**
* 更新链表集合
* 根据heroNode的no来修改
*
* @param heroNode 英雄节点
*/
public void update(HeroNode heroNode) {
if (head.next == null) {
System.out.println("链表为空,不能更新");
return;
}
// 找到需要修改的这个节点
// 定义一个辅助变量
HeroNode temp = head.next;
// flag表示是否找到该节点
boolean flag = false;
while (true) {
if (temp == null) {
break;
}
if (temp.no == heroNode.no) {
// 说明找到了这个节点
flag = true;
break;
}
temp = temp.next;
}
if (flag) {
temp.name = heroNode.name;
temp.nickname = heroNode.nickname;
} else {
System.out.println("没有找到编号为" + heroNode.no + "的节点,不能修改");
}
}
/**
* 根据no删除节点
* 1.head不能动,因此我们需要个temp辅助节点找到待删除节点的前一个节点
* 2.说明我们在比较时,是temp.next.no和需要删除节点的no做比较
*
* @param no 需要删除的英雄编号
*/
public void deleteByNo(int no) {
HeroNode temp = head;
// flag表示是否找到待删除节点
boolean flag = false;
while (true) {
if (temp.next == null) {// 已经到链表的最后
break;
}
if (temp.next.no == no) {// 找到了要删除节点的前一个节点temp
flag = true;
break;
}
// temp后移,遍历
temp = temp.next;
}
if (flag) {
// 找到
temp.next = temp.next.next;
} else {
System.out.println("要删除的英雄的" + no + "不存在");
}
}
/**
* 得到链表集合内容
*/
public void getSLList() {
// 判断链表是否为空
if (head.next == null) {
System.out.println("链表为空");
return;
}
HeroNode temp = head.next;
while (temp != null) {
// 输出节点
System.out.println(temp);
// 将temp后移
temp = temp.next;
}
}
public HeroNode getKHeroNode(int k){
//判断链表是否为空
return null;
}
/**
* 获取单链表的节点的个数,(如果是带头节点,需求是不统计头节点)
*
* @param head 链表的头节点
* @return int
*/
public int getLength(HeroNode head) {
// 判断链表是否为空
if (head.next == null) {
System.out.println("链表为空");
return 0;
}
// 定义一个辅助的变量,(没有统计头结点)
HeroNode temp = head.next;
int length = 0;
while (temp != null) {
length++;
temp = temp.next;
}
return length;
}
/**
* 逆序打印(栈的方法)
*
* @param head 头
*/
public static void reverePrint(HeroNode head){
if (head.next==null){
return;
}
//创建一个栈,将各个节点压入栈
Stack<HeroNode> stack = new Stack<>();
HeroNode cur = head.next;
//将链表的所有节点压入栈
while (cur!=null){
stack.push(cur);
cur=cur.next;
}
//将栈中的节点进行打印,pop 出栈
while (stack.size()>0){
System.out.println(stack.pop());
}
}
}
/**
* 英雄节点
* 定义HeroNode ,每个HeroNode 对象就是一个节点
*
* @author 罗汉 QQ;1072344372
* @date 2022/11/16
*/
class HeroNode {
public int no;
public String name;
public String nickname;
// 指向下一个节点
public HeroNode next;
public HeroNode(int no, String name, String nickname) {
this.no = no;
this.name = name;
this.nickname = nickname;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
", nickname='" + nickname + '\'' +
// ", next=" + next +
'}';
}
}
总结
栈先进后出