数据结构与算法

p6-9 二维数组与稀疏数组

在这里插入图片描述

package com.atguigu.sparseArray;

public class SparseArray {
    public static void main(String[] args) {
        //数据结构与算法 p9
        int[][] chessArr = new int[11][11];
        chessArr[1][2]=1;
        chessArr[2][3]=2;
        //非0的棋子
        int num=0;
        //行
        int rowNum = chessArr.length;
        //列
        int rankNum = chessArr[0].length;
//        System.out.println(rowNum);
//        System.out.println(rankNum);
        for (int[] row : chessArr) {
            for (int i : row) {
                System.out.printf("%d\t",i);
                if (i!=0){
                    num++;
                }
            }
            System.out.println();
        }
        //转换为稀疏数组
        int[][] sparseArr = new int[num + 1][3];
        sparseArr[0][0]=rowNum;
        sparseArr[0][1]=rankNum;
        sparseArr[0][2]=num;
        int sparseRow=0;
        for (int i = 0; i < chessArr.length; i++) {
            for (int j = 0; j < chessArr[i].length; j++) {
                if (chessArr[i][j]!=0){
                    sparseRow++;
                    sparseArr[sparseRow][0]=i;
                    sparseArr[sparseRow][1]=j;
                    sparseArr[sparseRow][2]=chessArr[i][j];
                }
            }
        }
        System.out.println("转换为稀疏数组");
        for (int[] ints : sparseArr) {
            for (int anInt : ints) {
                System.out.printf("%d\t",anInt);
            }
            System.out.println();
        }

        //把稀疏数组还原为二维数组
        int x=sparseArr[0][0];
        int y=sparseArr[0][1];
        int[][] newchessArr = new int[x][y];
//        for (int i = 0; i < newchessArr.length; i++) {
//            for (int j = 0; j < newchessArr[i].length; j++) {
//
//            }
//        }
        for (int i = 1; i < sparseArr.length; i++) {
            int x1=sparseArr[i][0];
            int y1=sparseArr[i][1];
            int val=sparseArr[i][2];
            newchessArr[x1][y1]=val;
        }
        System.out.println("把稀疏数组还原为二维数组");
        for (int[] ints : newchessArr) {
            for (int anInt : ints) {
                System.out.printf("%d\t",anInt);
            }
            System.out.println();
        }
    }
}

p 11 数组模拟队列

在这里插入图片描述

package com.atguigu.queue;

public class ArrayQueueDemo {
    public static void main(String[] args) {
        ArrayQueue arrayQueue = new ArrayQueue(3);
        try {
            arrayQueue.showList();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        arrayQueue.addQueue(4);
        arrayQueue.addQueue(1);
        try {
            arrayQueue.showList();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        System.out.println("获取:" + arrayQueue.getQueue());
        System.out.println("获取:" + arrayQueue.getQueue());
//        System.out.println("获取:"+arrayQueue.getQueue());

        arrayQueue.addQueue(3);
        arrayQueue.addQueue(5);
        try {
            arrayQueue.showList();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        try {
            System.out.println("获取:" + arrayQueue.getQueue());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        try {
            System.out.println("获取:" + arrayQueue.getQueue());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

}

//使用数组模拟队列
class ArrayQueue {
    private int maxSize;
    private int front;//队列头的前一个位置
    private int rear;//队列尾部,就是最后一个位置
    private int[] arr;

    public ArrayQueue(int arrMaxSize) {
        this.maxSize = arrMaxSize;
        arr = new int[arrMaxSize];
        front = -1;
        rear = -1;
    }

    //判断队列是否满
    public boolean isFull() {
        return rear == maxSize - 1;
    }

    //判断队列是否为空
    public boolean isEmpty() {
        return rear == front;
    }

    //    添加数据到队列
    public void addQueue(int n) {
        if (isFull()) {
            System.out.println("队列已满无法添加");
            return;
        }
        rear++;
        arr[rear] = n;
    }

    //获取队列数据,出队
    public int getQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空,不能取数据");
        }
        front++;
        return arr[front];
    }

    //显示队列所有数据
//    -1-a-b-c-d
    public void showList() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空");
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.printf("arr[%d]=%d\n", i, arr[i]);
        }
    }

    //显示头数据,不是取出
    public int headQueue() {
        if (isEmpty()) {
            throw new RuntimeException("队列为空");
        }
        return arr[front + 1];
    }


}

在这里插入图片描述

p14 数组模拟环形队列

在这里插入图片描述
韩老师给的图有点问题,讲得不是很清楚,自己画个下面的图就理解了,rear是一个空位
在这里插入图片描述

package com.atguigu.queue;

/**
 * 循环队列
 */
public class CircleArrQueue {
    //    0 0 0 0
    //指向第一个元素,初始值为0
    private int front;
    //指向最后一个元素的后一位,留一个空位不放元素 ,初始值为0
    private int rear;
    private int maxSize;
    private int[] arr;

    //循环队列
    public CircleArrQueue(int maxSize) {
        this.maxSize = maxSize;
        arr = new int[maxSize];
    }

    //判断队列是否为空
    public boolean ifEmpty() {
        return front == rear;
    }

    //判断队列是否已满
    public boolean ifFull() {
        return (rear + 1) % maxSize == front;
    }

    //判断有效元素个数
    public int size() {
        return (rear - front + maxSize) % maxSize;
    }


    //    添加元素
    public void add(int ele) {
        if (ifFull()) {
            throw new RuntimeException("队列已满,无法添加元素");
        }
        arr[rear] = ele;
        rear = (rear + 1) % maxSize;
    }

    //    取出元素
    public synchronized int get() {
        if (ifEmpty()) {
            throw new RuntimeException("队列为空");
        }
        int ele = arr[front];
        front = (front + 1) % maxSize;
        return ele;
    }

    //    //队列有效个数
//    public int size(){
//        return (rear-front+maxSize)%maxSize;
//    }
    //显示所有数据
    public void show() {
        if (ifEmpty()) {
            throw new RuntimeException("队列为空");
        }
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d]:%d ",i%maxSize,arr[i%maxSize]);
        }
    }

