JAVA数据结构与算法

JAVA数据结构与算法


一、 数据结构

1.1 稀疏数组

一:稀疏数组
      1.概念:对二维数组进行压缩,即对其二维数组的相同元素的值或0舍去
      2.思路:
            a.先对二维数组遍历得到非0元素的个数
            b.根据非0个数来创建稀疏数组
            c.再遍历二维数组将其非0元素压缩进稀疏数组
            d.将稀疏数组转为二维数组逆向操作
      3.结构:
            a.row col value
            b.第一行为二维数组的行数和列数;行数为非零个数+1
            c.其他行为对应元素在二维数组的位置
      4.应用:棋盘,地图

public class SparseArr {
	//数组的行数
	static final int ROW=11;
	//数组的列数
	static final int COL=11;
	//稀疏数组的列数
	static final int SPARSECOL=3;
	public static void main(String[] args) {
		//创建数组
		int[][] arr=new int[ROW][COL];
		//数组中1为红子,2为黑子
		arr[5][6]=1;
		arr[1][2]=2;
		arr[3][0]=1;
		//打印初始数组
		System.out.println("初始数组为:");
		printArr(arr);
		//遍历初始数组的到非0元素的个数
		int num=getNotZero(arr);
		System.out.println("非0元素个数为:"+num);
		//根据非零元素个数创建稀疏数组
		int[][] sparseArr=new int[num+1][SPARSECOL];
		//给稀疏数组的第一行赋值:行数,列数,非0个数
		sparseArr[0][0]=ROW;
		sparseArr[0][1]=COL;
		sparseArr[0][2]=num;
		//给稀疏数组其他行赋值
		int index=1;
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j < arr[i].length; j++) {
				if (arr[i][j]!=0) {
					sparseArr[index][0]=i;
					sparseArr[index][1]=j;
					sparseArr[index][2]=arr[i][j];
					index++;
				}
			}
		}
		//打印稀疏数组
		System.out.println("稀疏数组:");
		printArr(sparseArr);
		//将稀疏数组转为二维数组: 第一行构建,后面赋值
		int[][] realArr=new int[sparseArr[0][0]][sparseArr[0][1]];
		for (int i = 1; i < sparseArr.length; i++) {
			realArr[sparseArr[i][0]][sparseArr[i][1]]=sparseArr[i][2];
		}
		//打印转为二维的数组
		System.out.println("稀疏数组转为二维数组:");
		printArr(realArr);
	}
	//打印初始数组
	public static void printArr(int[][] arr) {
		for (int[] row : arr) {
			for (int col : row) {
				System.out.printf("%d \t",col);
			}
			System.out.println();
		}
	}
	//获取初始数组的非零个数
	public static int getNotZero(int[][] arr) {
		int num=0;
		for (int[] row : arr) {
			for (int col : row) {
				if (col!=0) {
					num++;
				}
			}
		}
		return num;
	}
}

1.2 队列

1.2.1 队列数组实现

一、数组实现队列
      1.队列特点:先进先出
      2.属性:队列大小,头,尾,存储数组
      3.方法:判空,判满,入队(判满),出队(判空),获取头部元素(判空),打印数据
      4.存储结构:数组
      5.缺陷:其存储空间数组只能用一次,为解决实现环形队列
      6.初始化头尾:front为始终指向第一个元素的前一个(位置不包含),rear为当前尾部元素(位置包含)

