数据结构
数据结构 大体上分为了 线性结构和非线性结构
如果再细分,可以把非线性结构分为 图 和 树,多维数组(2维以上),再加上集合(一般不研究)
线性结构
1.数据元素之间存在一对一的关系
2.数据存储有两种方式,顺序存储(一维数组)和链式存储(链表),
其中顺序存储的叫做线性表,存储的元素物理上是连续的,链式存储的叫做链表,物理上不一定连续
3.常见的线性结构
数组,链表,栈,队列
数组
稀疏数组:当一个数组里面大部分的值都一样的时候,可以使用稀疏数组(列永远是3)
只记录不同值所在的行,列,以及值(存到一个更小的数组中),以及原数组的大小和不同值的个数
比如五子棋
左边是正常数组 右边是稀疏数组,右边的意思是
上边的红框存储原数组的大小和有不同的值的个数,下边的红框表示第0行第2列有一个值为1的数据 同理 第0行第3列有一个值为2的数据........
这样存储的容量小于左边的
二维转稀疏
获得当前不同值的个数(遍历)n
创建稀疏数组 int [n+1] [3]
保存数据,第一行一定是二维数组的行,列,n
稀疏转二维
先读取第一行,获得n行,m列值 创建二维数组 int [n] [m]
去读后边的数据
1 import java.io.*; 2 3 public class MainTest { 4 public static void main(String[] args) throws IOException { 5 //直接赋值 6 int[][] arr1={{0,0,0,0,0},{1,0,4,0,51},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}}; 7 //创建一个对象 8 /* int[][] arr2=new int[5][5]; 9 arr2[1][0]=1; 10 arr2[1][2]=4; 11 arr2[1][4]=51;*/ 12 //打印arr1 13 System.out.println("二维数组:"); 14 for(int[] row:arr1) { 15 for (int i : row) { 16 System.out.print(i); 17 System.out.print(" "); 18 } 19 System.out.println(); 20 } 21 //遍历arr1二维数组 22 int count=0; 23 for(int i=0;i<arr1.length;i++){ 24 for(int j=0;j<arr1[i].length;j++){ 25 if(arr1[i][j]!=0) 26 count++; 27 } 28 } 29 //创建稀疏数组 行为个数+1 30 int[][] arrmix=new int[count+1][3]; 31 arrmix[0][0]=5; 32 arrmix[0][1]=5; 33 arrmix[0][2]=count; 34 35 //把二维数组的值存入 36 //稀疏数组的行 第0行已经存过数据了,从第一行开始 37 int n=1; 38 for(int i=0;i<arr1.length;i++){ 39 for(int j=0;j<arr1[i].length;j++){ 40 if(arr1[i][j]!=0) { 41 arrmix[n][0] = i; 42 arrmix[n][1] = j; 43 arrmix[n][2] = arr1[i][j]; 44 n++; 45 } 46 } 47 } 48 //打印稀疏数组 49 System.out.println("稀疏数组:"); 50 /*System.out.println(arrmix[0][0]); 51 System.out.println(arrmix[0][1]); 52 System.out.println(arrmix[0][2]);*/ 53 for(int[] row:arrmix) { 54 for (int i : row) { 55 System.out.print(i); 56 System.out.print(" "); 57 } 58 System.out.println(); 59 } 60 61 //恢复为二维数组 62 int[][] arr2=new int[arrmix[0][0]][arrmix[0][1]]; 63 for(int i=1;i<count+1;i++){ 64 arr2[arrmix[i][0]][arrmix[i][1]]=arrmix[i][2]; 65 } 66 System.out.println("打印恢复后的"); 67 for(int[] row:arr2){ 68 for(int i:row){ 69 System.out.print(i); 70 System.out.print(" "); 71 } 72 System.out.println(); 73 } 74 75 //保存稀疏数组 76 File file =new File("E:"+File.separator+"Data.data"); 77 System.out.println("保存稀疏数组"); 78 OutputStream fos = new FileOutputStream(file); 79 for(int i=0;i<count+1;i++){ 80 for(int j=0;j<3;j++){ 81 fos.write(arrmix[i][j]); 82 } 83 } 84 fos.close(); 85 System.out.println("保存稀疏数组完成"); 86 //读取稀疏数组 87 System.out.println("读取稀疏数组"); 88 InputStream fis = new FileInputStream(file); 89 int [][] arrymixnew = new int[((int)file.length())/3][3]; 90 for(int i=0;i<((int)file.length())/3;i++){ 91 for(int j=0;j<3;j++){ 92 arrymixnew[i][j]=fis.read(); 93 } 94 } 95 for(int[] row:arrymixnew){ 96 for(int i:row){ 97 System.out.print(i); 98 System.out.print(" "); 99 } 100 System.out.println(); 101 } 102 System.out.println("读取稀疏数组完成"); 103 } 104 }
打印结果
队列: 有序,先进先出,先进队列的则先出去,比如排队买东西,又或者营业厅的叫号
数组可以实现队列
1 package SF; 2 3 public class ArrayQueue { 4 private int maxSize; 5 int a[]; 6 private int front; //指向队列头前一个位置 7 private int rear; //指向队列尾数据 8 9 public ArrayQueue(int maxSize){ 10 this.maxSize=maxSize; 11 a=new int[maxSize]; 12 front=-1; 13 rear=-1; 14 } 15 16 public boolean isFull(){ 17 return rear==maxSize-1; 18 } 19 20 public boolean isEmpty(){ 21 return rear==front; 22 } 23 public void addQueue(int n){ 24 if(isFull()){ 25 System.out.println("队列满"); 26 } 27 rear++; 28 a[rear]=n; 29 } 30 public int getQueue(){ 31 if(isEmpty()){ 32 throw new RuntimeException("队列为空"); 33 } 34 front++; 35 return a[front]; 36 } 37 public void showQueue(){ 38 if(isEmpty()){ 39 System.out.println("队列为空"); 40 } 41 for(int i=0;i<a.length;i++){ 42 System.out.println(a[i]); 43 } 44 } 45 public int peekQueue(){ 46 if(isEmpty()){ 47 throw new RuntimeException("队列为空"); 48 } 49 return a[front+1]; 50 } 51 }
循环队列:队列的重复利用(预留一个空数据位)
当然判断队列是否是满的条件也会发生变化,判断队列为空 rear==front
判断队列是否是满的 (rear+1)%maxSize==front
队列有效的数据个数 (rear+maxsize-front)%maxSize
数组实现循环列表
package SF; public class CircleArrayQueue { private int maxSize; int a[]; private int front; //指向队列头数据 private int rear; //指向队列尾数据的后一个位置 public CircleArrayQueue(int maxSize) { this.maxSize = maxSize; a = new int[maxSize]; //front和rear默认wei0 } public boolean isFull() { return (rear+1)%maxSize==front; } public boolean isEmpty() { return rear == front; } public void addQueue(int n) { if (isFull()) { System.out.println("队列满"); } a[rear] = n; rear=(rear+1)%maxSize; } public int getQueue() { if (isEmpty()) { throw new RuntimeException("队列为空"); } int i = front; front=(front+1)%maxSize; return a[i]; } public void showQueue() { if (isEmpty()) { System.out.println("队列为空"); } for (int i = front; i < getNum(); i++) { System.out.println(a[i%maxSize]); } } public int peekQueue() { if (isEmpty()) { throw new RuntimeException("队列为空"); } return a[front + 1]; } public int getNum(){ return (rear+maxSize-front)%maxSize; } }
链表
链表是以节点方式存储
每个节点包含数据域和next域
next域指向下一个节点(存储下一个节点的位置)
物理上不一定连续,其中还分为带头(头结点)链表和不带头(不带头链表)
不排序的带头链表
package SF; public class SingleLinkListDemo { public static void main(String[] args){ PersonNode personNode1 = new PersonNode(1,"zhangsan",1); PersonNode personNode2 = new PersonNode(2,"lisi",2); PersonNode personNode3 = new PersonNode(3,"wangwu",3); SingleLinkList sll = new SingleLinkList(); sll.addNode(personNode1); sll.addNode(personNode2); sll.addNode(personNode3); sll.list(); } } class SingleLinkList{ //先初始化一个头节点 private PersonNode pn = new PersonNode(0,"",0); //添加节点 public void addNode(PersonNode personNode){ PersonNode temp = pn; //遍历链表寻找最后一个节点 while(true){ //找到了 if(temp.nextPersonNode==null){ break; } //没找到 temp=temp.nextPersonNode; } //找到后推出循环,此时temp指向最后一个节点,并将传入的新节点赋给temp,此时的temp.nextPesonNode指向新节点 temp.nextPersonNode=personNode; } //显示节点 public void list(){ //判断是否为空链表 if(pn.nextPersonNode==null){ System.out.println("链表为空"); } //辅助节点 PersonNode temp = pn.nextPersonNode; //遍历 while(true){ if(temp == null){ break; } System.out.println(temp); temp=temp.nextPersonNode; } } } //定义节点 class PersonNode{ private int id; private String name; private int age; public PersonNode nextPersonNode; public PersonNode(int id,String name,int age){ this.id=id; this.name=name; this.age=age; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public PersonNode getNextPersonNode() { return nextPersonNode; } public void setNextPersonNode(PersonNode nextPersonNode) { this.nextPersonNode = nextPersonNode; } //方便显示 @Override public String toString() { return "PersonNode{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
排序的带头链表
public void addByOrder(PersonNode personNode){ PersonNode temp = pn; //确保不会重复添加 boolean flag=false; while(true) { //temp是最后一个节点 if (temp.nextPersonNode == null) { break; } if(temp.nextPersonNode.getId()>personNode.getId()){//找到位置temp后插入 break; }else if(temp.nextPersonNode.getId()==personNode.getId()){ //相同id已经存在 flag=true; break; }else { temp=temp.nextPersonNode; } } if(flag){ System.out.println("要插入数据已存在,不能重复插入"); }else{ //下边两句顺序不能搞反,不然找不到了 personNode.nextPersonNode = temp.nextPersonNode; temp.nextPersonNode = personNode; } }
删除节点
public void del(PersonNode personNode){ boolean flag=false; if(pn.nextPersonNode==null){ System.out.println("链表为空,不能删除"); } PersonNode temp = pn; while(true){ if(temp.nextPersonNode==null){ break; } if (temp.nextPersonNode.getId()==personNode.getId()){ flag=true; break; } temp=temp.nextPersonNode; } if(!flag){ System.out.println("没有找到要删除的节点"); }else{ temp.nextPersonNode=temp.nextPersonNode.nextPersonNode; } }
修改节点
public void update(PersonNode personNode){ if(pn.nextPersonNode==null){ System.out.println("链表为空"); } PersonNode temp = pn.nextPersonNode; //判断是否找到的标志 boolean flag = false; while(true){ //遍历完毕没找到 if(temp==null){ break; } if(temp.getId()==personNode.getId()){ flag = true; break; } temp=temp.nextPersonNode; } if(!flag){ System.out.println("未找到要修改的节点"); }else{ temp.setName(personNode.getName()); temp.setAge(personNode.getAge()); } }
------------------------------------------未完待续,继续补充---------------------------------------------------------------