    public int  head(){
        if (ifEmpty()) {
            throw new RuntimeException("队列为空");
        }
        return arr[front];
    }
}

p17 链表创建和遍历 p18顺序插入

package com.atguigu.linkedlist;

public class HeroNode {
    public int no;
    public String name;
    public String nickName;
    public HeroNode next;

    public HeroNode(){}

    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 + '\'' +
                '}';
    }
}

package com.atguigu.linkedlist;

public class SingleLikedlist {
    //先初始化一个头节点
    private HeroNode head = new HeroNode(0, "", "");

    //添加节点到单向节点 0->1->1->1
    //当不考虑编号的顺序时,找到当前链表的最后节点,将最后这个节点测next指向新节点
    public void add(HeroNode heroNode) {
        HeroNode temp = head;
        while (true) {
//            0->null
            if (temp.next == null) {
                temp.next = heroNode;
                break;
            }
//            0->1->4->7
            temp = temp.next;
        }
    }

    /**
     * 顺序添加
     *
     * @param heroNode
     */
    public void addByOrder(HeroNode heroNode) {
        HeroNode temp = this.head;
        while (true) {
//            0->null
            if (temp.next == null) {
                temp.next = heroNode;
                break;
            }

//            0->3->4->7
            //假设添加2号
            if (temp.next.no > heroNode.no) {
                heroNode.next = temp.next;
                temp.next = heroNode;
                break;
            } else if (temp.next.no == heroNode.no) {//假设添加3号
                System.out.println("已存在该英雄");
                break;
            }
            // 0->3->4->7
            //如果上诉条件都不满足,指针往后移一位
            temp = temp.next;
        }
    }

    public void showList() {
        if (head.next == null) {
            return;
        }
        HeroNode temp = head.next;
        while (true) {
            //是否到链表最后
            if (temp == null) {
                break;
            }
            //输出节点信息;
            System.out.println(temp);
            temp = temp.next;//后移节点
        }
    }

    public void showList2() {
//        if (head.next == null) {
//            System.out.println("链表为空");
//            return;
//        }
        HeroNode tem = head.next;
        while (true) {
            if (tem != null) {
                System.out.println(tem);
                tem = tem.next;
            } else {
                break;
            }
        }
    }

    @Override
    public String toString() {
        return "SingleLikedlist{" +
                "head=" + head +
                '}';
    }

    public int getLength() {
        HeroNode temp = head.next;
        if (temp == null) {
            return 0;
        }
        int length = 0;
        while (true) {
            if (temp != null) {
                length++;
                System.out.println("计数+1");
                temp = temp.next;
            } else {
                System.out.println("计数完成");
                break;
            }
        }
        return length;
    }

    public int getLength2() {
        HeroNode temp = head.next;
        int length = 0;
        while (true) {
            if (temp != null) {
                length++;
                System.out.println("计数+1");
                temp = temp.next;
            } else {
                System.out.println("计数完成");
                break;
            }
        }
        return length;
    }
    //查找倒数第k个节点,假设查找倒数第三个节点,那就是查找第7-3+1个节点
    // 0  ->3->4->7->15->96->12->55


