数据结构
- 数据结构分为线性结构和非线性结构
- 线性结构
- 线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系
- 线性结构有两种不同的存储方式,即顺序存储结构和链式存储结构。顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的。
- 链式存储的线性表称为链表,链表中的存储元素不一定是连续的,元素节点中存放数据元素以及相邻元素的地址信息。
- 线性结构常见的有:数组,队列,链表和栈
- 非线性结构
非线性结构包括:二维数组,多维数组,广义表,树结构,图结构。
线性结构
数组
- 稀疏数组(五子棋问题中,有存盘和续上盘功能)
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
1.记录数组一共有几行几列,有多少个不同的值
2. 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
[0] 6 7表示原数组六行七列 共有8个非0值
[1] 表示第一个非0值为0行3列 值为22
依次往后
- 应用实例
- 使用稀疏数组,保留二维数组(棋盘,地图等)
- 恢复二维数组
二维数组转稀疏数组的思路
- 遍历原始二维数组,得到有效数据的个数sum
- 根据sum就可以创建稀疏数组sparseArr
- 将二维数组的有效数据存入到稀疏数组
稀疏数组转二维数组的思路
- 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组
- 在读取的稀疏数组的后几行的数据,并赋给原始的二维数组即可
public class sparseArry {
public static void main(String[] args) {
// TODO Auto-generated method stub
//用chessArray1表示原始二维数组
int chessArray1[][]=new int [11][11];
chessArray1[1][2]=3;
chessArray1[2][3]=4;
System.out.println("原始二维数组");
for(int row[] :chessArray1) {
for(int data:row) {
System.out.printf("%d\t",data);
}
System.out.println();
}
int sum = 0;
for(int i = 0;i<11;i++) {
for(int j = 0;j<11;j++) {
if(chessArray1[i][j]!=0) {
sum++;
}
}
}
System.out.println("有"+sum+"个非0数值");
//创建稀疏数组sparseArray
int count = 0;
int sparseArray [][] = new int [sum+1][3];
sparseArray[0][0]=11;
sparseArray[0][1]=11;
sparseArray[0][2]=sum;
for(int i = 0;i<11;i++) {
for(int j = 0;j<11;j++) {
if(chessArray1[i][j]!=0) {
count++;
sparseArray[count][0] = i;
sparseArray[count][1]=j;
sparseArray[count][2]=chessArray1[i][j];
}
}
}
System.out.println("稀疏数组为:");
for(int i=0;i<sparseArray.length;i++) {
System.out.printf("%d\t%d\t%d\t\n",sparseArray[i][0],sparseArray[i][1],sparseArray[i][2]);
}
}
}
队列
- 队列
- 队列是一个有序列表,可以用数组或是链表实现。
- 遵循先进先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
- 队尾(rear),队头(front)。加数据从队尾加,取数据从从队头取
数组模拟队列
先创建rear(队尾)和front(队头)两个变量
1)当将数据存入队列时 尾指针 rear往后移 rear+1 当 front == rear 时 队列为空。
2)当尾指针 rear 小于 队列最大下标 maxsize-1 .则将数据存入rear 所指的数组元素中,否则 无法存入数据。 rear == maxsize-1 此时队列满。
用数组模拟队列
public class Arrayqueue {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayQueue1 queue = new ArrayQueue1(3);
char key = ' ';//用来接受用户要求
Scanner sc = new Scanner(System.in);
boolean loop = true;
while(loop) {
System.out.println("a:添加数据");
System.out.println("g:获取数据");
System.out.println("s:输出队列数据");
System.out.println("h:显示队列头数据");
System.out.println("e:退出程序");
System.out.println("请输入功能需求");
key = sc.next().charAt(0);
switch(key) {
case 'a':
System.out.println("请输入一个数");
int s = sc.nextInt();
queue.addData(s);
break;
case 'g':
try {
System.out.println("取到的数据为:"+queue.getData());
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 's':
queue.showQueue();
break;
case 'h':
try {
System.out.println("队列头数据为:"+queue.headData());
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'e':
loop = false;
sc.close();
break;
default:
break;
}
}
}
}
class ArrayQueue1{
//创建数组模拟队列
private int front;//表示队头;
private int rear;//表示队尾;
private int maxsize; //表示队列的最大长度
private int [] arr ;
public ArrayQueue1(int arrmaxsize) {
maxsize = arrmaxsize;
arr = new int [maxsize];
front = -1;//表示队头指向第一个数据的前一个位置
rear = -1;//表示队尾指向的位置
}
public boolean isFull() {
//判断队列是否满
return front == maxsize -1 ;
}
public boolean isEmpty() {
//判断队列是否为空
return front == rear;
}
public void addData(int n){
//向队列中添加数据
if(isFull()) {
System.out.println("队列已满不能添加数据");
}
rear++;
arr[rear] = n;
}
public int getData() {
//获取队列中的数据
if(isEmpty()) {
throw new RuntimeException( "队列为空,不能取数据");
}
front++;
return arr[front];
}
public void showQueue () {
//输出队列中的数据
if(isEmpty()) {
throw new RuntimeException("队列为空,无数据");
}
for(int i = 0;i<arr.length;i++) {
System.out.printf("arr[%d]=%d\t",i,arr[i]);
}
}
public int headData() {
//展现队列中的头数据
if(isEmpty()) {
throw new RuntimeException("队列为空,无数据")