HMJAVA数据结构与算法4【线性表】

1、顺序表

1.1 顺序表实现

 

 

复制代码
package com.haifei.demo02linear;

import java.util.Iterator;

public class SequenceList <T>{

    //存储元素的数组
    private T[] eles;
    //记录当前顺序表中的元素个数
    private int N;

    //构造方法
    public SequenceList(int capacity){
        //初始化数组
        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];
    }

    //向线性表中追加元素t
    public void insert(T t){
        eles[N++] = t;
    }

    //在线性表索引i处插入元素t
    public void insert(int i, T t){
        //先把i索引处及其后面的元素依次向后移动一位
        for (int index=N-1; index>i; index--){
            eles[index] = eles[index-1];
        }
        //再将t元素添加到i索引处
        eles[i] = t;
    }

    //删除线性表索引i处的元素,并返回该元素
    public T remove(int i){
        //记录索引i处的元素
        T current = eles[i];
        //索引i处后面的元素依次向前移动一位
        for (int index=i; index<N-1; index++){
            eles[index] = eles[index+1];
        }
        //元素个数-1
        N--;
        //返回已删除元素
        return current;
    }

    //查照线性表中t元素第一次出现的位置
    public int indexOf(T t){
        for (int i=0; i<N; i++){
            if (eles[i].equals(t)){
                return i;
            }
        }
        return -1; //线性表当前不存在t元素
    }

}
View Code
复制代码
复制代码
package com.haifei.demo02linear.test;

import com.haifei.demo02linear.SequenceList;

public class Test01SequenceList {

    public static void main(String[] args) {
        //创建顺序表对象
        SequenceList<String> sl = new SequenceList<>(10);

        //测试插入
        sl.insert("姚明");
        sl.insert("科比");
        sl.insert("麦迪");
        sl.insert(1,"詹姆斯");
        //测试获取
        String getResult = sl.get(1);
        System.out.println("获取索引1处的结果为:"+getResult); //詹姆斯
        //测试删除
        String removeResult = sl.remove(0);
        System.out.println("删除的元素是:"+removeResult); //姚明
        //测试清空
        sl.clear();
        System.out.println("清空后的线性表中的元素个数为:"+sl.length()); //0
    }

}
View Code
复制代码

 

1.2 顺序表遍历

 

 

 

 

复制代码
package com.haifei.demo02linear;

import java.util.Iterator;

public class SequenceList <T> implements Iterable<T>{

    //存储元素的数组
    private T[] eles;
    //记录当前顺序表中的元素个数
    private int N;

    //构造方法
    public SequenceList(int capacity){
        //初始化数组
        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];
    }

    //向线性表中追加元素t
    public void insert(T t){
        eles[N++] = t;
    }

    //在线性表索引i处插入元素t
    public void insert(int i, T t){
        //先把i索引处及其后面的元素依次向后移动一位
        for (int index=N; index>i; index--){
            eles[index] = eles[index-1];
        }
        //再将t元素添加到i索引处
        eles[i] = t;
        //元素个数+1
        N++;
    }

    //删除线性表索引i处的元素,并返回该元素
    public T remove(int i){
        //记录索引i处的元素
        T current = eles[i];
        //索引i处后面的元素依次向前移动一位
        for (int index=i; index<N-1; index++){
            eles[index] = eles[index+1];
        }
        //元素个数-1
        N--;
        //返回已删除元素
        return current;
    }

    //查照线性表中t元素第一次出现的位置
    public int indexOf(T t){
        for (int i=0; i<N; i++){
            if (eles[i].equals(t)){
                return i;
            }
        }
        return -1; //线性表当前不存在t元素
    }


    @Override
    public Iterator<T> iterator() {
        return new 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++];
        }
    }


}
View Code
复制代码
复制代码
package com.haifei.demo02linear.test;

import com.haifei.demo02linear.SequenceList;

public class Test01SequenceList {