    //链表反转 0  ->3->4->7->15
    // 0  ->4->7->15     head->3
    // 0  ->7->15     head->4->3
    // 0  ->15     head->7->4->3
}

p19 单链表节点修改

//    根据编号修改节点
    public void update(HeroNode heronode ){
        HeroNode temp=head.next;
        if (temp==null){
            System.out.println("链表为空");
        }
        while (true){
            if (temp==null){
                System.out.println("没有找到要修改的节点");
                break;
            }
            //找到了
            if (temp.no==heronode.no){
                System.out.println("找到节点直接修改");
                temp.setName(heronode.getName());
                temp.setNickName(heronode.getNickName());
                break;
            }
            //没找到,移动到下一个节点
            temp=temp.next;
        }
    }
        System.out.println("=====================");
        HeroNode heroNodeUpdate = new HeroNode(3, "松江", "及时雨11");
                singleLikedlist.update(heroNodeUpdate);
        singleLikedlist.showList2();

p20 单链表的删除

//    根据编号删除节点 0  ->3->4->7->15
    public void delete(int no){
        HeroNode temp=head;
        if (temp.next==null){
            System.out.println("链表为空");
            return;
        }
//        0  ->3
        while (true){
            if (temp.next==null){
                System.out.println("没有找到删除节点"+no);
                return;
            }
            if (temp.next.no==no){
                System.out.println("找到删除节点"+no);
                temp.next= temp.next.next;
                break;
            }
            temp=temp.next;
        }
    }
        System.out.println("=====================删除");
        singleLikedlist.delete(1);
        singleLikedlist.delete(2);
        singleLikedlist.delete(3);
        singleLikedlist.delete(4);
        singleLikedlist.showList2();
        singleLikedlist.delete(4);
        singleLikedlist.showList2();

p21 链表面试题

获取链表长度

    public int getLength2() {
        HeroNode temp = head.next;
        int length = 0;
        while (true) {
            if (temp != null) {
                length++;
//                System.out.println("计数+1");
                temp = temp.next;
            } else {
//                System.out.println("计数完成");
                break;
            }
        }
        return length;
    }

获取倒数第几个节点

//查找倒数第k个节点,假设查找倒数第三个节点,那就是查找第7-3+1个节点
    // 0  ->3->4->7->15->96->12->55
    public HeroNode findLastIndexNode(int index){
        HeroNode temp = head.next;
        if (temp==null){
            System.out.println("链表为空");
            return null;
        }
        int length2 = getLength2();
        if (index<=0||index>length2){
            System.out.println("没有该位置元素");
            return null;
        }
        int target=length2-index+1;//5
        int begin=1;
//        while (true){
//            if (begin==target){
//                return temp;
//            }
//            begin++;
//            temp=temp.next;
//        }

        for (int start=1;start<target;start++){
            temp=temp.next;
        }
        return temp;
    }

p22 链表反转

//链表反转 head  ->3->4->7->15  newHead->null
    // head  ->4->7->15     newHead->3
    // head  ->7->15     newHead->4->3
    // head  ->15     newHead->7->4->3
    // head  ->null     newHead->15->7->4->3
    // head  ->15->7->4->3     newHead->

    public void reverse() {
        HeroNode newHead = new HeroNode(0, "", "");

//        HeroNode temp =next;
        while (true) {
            HeroNode temp = head.next;
            if (temp != null) {
                head.next=temp.next;//移动到下一个节点
                temp.next = newHead.next;//把新head的最前面的节点挂到新来的节点的后面
                newHead.next = temp;
            }else{
                break;
            }
        }
        //最后把节点全部挂到原来的head上
        head.next=newHead.next;
    }

p23使用栈逆序打印

 //    逆序打印单链表,方式1先反转链表(会改变链表结构),方式2使用栈 head  ->3->4->7->15
    public void reversePrint() {
        Stack<HeroNode> stack = new Stack<HeroNode>();
        HeroNode temp=head.next;
        while (temp!=null){
            stack.push(temp);
            temp=temp.next;
        }
        while (stack.size()>0){
            System.out.println(stack.pop());
        }
    }

p30-32 栈

package com.atguigu.linkedlist;

public class ArrayStackDemo {
    public static void main(String[] args) {
        ArrayStack arrayStack = new ArrayStack(4);
//        arrayStack.showList();
        arrayStack.push(52);
        arrayStack.push(33);
        arrayStack.push(11);
        arrayStack.push(99);
//        arrayStack.push(991);
        arrayStack.showList();
        System.out.println();
        arrayStack.pop();
        arrayStack.pop();
        arrayStack.pop();
        arrayStack.pop();
        arrayStack.pop();
    }

