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