B为A的后继元素)
头结点
尾节点
可以是顺序存储,也可以是链式存储,按照存储方式不同,可以将线性表分为线性表和链表通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系代表有数组形式。
package linear;
/**
* @ClassName SequenceListTest
* @Authoc 孙少聪
* @Date 2022/7/28 10:04:58
*/
public class SequenceList<T> {
// 存储元素的数据
private T[] eles;
// 记录当前顺序表中的元素个数
private int N;
// 构造方法
public SequenceList(int capacity){
// 初始化数据 Object也可以存储任意类型的数据
this.eles = (T[]) new Object[capacity];
// 初始化长度
this.N = 0;
}
// 清空线性表置为空
public void clear(){
this.N = 0;
}
// 线性表是否为空
public boolean isEmpty(){
return N==0;
}
// 获取线性表的长度
public int length(){
return N;
}
public T get(int i){
return eles[i];
}
// 在线性表最后加一个元素
public void insert(T t){
eles[N++] = t;
}
// 在线性表任意位置加一个元素
public void insert(int i,T t){
for (int j = N-1; j > i; j--) {
eles[j] = eles[j-1];
}
eles[i] = t;
}
// 删除指定索引位置,并返回该位置元素
public T remove(int i){
T current = eles[i];
for (int j = i; j < N-1; j++) {
eles[j] = eles[j+1];
}
// 元素个数减一
N--;
return current;
}
// 第一次出现元素的索引
public int indexOf(T t){
for (int i = 0; i < N; i++) {
if(eles[i].equals(t)){
return i;
}
}
// 未出现返回-1
return -1;
}
}
public class SequenceList<T> implements Iterable<T>{
@Override
public Iterator<T> iterator() {
SIterator sIterator = new SIterator();
return sIterator;
}
private class SIterator implements Iterator{
private int cusor;
public SIterator(){
this.cusor = 0;
}
@Override
public boolean hasNext() {
return cusor < N;
}
// 获取当前元素下一位元素
@Override
public Object next() {
return eles[cusor++];
}
}
}
public static void main(String[] args) {
SequenceList<String> sl = new SequenceList<>(3);
sl.insert("张三");
sl.insert("李四");
sl.insert("王五");
sl.insert("赵六");
}
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
-解决
// 根据参数newSize,重置eles的大小
public void resize(int newSize){
// 定义一个临时数组,指向原数组
T[] temp = eles;
// 创建新数组
eles =(T[]) new Object[newSize];
// 把原数组的数组拷贝到新数组
for (int i = 0; i < N; i++) {
eles[i] = temp[i];
}
}
// 在线性表最后加一个元素
public void insert(T t){
if(N == eles.length){
resize(2*eles.length);
}
eles[N++] = t;
}
// 在线性表任意位置加一个元素
public void insert(int i,T t){
if(N == eles.length){
resize(2*eles.length);
}
for (int j = N; j > i; j--) {
eles[j] = eles[j-1];
}
eles[i] = t;
// 元素个数加1
N++;
}
public static void main(String[] args) {
SequenceList<String> sl = new SequenceList<>(3);
sl.insert("张三");
sl.insert("李四");
sl.insert("王五");
sl.insert("赵六");
for (String s:sl
) {
System.out.println(s);
}
System.out.println(sl.length());
}
get(i),不论数据元素量N有多大,只需要一次eles[i]就可以获取到对应的元素,所以时间复杂度为O(1);insert(int i,T t):每一次插入,都需要把i位置后面的元素移动一次,随着元素数量N的增大,移动的元素也越多,时间复杂为O(n);remove(int i):每一次删除,都需要把i位置后面的元素移动一次,随着数据量N的增大,移动的元素也越多,时间复杂度为O(n);容器扩容操作。这样会导致顺序表在使用过程中的时间复杂度不是线性的,在某些需要扩容的结点处,耗时会突增,尤其是元素越多,这个问题越明显
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return true (as specified by {@link Collection#add})
*/
public boolean add(E e) {
// 扩容
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
顺序表查询比较快,增删效率比较低,每次增删操作伴随着大量的数据元素移动



package linear;
import java.util.Iterator;
/**
* @ClassName LinkList
* @Authoc 孙少聪
* @Date 2022/7/30 15:18:21
*/
public class LinkList<T> implements Iterable<T> {
// 记录头结点
private Node head;
// 记录链表的长度
private int N;
public class Node {
// 存储元素
public T item;
// 指向下一个元素
public Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
public LinkList(){
// 初始化头结点
this.head = new Node(null,null);
// 初始化元素个数
this.N = 0;
}
// 清空链表
public void clear(){
// 断开头节点
head.next = null;
this.N = 0;
}
// 清空链表
public int length(){
return N;
}
// 判断链表是否为空
public boolean isEmpty(){
return N==0;
}
// 获取指定位置i处的元素
public T get(int i){
// 从头结点开始循环i次
Node n = head.next;
for (int j = 0; j < i; j++) {
n = n.next;
}
return n.item;
}
// 像链表中添加元素t
public void insert(T t){
// 找到当前最后一个节点
Node n = head;
while(n.next != null){
n = n.next;
}
// 创建新节点,保存元素t
Node newNode = new Node(t, null);
// 让当前最后一个节点指向新节点
n.next = newNode;
// 元素个数+1
N++;
}
// 向链表指定位置中添加元素t
public void insert(int i,T t){
// 找到i位置前一个节点
Node pre = head;
for (int j = 0; j <= i-1; j++) {
pre = pre.next;
}
// 找到i位置的节点
Node curr = pre.next;
// 创建新节点,并且新节点需要指向原来的i位置的结点
Node newNode = new Node(t, curr);
pre.next = newNode;
// 元素的个数+1
N++;
}
// 删除指定位置i处的元素,并返回被删除的元素
public T remove(int i){
// 找到i位置前一个节点
Node pre = head;
for (int index = 0; index <= i-1; index++) {
pre = pre.next;
}
// 找到i位置的节点
Node curr = pre.next;
// 找打i位置的下一个节点
Node after = curr.next;
// 前一个节点指向下一个节点
pre.next = after;
// 元素个数-1
N--;
return curr.item;
}
// 查找元素t在链表中第一次出现的位置
public int indexOf(T t){
Node pre = head;
int i = 0;
for (int j = 0; pre.next != null; j++) {
pre = pre.next;
if(pre.item.equals(t)){
return i;
}
}
return -1;
}
@Override
public Iterator<T> iterator() {
return new LIterator();
}
private class LIterator implements Iterator{
private Node n;
public LIterator(){
this.n = head;
}
@Override
public boolean hasNext() {
return n.next != null;
}
@Override
public Object next() {
n = n.next;
return n.item;
}
}
}
package linear.test;
import linear.LinkList;
import linear.SequenceList;
/**
* @ClassName SequenceListTest
* @Authoc 孙少聪
* @Date 2022/7/28 10:19:59
*/
public class LinkListTest1 {
public static void main(String[] args) {
// 创建顺序表对象
LinkList<String> sl = new LinkList<>();
// 测试插入
sl.insert("姚明");
sl.insert("科比");
sl.insert("麦迪");
sl.insert(1,"詹姆斯");
for (String s : sl) {
System.out.println(s);
}
// 测试获取
String s = sl.get(1);
System.out.println("索引1的元素"+s);
// 测试删除
String remove = sl.remove(0);
System.out.println("删除索引0的元素"+remove);
// 测试清空
sl.clear();
System.out.println("线性表的长度"+sl.length());
}
}



package linear;
import java.util.Iterator;
/**
* @ClassName TwoWayLinkList
* @Authoc 孙少聪
* @Date 2022/7/30 15:18:21
*/
public class TwoWayLinkList<T> implements Iterable<T> {
// 记录头结点
private Node head;
// 记录尾结点
private Node last;
// 记录链表的长度
private int N;
public class Node {
// 存储元素
public T item;
// 指向下一个元素
public Node pre;
// 指向下一个元素
public Node next;
public Node(T item, Node pre, Node next) {
this.item = item;
this.next = next;
this.pre = pre;
}
}
public TwoWayLinkList(){
this.head = new Node(null,null,null);
this.last = null;
this.N = 0;
}
// 清空链表
public void clear(){
this.head.next = null;
this.head.pre = null;
this.head.item = null;
this.last = null;
this.N = 0;
}
// 清空链表
public int length(){
return N;
}
// 判断链表是否为空
public boolean isEmpty(){
return N==0;
}
// 获取第一个元素
public T getFirst(int i){
if(isEmpty()){
return null;
}
// 扎到头结点下一个,因为头节点不存储数据
return head.next.item;
}
// 获取最后一个元素
public T getLast(int i){
if(isEmpty()){
return null;
}
// 最后一个节点的item返回
return last.item;
}
// 获取指定位置i处的元素
public T get(int i){
Node n = head.next;
for (int index = 0; index < i; index++) {
n = n.next;
}
return n.item;
}
// 像链表中添加元素t
public void insert(T t){
// 链表为空
if(isEmpty()){
Node newNode = new Node(t, head, null);
last = newNode;
head.next = last;
}else { // 链表不为空
// 记录尾节点
Node oldLast = last;
// 创建新节点
Node newNode = new Node(t, oldLast, null);
// 将老的尾节点下一位指向新节点
oldLast.next = newNode;
// 更新尾节点数据
last = newNode;
}
// 链表长度+1
N++;
}
// 向链表指定位置中添加元素t
public void insert(int i,T t){
// 找到i位置的前一个节点
Node pre = head;
for (int index = 0; index < i; index++) {
pre = pre.next;
}
// 找到i位置的节点
Node curr = pre.next;
// 创建新节点
Node newNode = new Node(t,pre,curr);
// 更新一下数据
// 让i位置的前一个节点的下一个节点变为新节点
pre.next = newNode;
// 让i位置的前一个节点变为新节点
curr.pre = newNode;
// 元素个数+1
N++;
}
// 删除指定位置i处的元素,并返回被删除的元素
public T remove(int i){
// 找到前一个节点
Node pre = head;
for (int j = 0; j < i; j++) {
pre = pre.next;
}
Node curr = pre.next;
Node after = curr.next;
pre.next = after;
after.pre = pre;
return curr.item;
}
// 查找元素t在链表中第一次出现的位置
public int indexOf(T t){
Node n = head;
for (int i = 0; n.next != null; i++) {
n = n.next;
if(n.item.equals(t)){
return i;
}
}
return -1;
}
@Override
public Iterator<T> iterator() {
return new LIterator();
}
private class LIterator implements Iterator{
private Node n;
public LIterator(){
this.n = head;
}
@Override
public boolean hasNext() {
return n.next != null;
}
@Override
public Object next() {
n = n.next;
return n.item;
}
}
}
/**
* Links e as last element.
*/
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
get(int i):每一次查询,都需要从链表的头部开始,依次向后查找,随着数据元素N的增多,比较的元素越多,时间复杂度为O(n)insert(int i,T t):每一次插入,需要先找到i位置的前一个元素,然后完成插入操作,随着数据元素N的增多,查找的元素越多,时间复杂度为O(n);remove(int i):每一次移除,需要先找到i位置的前一个元素,然后完成插入操作,随着数据元素N的增多,查找的元素越多,时间复杂度为O(n)不需要预先指定存储空间大小,或者在存储过程中涉及到扩容等操作,同时它并没有涉及的元素的交换。链表的查询操作性能会比较低。因此,如果我们的程序中查询操作比较多,建议使用顺序表,增删操作比较多,建议使用链表。
public void reverse(){
// 空链表结束运行,如果是空链表结束运行,如果不是则递归调用reverse方法进行反转
if(isEmpty()){
return;
}
reverse(head.next);
}
// 反转指定的结点curr,并把反转后的节点返回
public Node reverse(Node curr){
if(curr.next == null){
head.next = curr;
return curr;
}
// 递归的反转当前节点curr的下一个结点,返回值就是链表反转后当前结点的上一个结点
Node pre = reverse(curr.next);
// 返回的结点的下一个结点变为当前节点curr
pre.next = curr;
// 当前结点下一个节点变为null
curr.next = null;
return curr;
}
一般情况下,快指针的移动步长为慢指针的两倍public static void main(String[] args) {
// 创建结点
Node<String> first = new Node<String>("aa",null);
Node<String> second = new Node<String>("bb",null);
Node<String> third = new Node<String>("cc",null);
Node<String> fourth = new Node<String>("dd",null);
Node<String> fifth = new Node<String>("ee",null);
Node<String> six = new Node<String>("ff",null);
Node<String> seven = new Node<String>("gg",null);
// 形成链表
first.next =second;
second.next = third;
third.next = fourth;
fourth.next = fifth;
fifth.next = six;
six.next = seven;
String mid = getMid(first);
System.out.println(mid);
}
// 快慢指针获取中间值
public static String getMid(Node<String> first){
// 定义两个指针
Node<String>fast = first;
Node<String> slow = first;
// 使用两个指针遍历列表,当快指针指向的结点没有下一个结点就结素,返回慢指针的结点就是中间值
while(fast.next != null && fast != null){
// 变化fast的值和slow的值
fast = fast.next.next;
slow = slow.next;
}
return slow.item;
}
// 内部类
private static class Node<T> {
T item;
Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
public static void main(String[] args) {
// 创建结点
Node<String> first = new Node<String>("aa",null);
Node<String> second = new Node<String>("bb",null);
Node<String> third = new Node<String>("cc",null);
Node<String> fourth = new Node<String>("dd",null);
Node<String> fifth = new Node<String>("ee",null);
Node<String> six = new Node<String>("ff",null);
Node<String> seven = new Node<String>("gg",null);
// 形成链表
first.next =second;
second.next = third;
third.next = fourth;
fourth.next = fifth;
fifth.next = six;
six.next = seven;
// 产生环
seven.next = third;
Boolean circle = isCircle(first);
System.out.println(circle);
}
public static Boolean isCircle(Node<String> first){
// 定义两个指针
Node<String>fast = first;
Node<String> slow = first;
// 如果快慢指针指向同一个节点,证明有欢
while(fast.next != null && fast != null){
// 变化fast的值和slow的值
fast = fast.next.next;
slow = slow.next;
// 如果快指针遇到慢指针
if(fast.equals(slow)){
return true;
}
}
return false;
}
// 内部类
private static class Node<T> {
T item;
Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
package linear.test;
/**
* @ClassName FastSlowTest
* @Authoc 孙少聪
* @Date 2022/8/1 15:56:09
*/
public class FastSlowTest {
public static void main(String[] args) {
// 创建结点
Node<String> first = new Node<String>("aa",null);
Node<String> second = new Node<String>("bb",null);
Node<String> third = new Node<String>("cc",null);
Node<String> fourth = new Node<String>("dd",null);
Node<String> fifth = new Node<String>("ee",null);
Node<String> six = new Node<String>("ff",null);
Node<String> seven = new Node<String>("gg",null);
// 形成链表
first.next =second;
second.next = third;
third.next = fourth;
fourth.next = fifth;
fifth.next = six;
six.next = seven;
// 产生环
seven.next = fifth;
String entrance = getEntrance(first);
System.out.println(entrance);
}
public static String getEntrance(Node<String> first){
if (!isCircle(first)){
return "无环";
}
// 定义两个指针
Node<String> fast = first;
Node<String> slow = first;
Node<String> temp = null;
// 如果快慢指针指向同一个节点,证明有欢
while(fast.next != null && fast != null){
// 变化fast的值和slow的值
fast = fast.next.next;
slow = slow.next;
if(fast.equals(slow)){
temp = first;
break;
}
}
while (temp != null){
temp = temp.next;
slow = slow.next;
if(temp.equals(slow)){
return temp.item;
}
}
return null;
}
public static Boolean isCircle(Node<String> first){
// 定义两个指针
Node<String>fast = first;
Node<String> slow = first;
// 如果快慢指针指向同一个节点,证明有欢
while(fast.next != null && fast != null){
// 变化fast的值和slow的值
fast = fast.next.next;
slow = slow.next;
if(fast.equals(slow)){
return true;
}
}
return false;
}
// 内部类
private static class Node<T> {
T item;
Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
}
public static void main(String[] args) {
// 创建结点
Node<String> first = new Node<String>("aa",null);
Node<String> second = new Node<String>("bb",null);
Node<String> third = new Node<String>("cc",null);
Node<String> fourth = new Node<String>("dd",null);
Node<String> fifth = new Node<String>("ee",null);
Node<String> six = new Node<String>("ff",null);
Node<String> seven = new Node<String>("gg",null);
// 形成链表
first.next =second;
second.next = third;
third.next = fourth;
fourth.next = fifth;
fifth.next = six;
six.next = seven;
// 产生环
seven.next = first;
}

package linear.test;
/**
* @ClassName JosephTest
* @Authoc 孙少聪
* @Date 2022/8/1 17:32:30
*/
public class JosephTest {
public static void main(String[] args) {
// 创建一个循环链表,包含41个结点,分别存储1-41之间的值
Node<Integer> first = null; // 记录首节点
Node<Integer> pre = null; // 用来记录前一个节点
for (int i = 1; i <= 41; i++) {
// 是第一个节点
if(i==1){
first = new Node(i,null);
pre = first;
continue;
}
// 不是第一个节点
Node<Integer> newNode = new Node<>(i, null);
pre.next = newNode;
pre = newNode;
// 是最后一个节点,吧下一个节点变成头结点
if(i==41){
pre.next = first;
}
System.out.println(pre.item);
}
// count计数器
int count = 0;
// 遍历循环链表
Node<Integer> n = first; // 记录每次遍历拿到的节点
Node<Integer> before = null; // 记录每次遍历拿到的节点的上一个节点
while(n!=n.next){
// 模拟报数
count++;
// 如果是3,则把当前节点删除调用,打印当前节点,重置count,让当前的n后移
if(count==3){
before.next = n.next;
System.out.print(n.item+",");
count = 0;
n = n.next;
}else {// 如果不是3让before变为当前节点,让当前节点后移
before = n;
n = n.next;
}
}
System.out.println(n.item);
System.out.println(1+",");
}
public static class Node<T>{
T item;
Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
}
先进后出(FILO)的数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。压栈,数据从栈中出去的动作为弹栈。

package linear;
import java.util.Iterator;
/**
* @ClassName Stack
* @Authoc 孙少聪
* @Date 2022/8/2 09:36:34
*/
public class Stack<T> implements Iterable<T>{
// 记录首节点
private Node head;
// 栈中元素的个数
private int N;
public class Node{
public T item;
public Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
public Stack(){
this.head = new Node(null,null);
this.N = 0;
}
// 判断是否为空
public boolean isEmpty(){
return N==0;
}
// 判断栈的大小
public int size(){
return N;
}
public void push(T t){
// 存下第一个元素
Node oldFirst = head.next;
Node newNode = new Node(t, null);
head.next = newNode;
newNode.next = oldFirst;
N++;
}
public T pop(){
Node oldFirst = head.next;
if(oldFirst == null){
return null;
}
head.next = oldFirst.next;
N--;
return oldFirst.item;
}
@Override
public Iterator<T> iterator() {
return new SIterator();
}
public class SIterator implements Iterator{
private Node n;
public SIterator() {
this.n = head;
}
@Override
public boolean hasNext() {
return n.next!=null;
}
@Override
public Object next() {
n = n.next;
return n.item;
}
}
}
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
stack.push("a");
stack.push("b");
stack.push("c");
stack.push("d");
stack.push("e");
for (String item: stack) {
System.out.println(item);
}
System.out.println("==============弹栈测试==================");
String result = stack.pop();
System.out.println(result);
System.out.println(stack.size());
}
“(上海)(长安)”:正确匹配
“上海((长安))”:正确匹配
“上海(长安(北京)(深圳)南京)”:正确匹配
“上海(长安))”:错误匹配
“((上海)长安”:错误匹配
public static void main(String[] args) {
String str = "((上海(长安)()))";
boolean match = isMatch(str);
System.out.println(match);
}
// 是否括号匹配,遇到左括号实行压栈,遇到右括号弹出一个左括号,遍历完之后如果有剩余的左括号或者右括号没有左括号与之对应则表示不匹配
private static boolean isMatch(String str) {
Stack<String> stack = new Stack<>();
for (int i = 0; i < str.length(); i++) {
String currChar = str.charAt(i)+"";
if(currChar.equals("(")){
stack.push(currChar);
}else if(currChar.equals(")")){
String pop = stack.pop();
if(pop==null){
return false;
}
}
}
if (stack.size()==0){
return true;
}
return false;
}

public static void main(String[] args) {
String[] notation = {"3", "17", "15", "-", "*","20", "6","/","+"};
int result = caculate(notation);
System.out.println("逆波兰表达式的结果为:"+result);
}
private static int caculate(String[] notation) {
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < notation.length; i++) {
Integer one;
Integer two;
switch (notation[i]){
case "+":
one = stack.pop();
two = stack.pop();
stack.push(two+one);
break;
case "-":
one = stack.pop();
two = stack.pop();
stack.push(two-one);
break;
case "*":
one = stack.pop();
two = stack.pop();
stack.push(two*one);
break;
case "/":
one = stack.pop();
two = stack.pop();
stack.push(two/one);
break;
default:
stack.push(Integer.valueOf(notation[i]));
break;
}
}
int result = stack.pop();
return result;
}


package linear;
import linear.Stack;
import java.io.FileReader;
import java.util.Iterator;
/**
* @ClassName Queue
* @Authoc 孙少聪
* @Date 2022/8/2 15:14:49
*/
public class Queue<T> implements Iterable<T>{
// 记录首节点
private Node head;
// 记录尾节点
private Node last;
// 栈中元素的个数
private int N;
public class Node{
public T item;
public Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
public Queue(){
this.head = new Node(null,null);
this.last = null;
this.N = 0;
}
// 判断是否为空
public boolean isEmpty(){
return N==0;
}
// 判断栈的大小
public int size(){
return N;
}
public void enqueue(T t){
if(last == null){
last = new Node(t,null);
head.next = last;
}else{
Node oldLast = last;
last = new Node(t,null);
oldLast.next = last;
}
N++;
}
public T dequeue(){
if(isEmpty()){
return null;
}
Node oldFirst = head.next;
head.next = oldFirst.next;
N--;
if(isEmpty()){
last = null;
}
return oldFirst.item;
}
@Override
public Iterator<T> iterator() {
return new QIterator();
}
public class QIterator implements Iterator{
private Node n;
public QIterator() {
this.n = head;
}
@Override
public boolean hasNext() {
return n.next!=null;
}
@Override
public Object next() {
n = n.next;
return n.item;
}
}
}
public static void main(String[] args) {
// 创建对象
Queue<String> q = new Queue<>();
q.enqueue("a");
q.enqueue("b");
q.enqueue("c");
q.enqueue("d");
for (String str:q
) {
System.out.println(str);
}
System.out.println("=========================");
String r = q.dequeue();
System.out.println(r);
System.out.println(q.size());
}