数据结构笔记 2

栈的应用

进制转换

例:十进制转十六进制
输入654321,打印输出与其等值的十六进制数。
654321 ÷ 16 =‬ 40895 ~ 1
40895 ÷ 16 = 2555 ~ 15
2555 ÷ 16 = 159 ~ 11
159 ÷ 16 = 9 ~ 15
9 ÷ 16 = 0 ~ 9

9 F B F 1
在这里插入图片描述
十六进制转换为十进制

9 F B F 1
1 × 160 + F × 161 + B × 162 + F × 163 + 9 × 164
1 × 160 + 15 × 161 + 11 × 162 + 15 × 163 + 9 × 164
在这里插入图片描述

import jdk.internal.dynalink.linker.ConversionComparator;
import java.util.Stack;

public class BinaryConversion {
    public static void main(String[] args) {
   
     //进制转化
        int num = 654321;
        String a = Conversion(num);
        System.out.println(a);
        String  n = "9FBF1";
        int p =  Con(n);
        System.out.println(p);
    }
    private static int Con(String n) {
        //  16--> 10;
        Stack <Character>s = new Stack();
        int i = 0;
        int rs = 0;
        while (i < n.length()){
            s.push(n.charAt(i));
            i++;
        }
        while(!s.isEmpty()){
            for (int j = 0; j < n.length(); j++) {
                int p = s.pop();
                if(p <=57 &&p >=49){
                    rs = rs+ (p-48) * mi(16,j);
                }else if(p <=70 && p >=65){
                    rs = rs+ (p-55) * mi(16,j);
                }else{
                    throw new IllegalArgumentException("erro");
                }
            }
        }
        return rs;
    }
    private static int mi(int i, int j) {
        int c = 1;
        if(i==0){
            return 1;
        }
        for(i =0;i < j;i++){
            c = c * 16;
        }
        return c;
    }
    private static String Conversion(int num) {
        //10  --> 16
        StringBuilder sb = new StringBuilder();
        Stack<String> s = new Stack();
        while (num!=0){
            int res = num % 16 ;
            if(res < 10 && res >=0){
                s.push(res+"");
            }else{
                s.push((char)(res + 55) +"");
            }
            num = num/ 16;
        }
        while (!s.isEmpty()){
            sb.append(s.pop());
        }
        return sb.toString();
    }
}

括号匹配

在这里插入图片描述

import java.util.Stack;

public class ParenthesesMatching {
   
    //括号匹配
    public static void main(String[] args) {
        String s1 = "{[<>]()}";
        boolean matching = Matching(s1);
        System.out.println(matching);
    }
    private static boolean Matching(String s1) {
        Stack<Character> st = new Stack();
        for (int i = 0; i < s1.length(); i++) {
            //进栈  如果是空  或者 ASCII码的差值不为2或者1;
            int res = 0;
            if(!st.isEmpty()){
                res = s1.charAt(i) - st.peek();
                if (res ==1 || res == 2){
                    st.pop();
                }else{
                    st.push(s1.charAt(i));
                }
            }else{
                st.push(s1.charAt(i));
            }
        }
        return st.isEmpty();
    }
}

双端栈

双端栈的定义
是指将一个线性表的两端当做栈底分别进行入栈和出栈操作
主要利用了栈“栈底位置不变,而栈顶位置动态变化” 的特性。

                   左栈为空:ltop = -1
                   左栈元素个数:ltop + 1
                   右栈为空:rtop = length
                   右栈元素个数:length – rtop
                   栈满:ltop + 1 = rtop

在这里插入图片描述
双端栈是线性表的一种,更是栈的一个特殊分类,可以用动态数组和栈的思想来实现双端栈
在这里插入图片描述
双端栈扩容缩容问题
在这里插入图片描述
因为双端栈对两端进行操作,所有不能用ArrayList来实现(ArrayList只能在一端进行操作)用数组来实现左右端 push pop peek 等方法

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