    public static void main(String[] args) {
        //创建顺序表对象
        SequenceList<String> sl = new SequenceList<>(10);

        //测试插入
        sl.insert("姚明");
        sl.insert("科比");
        sl.insert("麦迪");
        sl.insert(1,"詹姆斯");
        //测试遍历
        for (String s : sl) {
            System.out.println(s);
        }
        /*
        姚明
        詹姆斯
        科比
        麦迪
         */
        System.out.println("========================");
        //测试获取
        String getResult = sl.get(1);
        System.out.println("获取索引1处的结果为:"+getResult); //詹姆斯
        //测试删除
        String removeResult = sl.remove(0);
        System.out.println("删除的元素是:"+removeResult); //姚明
        //测试清空
        sl.clear();
        System.out.println("清空后的线性表中的元素个数为:"+sl.length()); //0
    }

}
View Code
复制代码

 

1.3 顺序表的容量可变

复制代码
package com.haifei.demo02linear.test;

import com.haifei.demo02linear.SequenceList;

public class Test02SequenceList {

    public static void main(String[] args) {
        SequenceList<String> sl = new SequenceList<>(3);

        sl.insert("张三");
        sl.insert("李四");
        sl.insert("王五");
//        sl.insert("赵六"); //java.lang.ArrayIndexOutOfBoundsException: 3

    }

}
View Code
复制代码

 

 

 

 

 

 

复制代码
package com.haifei.demo02linear;

import java.util.Iterator;

public class SequenceList <T> implements Iterable<T>{

    //存储元素的数组
    private T[] eles;
    //记录当前顺序表中的元素个数
    private int N;

    //构造方法
    public SequenceList(int capacity){
        //初始化数组
        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];
    }

    //向线性表中追加元素t
    /*public void insert(T t){
        eles[N++] = t;
    }*/
    public void insert(T t){
        if (N == eles.length){ //扩容
            resize(2 * eles.length);
        }

        eles[N++] = t;
    }

    //在线性表索引i处插入元素t
    /*public void insert(int i, T t){
        //先把i索引处及其后面的元素依次向后移动一位
        for (int index=N-1; index>i; index--){
            eles[index] = eles[index-1];
        }
        //再将t元素添加到i索引处
        eles[i] = t;
    }*/
    /*public void insert(int i, T t){
        //先把i索引处及其后面的元素依次向后移动一位
        for (int index=N; index>i; index--){
            eles[index] = eles[index-1];
        }
        //再将t元素添加到i索引处
        eles[i] = t;
        //元素个数+1
        N++;
    }*/
    public void insert(int i, T t){
        if (N == eles.length){ //扩容
            resize(2 * eles.length);
        }

        //先把i索引处及其后面的元素依次向后移动一位
        for (int index=N; index>i; index--){
            eles[index] = eles[index-1];
        }
        //再将t元素添加到i索引处
        eles[i] = t;
        //元素个数+1
        N++;
    }

    //删除线性表索引i处的元素,并返回该元素
    /*public T remove(int i){
        //记录索引i处的元素
        T current = eles[i];
        //索引i处后面的元素依次向前移动一位
        for (int index=i; index<N-1; index++){
            eles[index] = eles[index+1];
        }
        //元素个数-1
        N--;
        //返回已删除元素
        return current;
    }*/
    public T remove(int i){
        //记录索引i处的元素
        T current = eles[i];
        //索引i处后面的元素依次向前移动一位
        for (int index=i; index<N-1; index++){
            eles[index] = eles[index+1];
        }
        //元素个数-1
        N--;

        if (N < eles.length/4){ //缩容
            resize(eles.length / 2);
        }

        //返回已删除元素
        return current;
    }

    //查照线性表中t元素第一次出现的位置
    public int indexOf(T t){
        for (int i=0; i<N; i++){
            if (eles[i].equals(t)){
                return i;
            }
        }
        return -1; //线性表当前不存在t元素
    }

    //根据参数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];
        }
    }


    @Override
    public Iterator<T> iterator() {
        return new 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++];
        }
    }


}
View Code
复制代码
复制代码
package com.haifei.demo02linear.test;

import com.haifei.demo02linear.SequenceList;

public class Test02SequenceList {