    static class ArrayStack{
        private int maxSize;//栈的大小
        private int[] stack;
        private int top=-1;//栈顶初始化为-1

        public ArrayStack(int maxSize) {
            this.maxSize = maxSize;
            this.stack = new int[maxSize];
        }

        //栈满
        public boolean isFull(){
            return top==maxSize-1;
        }

        //栈空
        public boolean isEmpty(){
            return top==-1;
        }

        public void push(int e){
            if (isFull()){
                System.out.println("栈已满");
                return;
            }
            top++;
            stack[top]=e;
        }

        public void pop(){
            if (isEmpty()){
                System.out.println("栈已空");
                return;
            }
            int val=stack[top];
            System.out.println("弹出:"+val);
            top--;
        }

        //展示栈元素
        public void showList(){
            if (isEmpty()){
                System.out.println("栈已空");
                return;
            }
            for (int i=top;i>=0;i--){
                System.out.printf("arr[%d]=%d ",i,stack[i]);
            }
        }
    }
}

p33-35 栈实现中缀表达式计算器

package com.atguigu.stack;

import java.util.Stack;

public class MiddleExpress {
    public static void main(String[] args) {

        MiddleExpress middleExpress = new MiddleExpress();
        middleExpress.calculate();
    }

    //中缀表达式为3+2*6-2 使用栈完成一个表达式的结果,目前还不支持小括号
    // 创建2个栈,一个是符号栈,一个是数字栈,
    // 依次遍历表达式每个字符,
    // 如果是数字,直接入数字栈,
    // 如果是符号,
    //      如果符号栈当前为空或者 该符号优先级大于当前栈顶的符号,直接入栈,
    //      否则数字栈弹出2个数,符号栈弹出一个符号,计算出结果,将结果入数字栈,再将符号入符号栈
    //当表达式扫描完毕,就顺序的从数字栈弹出2个数字,符号栈弹出一个符号,计算得出结果,将结果入数字栈
    //最终数字栈只有一个数,符号栈为空,数字栈结果就为最终结果
    public void calculate() {
        ArrayStack numStack = new ArrayStack(10);
        ArrayStack signStack = new ArrayStack(10);
        String express = "316+2*6-200";
        int index = express.length();
        String wholeStr = "";
        for (int i = 0; i < index; i++) {
            char c = express.charAt(i);
            if (Character.isDigit(c)) {//如果是数字,判断是否是多位数,把多位数拼接好
                wholeStr = String.valueOf(c - 48);
                //保证不是最后一位
                while (i < index - 1 && Character.isDigit(express.charAt(i + 1))) {
                    wholeStr += (express.charAt(++i) - 48);
                }
                numStack.push(Integer.parseInt(wholeStr));
            } else if (isSign(c)) { //如果是符号,
                if (signStack.isEmpty() || getSignLevel(c) > getSignLevel((char) signStack.peek())) {
                    signStack.push(c);
                } else {
                    int num1 = numStack.pop();
                    int num2 = numStack.pop();
                    char sign = (char) signStack.pop();
                    int result = compute(num1, num2, sign);
                    numStack.push(result);
                    signStack.push(c);
                }
            } else {
                System.out.println("表达式输入错误");
            }
        }
        while (!signStack.isEmpty()) {
            int num1 = numStack.pop();
            int num2 = numStack.pop();
            char sign = (char) signStack.pop();
            int result = compute(num1, num2, sign);
            numStack.push(result);
        }
        System.out.println(express + "结果为:" + numStack.pop());
    }

    public int compute(int n1, int n2, char sign) {
        if (sign == '+') {
            return n2 + n1;
        } else if (sign == '-') {
            return n2 - n1;
        } else if (sign == '*') {
            return n2 * n1;
        } else if (sign == '/') {
            return n2 / n1;
        } else {
            return 0;
        }
    }