public class ArrayDoubleEndStack<E> implements Iterable<E> {
    //属性和行为
    //左端栈的栈顶
    private  int ltop;
    //右端栈的栈顶
    private int rtop;
    //存储元素的容器
    private  E [] data;
    //数组容器的默认容量
    private static int Default_CAPACITY=10;
    public  ArrayDoubleEndStack(){
        data = (E[]) new Object[Default_CAPACITY];
        ltop = -1;
        rtop = data.length;
    }
    public  void pushLeft(E element){
        //判断是否满了
        if(ltop +1 == rtop){
            resize(data.length *2);
        }
        data[++ltop] = element;
    }
    public  void pushRight(E element){
        if(ltop +1 == rtop){
            resize(data.length *2);
        }
        data[--rtop] = element;
    }
    private void resize(int newLen) {
        E[] newData = (E[]) new Object[newLen];
        //复制左端栈
        for (int i = 0; i <= ltop; i++) {
            newData[i] = data[i];
        }
        //复制右端栈的元素
        int index = rtop;
        for (int i = newLen - sizeRight();i < newLen;i++){
            newData[i] = data[index++];
        }
        rtop = newLen - sizeRight();
        data = newData;
    }
    public  E popLeft(){
        if(isLeftEmpty()){
            throw new IllegalArgumentException("left is null");
        }
        E ret = data[ltop--];
        if(sizeLeft() +sizeRight() <= data.length/4 && data.length>Default_CAPACITY){
            resize(data.length/2);
        }
        return  ret;
    }
    public  E popRight(){
        if(isRightEmpty()){
            throw new IllegalArgumentException("right is null");
        }
        E ret = data[rtop++];
        if(sizeLeft() +sizeRight() <= data.length/4 && data.length>Default_CAPACITY){
            resize(data.length/2);
        }
        return  ret;
    }
    public E peekLeft(){
        if(isLeftEmpty()){
            throw new IllegalArgumentException("left is null");
        }
        return data[ltop];
    }
    public  E peekRight(){
        if(isRightEmpty()){
            throw new IllegalArgumentException("right is null");
        }
        return data[rtop];
    }
    public  boolean isLeftEmpty(){
        return ltop ==-1;
    }
    public  boolean isRightEmpty(){
        return  rtop== data.length;
    }
    private int sizeRight() {
        return data.length - rtop;
    }
    private int sizeLeft() {
        return ltop;
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        if(isLeftEmpty()&& isRightEmpty()){
            sb.append("]");
            return  sb.toString();
        }
        //左边
        for (int i = 0; i <= ltop; i++) {
            sb.append(data[i]);
            if(i==ltop && isRightEmpty()){
                sb.append("]");
                return sb.toString();
            }else{
                sb.append(",");
            }
        }
        //右边
        for (int i = rtop; i < data.length ; i++) {
            sb.append(data[i]);
            if(i == data.length-1){
                sb.append("]");
            }else{
                sb.append(",");
            }
        }
        return sb.toString();
    }
    @Override
    public Iterator<E> iterator () {

        return new ArrayDoubleEndStackStackInerator();
    }
    class  ArrayDoubleEndStackStackInerator implements Iterator<E>{
        private ArrayList<E>list1 ;
        private Iterator<E>it;
        public  ArrayDoubleEndStackStackInerator(){
            list1 = new ArrayList<>();
            for (int i = 0; i < ltop; i++) {
                list1.add(data[i]);
            }
            for (int i = rtop; i < data.length ; i++) {
                list1.add(data[i]);
            }
            it = list1.iterator();
        }
        @Override
        public boolean hasNext() {
            return it.hasNext();
        }
        @Override
        public E next() {
            return it.next();
        }
    }
}

用ArrayList实现队列

定义:
1.队列只是允许在一端进行插入操作,而在另一端进行删除操作的线性表
2.队首:允许删除的一端。
3.队尾:插入的一端
4.不含任何数据元素的队列称为空队列
5.队列本身就是一个线性表,其数据元素具有线性关系,只不过他是一种特殊的线性表
6.队列的插入叫做入队
7.队列的删除叫做出队

import p1.接口.Queue;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Objects;

public class ArrayQueue<E> implements Queue<E> {
    //底层用ArrayList
    private ArrayList<E> list ;
    public ArrayQueue(){
        list = new ArrayList<>();
    }
    @Override
    public void offer(E element) {
        //入队
        list.add(list.size(), element);
    }
    @Override
    public E poll() {
        return list.remove(0);
    }
    @Override
    public E peek() {
        return list.get(0);
    }
    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }
    @Override
    public void clear() {
        list.clear();
    }
    @Override
    public int size() {
        return list.size();
    }
    @Override
    public Iterator<E> iterator() {
        return list.iterator();
    }
    @Override
    public String toString() {
        return list.toString();
    }
    @Override
    public boolean equals(Object o) {
       if(o==null){
           return false;
       }
       if(this ==o){
           return true;
       }
       if(o instanceof ArrayQueue){
           ArrayQueue other = (ArrayQueue) o;
           return list.equals(other.list);
       }
       return  false;
    }
}

用栈实现队列

在这里插入图片描述
用两个栈来实现队列的功能
stack A主要存储元素
stackB 临时存储元素

import p1.接口.Queue;
import java.util.Iterator;
import java.util.Stack;

public class StackToQueue {
    //栈实现队列
    public static void main(String[] args) {
        QueueImplByStack <Integer> queue = new QueueImplByStack<>();
        for(int i =1;i <=5;i++){
            queue.offer(i);
        }
        System.out.println(queue);
        System.out.println(queue.poll());
        System.out.println(queue);
    }
}
class QueueImplByStack<E> implements Queue<E>{
    private Stack<E> stackA;
    private Stack<E> stackB;
    public QueueImplByStack(){
        stackA = new Stack<>();
        stackB = new Stack<>();
    }
    @Override
    public void offer(E element) {
        stackA.push(element);
    }
    @Override
    public E poll() {
        if(isEmpty()){
            throw new IllegalArgumentException("queue is null");
        }
        while (stackA.size()!=1){
            stackB.push(stackA.pop());
        }
        E ret = stackA.pop();
        while (!stackB.isEmpty()){
            stackA.push(stackB.pop());
        }
        return ret;
    }
    @Override
    public E peek() {
        if(isEmpty()){
            throw new IllegalArgumentException("queue is null");
        }
        while (stackA.size()!=1){
            stackB.push(stackA.pop());
        }
        E ret = stackA.peek();
        while (!stackB.isEmpty()){
            stackA.push(stackB.pop());
        }
        return ret;
    }
    @Override
    public boolean isEmpty() {
        return stackA.isEmpty();
    }
    @Override
    public void clear() {
        stackA.clear();
        stackB.clear();
    }
    @Override
    public int size() {
        return stackA.size();
    }
    @Override
    public Iterator<E> iterator() {
        return stackA.iterator();
    }
    @Override
    public String toString() {
        return stackA.toString();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值