    public static void main(String[] args) {
        /*SequenceList<String> sl = new SequenceList<>(3);
        sl.insert("张三");
        sl.insert("李四");
        sl.insert("王五");
//        sl.insert("赵六"); //java.lang.ArrayIndexOutOfBoundsException: 3*/


        //在SequenceList类中添加resize()以及对应插入删除配置后
        SequenceList<String> sl = new SequenceList<>(3);
        sl.insert("张三");
        sl.insert("李四");
        sl.insert("王五");
        sl.insert("赵六"); //ok
    }

}
View Code
复制代码

 

1.4 顺序表的时间复杂度

 

 

1.5 Java中ArrayList实现

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2、链表

 

 

 

 

 

 

 

 

 

 

 

 

2.1 单向链表

 

 

 

 

 

 

复制代码
package cn.itcast.algorithm.linear;

import java.util.Iterator;

public class LinkList<T> implements Iterable<T>{
    //记录头结点
    private Node head;
    //记录链表的长度
    private int N;



    //结点类
    private class Node {
        //存储数据
        T item;
        //下一个结点
        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 index=0;index<i;index++){
            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++;
    }

    //向指定位置i出,添加元素t
    public void insert(int i, T t) {
        //找到i位置前一个结点
        Node pre = head;
        for(int index=0;index<=i-1;index++){
            pre=pre.next;
        }

        //找到i位置的结点
        Node curr = pre.next;
        //创建新结点,并且新结点需要指向原来i位置的结点
        Node newNode = new Node(t, curr);
        //原来i位置的前一个节点指向新结点即可
        pre.next=newNode;
        //元素的个数+1
        N++;
    }

    //删除指定位置i处的元素,并返回被删除的元素
    public T remove(int i) {
        //找到i位置的前一个节点
        Node pre = head;
        for(int index=0;index<=i-1;i++){
            pre=pre.next;
        }
        //要找到i位置的结点
        Node curr = pre.next;
        //找到i位置的下一个结点
        Node nextNode = curr.next;
        //前一个结点指向下一个结点
        pre.next=nextNode;
        //元素个数-1
        N--;
        return curr.item;
    }

    //查找元素t在链表中第一次出现的位置
    public int indexOf(T t) {
        //从头结点开始,依次找到每一个结点,取出item,和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;
        }
    }

    //用来反转整个链表
    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;
    }


}
View Code
复制代码

 

2.2 双向链表

 

 

 

 

 

复制代码
package cn.itcast.algorithm.linear;

import java.util.Iterator;

public class TowWayLinkList<T> implements Iterable<T> {
    //首结点
    private Node head;
    //最后一个结点
    private Node last;

    //链表的长度
    private int N;



    //结点类
    private class Node{
        public Node(T item, Node pre, Node next) {
            this.item = item;
            this.pre = pre;
            this.next = next;
        }

        //存储数据
        public T item;
        //指向上一个结点
        public Node pre;
        //指向下一个结点
        public Node next;
    }

    public TowWayLinkList() {
       //初始化头结点和尾结点
        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(){
        if (isEmpty()){
            return null;
        }
        return head.next.item;
    }

    //获取最后一个元素
    public T getLast(){
        if (isEmpty()){
            return null;
        }
        return last.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++;

    }

    //向指定位置i处插入元素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 get(int i){
        Node n = head.next;
        for(int index=0;index<i;index++){
            n=n.next;
        }
        return n.item;
    }

    //找到元素t在链表中第一次出现的位置
    public int indexOf(T t){
        Node n = head;
        for(int i=0;n.next!=null;i++){
            n=n.next;
            if (n.next.equals(t)){
                return i;
            }
        }
        return -1;
    }

    //删除位置i处的元素,并返回该元素
    public T remove(int i){
        //找到i位置的前一个结点
        Node pre = head;
        for(int index=0;index<i;index++){
            pre=pre.next;
        }
        //找到i位置的结点
        Node curr = pre.next;
        //找到i位置的下一个结点
        Node nextNode= curr.next;
        //让i位置的前一个结点的下一个结点变为i位置的下一个结点
        pre.next=nextNode;
        //让i位置的下一个结点的上一个结点变为i位置的前一个结点
        nextNode.pre=pre;
        //元素的个数-1
        N--;
        return curr.item;
    }

    @Override
    public Iterator<T> iterator() {
        return new TIterator();
    }