    public boolean isSign(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    //获取运算符优先级
    public int getSignLevel(char c) {
        int priority = 0;
        switch (c) {
            case '+':
                priority = 1;
                break;
            case '-':
                priority = 1;
                break;
            case '*':
                priority = 2;
                break;
            case '/':
                priority = 2;
                break;
            default:
                priority = 0; // 如果运算符不是加减乘除之一,默认为0
                break;
        }
        return priority;
    }


    static class ArrayStack {
        private int maxSize;//栈的大小
        private int[] stack;
        private int top = -1;//栈顶初始化为-1

        public ArrayStack(int maxSize) {
            this.maxSize = maxSize;
            this.stack = new int[maxSize];
        }

        //栈满
        public boolean isFull() {
            return top == maxSize - 1;
        }

        //栈空
        public boolean isEmpty() {
            return top == -1;
        }

        public void push(int e) {
            if (isFull()) {
                System.out.println("栈已满");
                return;
            }
            top++;
            stack[top] = e;
        }

        public int pop() {
            if (isEmpty()) {
                System.out.println("栈已空");
                return -1;
            }
            int val = stack[top];
            System.out.println("弹出:" + val);
            top--;
            return val;
        }

        /**
         * 获取栈顶
         */
        public int peek() {
            if (isEmpty()) {
                System.out.println("栈已空");
                return -1;
            }
            return stack[top];
        }

        //展示栈元素
        public void showList() {
            if (isEmpty()) {
                System.out.println("栈已空");
                return;
            }
            for (int i = top; i >= 0; i--) {
                System.out.printf("arr[%d]=%d ", i, stack[i]);
            }
        }
    }
}

p 37 38 逆波兰计算器实现

package com.atguigu.stack;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * 逆波兰表达式计算器
 */
public class PolandNotation {
    public static void main(String[] args) {
        List<String> list = getListString("3 4 + 5 * 6 -");
        calculate(list);
    }

    //将一个逆波兰表达式放入到LIST 例如(3+4)*5-6对应的后缀表达式就是3 4 + 5 * 6 -
    public static List<String> getListString(String suffixExpression) {
        String[] split = suffixExpression.split(" ");
        ArrayList<String> list = new ArrayList<>();
        for (String s : split) {
            list.add(s);
        }
        return list;
    }

//    3 4 + 5 * 6 -
    public static void calculate(List<String> list){
        Stack<String> stack = new Stack<>();
        for (String str : list) {
            if (str.matches("\\d+")){
                stack.push(str);
            }else {
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                int result = compute(num1, num2, str.charAt(0));
                stack.push(String.valueOf(result));
            }
        }
        System.out.println("最终结果:"+stack.peek());
    }

    public static int compute(int n1, int n2, char sign) {
        if (sign == '+') {
            return n2 + n1;
        } else if (sign == '-') {
            return n2 - n1;
        } else if (sign == '*') {
            return n2 * n1;
        } else if (sign == '/') {
            return n2 / n1;
        } else {
            return 0;
        }
    }
}

p39 -41 中缀表达式转化为后缀表达式

package com.atguigu.stack;

import java.util.Stack;

/**
 * 中缀表达式转化为后缀表达式
 */
public class PolandNotation2 {
    public static void main(String[] args) {
//        convert("(316+2)*6-200");
        convert("(300+4)*5-60");
    }

    public static void convert(String express) {
        Stack<String> signStack = new Stack<>();
        Stack<String> resultStack = new Stack<>();
        int index = express.length();
        String wholeStr = "";
        for (int i = 0; i < index; i++) {
            char c = express.charAt(i);
            if (Character.isDigit(c)) {//如果是数字,判断是否是多位数,把多位数拼接好
                wholeStr = String.valueOf(c - 48);
                //保证不是最后一位
                while (i < index - 1 && Character.isDigit(express.charAt(i + 1))) {
                    wholeStr += (express.charAt(++i) - 48);
                }
                resultStack.push(wholeStr);
            } else if (isSign(c)) { //如果是符号,
                while (!(signStack.isEmpty() ||   signStack.peek().charAt(0) == '(' || getSignLevel(c) > getSignLevel( signStack.peek().charAt(0)))) {
                    String sign = signStack.pop();
                    resultStack.push(sign);
                }
                signStack.push(String.valueOf(c));
            } else if (c == '(') {
                signStack.push(String.valueOf(c));
            } else if (c == ')') {
                char a;
                while ((a = signStack.pop().charAt(0)) != '(') {
                    resultStack.push(String.valueOf(a));
                }
            }else {
                System.out.println("符号错误");
            }
        }
        while (!signStack.isEmpty()){
            resultStack.push(signStack.pop());
        }
        System.out.println(resultStack);
    }

    public static boolean isSign(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    //获取运算符优先级
    public static int getSignLevel(char c) {
        int priority = 0;
        switch (c) {
            case '+':
                priority = 1;
                break;
            case '-':
                priority = 1;
                break;
            case '*':
                priority = 2;
                break;
            case '/':
                priority = 2;
                break;
            default:
                priority = 0; // 如果运算符不是加减乘除之一,默认为0
                break;
        }
        return priority;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值