public class Queue {
	public static void main(String[] args) {
		// 测试
		QueueArr queueArr = new QueueArr(3);
		boolean loop = true;
		char in;
		Scanner input = new Scanner(System.in);
		while (loop) {
			System.out.println("s(show)打印数据");
			System.out.println("h(head)获取头数据");
			System.out.println("g(get)出队");
			System.out.println("a(add)入队");
			System.out.println("e(exit)退出");
			System.out.println("=========================");
			in=input.next().charAt(0);
			switch (in) {
			case 's': 
				queueArr.getQueue();
				break;
			case 'h': 
				try {
					System.out.println("头数据为:"+queueArr.getHeadElement());
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case 'g': 
				try {
					System.out.println("获取数据:"+queueArr.getElement());
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case 'a': 
				int element=input.nextInt();
				if (queueArr.addElement(element)) {
				}else {
					System.out.println("添加失败,队列已经满了~");
				}
				break;
			case 'e': 
				loop=false;
			default:
				break;
			}
		}
	}
}

class QueueArr {
	// 最大容量
	private int maxSize;
	// 头
	private int front;
	// 尾
	private int rear;
	// 数组存储
	private int[] arr;

	// 构造方法初始化:传最大容量
	public QueueArr(int maxSize) {
		this.maxSize = maxSize;
		// 构建数组
		this.arr = new int[maxSize];
		// 初始化头尾:front为始终指向第一个元素的前一个(位置不包含),rear为当前尾部元素(位置包含)
		this.front = this.rear = -1;
	}

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

	// 判断队列是否已满:容量-1
	public boolean isFull() {
		return this.rear == this.maxSize - 1;
	}

	// 出队:获取队列元素
	public int getElement() {
		// 先判断队列是否为空
		if (isEmpty()) {
			// 抛异常:不能返回了,返回值可能就为元素值
			throw new RuntimeException("队列为空~");
		}
		// 头部指针发生变化
		this.front++;
		return this.arr[front];
	}

	// 入队:添加元素
	public boolean addElement(int element) {
		// 先判断队列是否已经满了
		if (isFull()) {
			return false;
		}
		// 为指针发生变化
		this.arr[++rear] = element;
		return true;
	}

	// 获取头部元素:不弹出
	public int getHeadElement() {
		// 判断队列是否为空
		if (isEmpty()) {
			throw new RuntimeException("当前队列为空~");
		}
		return this.arr[front+1];
	}

	// 显示队列的数据
	public void getQueue() {
		System.out.print("数据为:");
		for (int i = this.front + 1; i <= this.rear; i++) {
			System.out.printf("%d\t", this.arr[i]);
		}
		System.out.println();
	}
}

1.2.2 环形队列数组实现

一、数组实现环形队列
      1.属性:maxSize(最大个数),front(头),rear(尾),arr(存储结构)
      2.注意:
            a.front始终指向头元素,rear始终指向尾元素后一个,(头包尾不包)初始                化front=rear=0
            b.整个数组始终会预留一个存储空间=>实际大小=maxSize-1
      3.方法:
            a.判空:front==rear;其数组尾部先动,头跟随尾部而动;当尾从未动或                头跟随动至尾重合即空
            b.判满:(rear+1)%maxSize‘==front:其rear是指向尾元素的后一个,其                当队满时rear和front始终会隔一个存储空间
            c.入队:判满 => arr[rear]=data => rear=(rear+1)%maxSize
            d.出队:判空 => arr[front].out => front=(front+1)%maxsize(跟随尾指针步                伐)
            e.取头:判空 => arr[front]
            f.打印:判空 => 获元素个数(front+maSize-rear)%maxSize;可分为rear大                于或小于front看待

public class CircleQueueByArr {
	public static void main(String[] args) {
		CircleQueue queue=new CircleQueue(4);
		boolean loop=true;
		Scanner input=new Scanner(System.in);
		int judge;
		int data;
		while(loop) {
			System.out.println("1:入队");
			System.out.println("2:出队");
			System.out.println("3:头元素");
			System.out.println("4:打印");
			System.out.println("5:退出");
			judge=input.nextInt();
			switch (judge) {
				case 1:System.out.print("->要添加的元素值:");
						data=input.nextInt();
						queue.addData(data);
						break;
				case 2:System.out.println("->头元素出队:"+queue.outData());
						break;
				case 3:System.out.println("->获取头元素:"+queue.getHeadData());
						break;
				case 4:System.out.println("->队列打印结果:");
						queue.printQueue();
						System.out.println();
						break;
				case 5:loop=false;
						System.out.println("测试完成");
						break;
				default :break;
			}
		}
	}
}

class CircleQueue {
	// 队列大小:但实际大小始终要小1,要预留一个存储空间
	private int maxSize;
	// 对头:始终指向头一个元素
	private int front;
	// 队尾:始终指向尾部元素后一个
	private int rear;
	// 存储结构
	private int[] arr;

	public CircleQueue(int maxSize) {
		this.maxSize = maxSize;
		this.arr = new int[maxSize];
	}

	// 判空
	public boolean isEmpty() {
		if (this.front == this.rear) {
			return true;
		}
		return false;
	}

	// 判满
	public boolean isFull() {
		if ((this.rear + 1) % this.maxSize == front) {
			return true;
		}
		return false;
	}

	// 入队
	public void addData(int data) {
		if (!isFull()) {
			this.arr[this.rear] = data;
			this.rear = (this.rear + 1) % this.maxSize;
			System.out.println("-->!入队成功!<--");
			return;
		}
		System.out.println("-->!入队失败!<--");
	}

	// 出队
	public int outData() {
		if (!isEmpty()) {
			int data = this.arr[this.front];
			this.front = (this.front + 1) % this.maxSize;
			return data;
		} else {
			throw new RuntimeException("-->!队列已空,无法取出数据!<--");
		}

	}

	// 获取头元素
	public int getHeadData() {
		return this.arr[this.front];
	}

	// 打印队列
	public void printQueue() {
		int index=front;
		//注意front在打印时要变化
		for (int i = 0; i < (this.rear+this.maxSize-this.front)%this.maxSize; i++) {
			System.out.printf("%d\t", this.arr[index]);
			index=(index+1)%this.maxSize;
			System.out.println("---"+i);
		}
	}
}

1.3 链表

1.3.1 单向链表实现

1.3.2 双向链表实现

1.3.3 单向环形链表解决约瑟夫问题

1.4 栈

1.4.1 栈的数组实现

1.4.2 栈实现综合计算器

1.4.3 栈实现逆波兰计算器

二、算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不羁的风zk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值