    private class TIterator implements Iterator{
        private Node n;
        public TIterator(){
            this.n=head;
        }
        @Override
        public boolean hasNext() {
            return n.next!=null;
        }

        @Override
        public Object next() {
            n=n.next;
            return n.item;
        }
    }

}
View Code
复制代码

 

 

 

 

2.3 链表的时间复杂度

 

 

 

 

2.4 链表翻转

 

 

 

 

 

 

 

 

 

public void reverse(){
    if (N==0){
        //当前是空链表,不需要反转
        return;
    }
    reverse(head.next);
}    

 

复制代码
/**
*
* @param curr 当前遍历的结点
* @return 反转后当前结点上一个结点
*/
public Node reverse(Node curr){
    //已经到了最后一个元素
    if (curr.next==null){
        //反转后,头结点应该指向原链表中的最后一个元素
        head.next=curr;
        return curr;
    }
    //当前结点的上一个结点
    Node pre = reverse(curr.next);     
    pre.next = curr;
    //当前结点的下一个结点设为null
    curr.next=null;
    //返回当前结点
    return curr;
}
复制代码

 

2.5 快慢指针的应用(中间值、单链表有环否、有环链表入口)

快慢指针指的是定义两个指针,这两个指针的移动速度一块一慢,以此来制造出自己想要的差值,

这个差值可以让我们找到链表上相应的结点。一般情况下,快指针的移动步长为慢指针的两倍

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

复制代码
/**
* 判断链表中是否有环
* @param first 链表首结点
* @return ture为有环,false为无环
*/
public static boolean isCircle(Node<String> first) {
    Node<String> slow = first;
    Node<String> fast = first;
    while(fast!=null && fast.next!=null){
        fast = fast.next.next;
        slow = slow.next;
        if (fast.equals(slow)){
            return true;
        }
    }
    return false;
} 
复制代码

 

 

 

 

 

 

 

2.6 循环链表

 

 

2.7 约瑟夫问题

 

 

 

 

 

 

3、栈

3.1 栈概述

 

 

3.2 栈实现

 

 

复制代码
package cn.itcast.algorithm.linear;

import java.util.Iterator;

public class Stack<T> implements Iterable<T>{
    //记录首结点
    private Node head;
    //栈中元素的个数
    private int N;



    private 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;
    }

    //判断当前栈中元素个数是否为0
    public boolean isEmpty(){
        return N==0;
    }

    //获取栈中元素的个数
    public int size(){
        return N;
    }

    //把t元素压入栈
    public void push(T t){
        //找到首结点指向的第一个结点
        Node oldFirst = head.next;
        //创建新结点
        Node newNode = new Node(t, null);
        //让首结点指向新结点
        head.next = newNode;
        //让新结点指向原来的第一个结点
        newNode.next=oldFirst;
        //元素个数+1;
        N++;
    }

    //弹出栈顶元素
    public T pop(){
        //找到首结点指向的第一个结点
        Node oldFirst = head.next;
        if (oldFirst==null){
            return null;
        }
        //让首结点指向原来第一个结点的下一个结点
        head.next=oldFirst.next;
        //元素个数-1;
        N--;
        return oldFirst.item;
    }

    @Override
    public Iterator<T> iterator() {
        return new SIterator();
    }

    private 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;
        }
    }

}
View Code
复制代码

 

3.3 栈案例

 

 

 

 

 

复制代码
package cn.itcast.algorithm.test;

import cn.itcast.algorithm.linear.Stack;

public class BracketsMatchTest {
    public static void main(String[] args) {
        String str = "上海(长安)())";
        boolean match = isMatch(str);
        System.out.println(str+"中的括号是否匹配:"+match);
    }

    /**
     * 判断str中的括号是否匹配
     * @param str 括号组成的字符串
     * @return 如果匹配,返回true,如果不匹配,返回false
     */
    public static boolean isMatch(String str){
        //1.创建栈对象,用来存储左括号
        Stack<String> chars = new Stack<>();
        //2.从左往右遍历字符串
        for (int i = 0; i < str.length(); i++) {
            String currChar = str.charAt(i)+ "";

            //3.判断当前字符是否为左括号,如果是,则把字符放入到栈中
            if (currChar.equals("(")){
                chars.push(currChar);
            }else if(currChar.equals(")")){
                //4.继续判断当前字符是否是有括号,如果是,则从栈中弹出一个左括号,并判断弹出的结果是否为null,如果为null证明没有匹配的左括号,如果不为null,则证明有匹配的左括号
                String pop = chars.pop();
                if (pop==null){
                    return false;
                }
            }

        }
        //5.判断栈中还有没有剩余的左括号,如果有,则证明括号不匹配
        if (chars.size()==0){
            return true;
        }else{
            return false;
        }

    }
}
View Code
复制代码

 

 

 

 

 

 

 

 

 

 

 

复制代码
package cn.itcast.algorithm.test;


import cn.itcast.algorithm.linear.Stack;

public class ReversePolishNotationTest {

    public static void main(String[] args) {
        //中缀表达式 3*(17-15)+18/6 的逆波兰表达式如下 6+3=9
        String[] notation = {"3", "17", "15", "-", "*", "18", "6", "/", "+"};
        int result = caculate(notation);
        System.out.println("逆波兰表达式的结果为:" + result);
    }

    /**
     * @param notaion 逆波兰表达式的数组表示方式
     * @return 逆波兰表达式的计算结果
     */
    public static int caculate(String[] notaion) {
        //1.定义一个栈,用来存储操作数
        Stack<Integer> oprands = new Stack<>();
        //2.从左往右遍历逆波兰表达式,得到每一个元素
        for (int i = 0; i < notaion.length; i++) {
            String curr = notaion[i];
            //3.判断当前元素是运算符还是操作数
            Integer o1;
            Integer o2;
            Integer result;
            switch (curr) {
                case "+":
                    //4.运算符,从栈中弹出两个操作数,完成运算,运算完的结果再压入栈中
                    o1 = oprands.pop();
                    o2 = oprands.pop();
                    result = o2 + o1;
                    oprands.push(result);
                    break;
                case "-":
                    //4.运算符,从栈中弹出两个操作数,完成运算,运算完的结果再压入栈中
                    o1 = oprands.pop();
                    o2 = oprands.pop();
                    result = o2 - o1;
                    oprands.push(result);
                    break;
                case "*":
                    //4.运算符,从栈中弹出两个操作数,完成运算,运算完的结果再压入栈中
                    o1 = oprands.pop();
                    o2 = oprands.pop();
                    result = o2 * o1;
                    oprands.push(result);
                    break;
                case "/":
                    //4.运算符,从栈中弹出两个操作数,完成运算,运算完的结果再压入栈中
                    o1 = oprands.pop();
                    o2 = oprands.pop();
                    result = o2 / o1;
                    oprands.push(result);

                    break;
                default:
                    //5.操作数,把该操作数放入到栈中;
                    oprands.push(Integer.parseInt(curr));
                    break;
            }

        }


        //6.得到栈中最后一个元素,就是逆波兰表达式的结果
        int result = oprands.pop();

        return result;
    }

}
View Code
复制代码

 

 

4、队列

 

 

 

 

复制代码
package cn.itcast.algorithm.linear;

import java.util.Iterator;

public class Queue<T> implements Iterable<T>{
    //记录首结点
    private Node head;
    //记录最后一个结点
    private Node last;
    //记录队列中元素的个数
    private int N;


    private 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;
    }

    //向队列中插入元素t
    public void enqueue(T t){

        if (last==null){
            //当前尾结点last为null
            last= new Node(t,null);
            head.next=last;
        }else {
            //当前尾结点last不为null
            Node oldLast = last;
            last = new Node(t, null);
            oldLast.next=last;
        }

        //元素个数+1
        N++;
    }

    //从队列中拿出一个元素
    public T dequeue(){
        if (isEmpty()){
            return null;
        }

        Node oldFirst= head.next;
        head.next=oldFirst.next;
        N--;

        //因为出队列其实是在删除元素,因此如果队列中的元素被删除完了,需要重置last=null;

        if (isEmpty()){
            last=null;
        }
        return oldFirst.item;
    }


    @Override
    public Iterator<T> iterator() {
        return new QIterator();
    }

    private 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;
        }
    }


}
View Code
复制代码

 

posted @   yub4by  阅读(34)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示