目录
双向链表:每个节点有记录上一个节点的信息和记录上一个节点的信息。
栈:(Stack)又称为堆栈或堆叠,是限制在表的一端进行插入和删除运算的线性表。
数据结构是程序设计优化的方法论研究数据的逻辑结构和物理结构以及它们之间的相互关系,并对这种结构定义相应的运算,目的是加快程序的执行速度、减少内存占用的空间。
①集合结构:数据结构之间的元素只有“同属于同一个集合”的关系。
②线性结构:数据结构中的元素存在一对一的相互关系。(体现:一维数组,链表,栈,队列)
③树形结构:数据结构中的元素存在一对多的相互关系。
④图形结构:数据结构中的元素之间存在多对多的相互关系。
①顺序结构:使用一组连续的存储单元依次存储逻辑上相邻的各个元素。
优点:只需要申请存放数据本身的内存空间即可,支持下标访问,也可以实现随机访问。
缺点:必须静态分配连续空间,内存的利用率较低。插入或删除可能要移动大量元素,效率低。
②链式结构:不使用连续的空间存放结构的元素,而是为每一个元素构造一个节点。节点中除了存放数据本身之外,还需要存放指向下一个节点的指针。
优点:不采用连续的存储空间从而内存空间利用率更高,克服顺序存储结构中预知元素个数的缺点。插入或删除元素时不需要移动大量元素。
缺点:需要额外的空间来表达数据之间的逻辑关系,不支持下标访问和随机访问。
③索引结构:除了建立存储节点信息之外,还建立附加的索引表来记录每个元素节点的地址。索引表由若干索引项组成。索引项的一般形式是:(关键字,地址)
优点:用节点的索引号来来确定节点存储地址,检索速度快。
缺点:增加了附加的索引表,会占用较多的存储空间。在增加和删除数据时要修改索引表,会花费较多的时间。
④散列结构:根据元素的关键字直接计算出该元素的存储地址,又称Hash存储。
优点:检索、增加和删除节点的操作都很快。
缺点:不支持排序,一般比线性表存储需要更多的空间,并且记录的关键字不能重复。
施加在数据上的运算包括运算的定义和实现。运算的定义是针对逻辑结构的,指出运算的功能。运算的实现是针对存储结构的,指出运算的具体操作步骤。
·分配资源,建立结构,释放资源
·插入和删除
·获取和遍历
·修改和排序
模拟单向链表的代码如下:
- package 数据结构.链表.单向链表;
-
-
- public class Test
- {
- public static void main(String[] args)
- {
- Node n1 = new Node("aaa");
- Node n2 = new Node("bbb");
- Node n3 = new Node("ccc");
- n1.next = n2;//记录下一个元素
- n2.next = n3;//记录下一个元素
- //尾节点没有下一个元素,next赋值为null
- }
- }
- class Node
- {
- Object Data;//用于记录本节点的数据
- Node next;//用于记录下一个元素
-
-
- public Node()
- {
- }
-
-
- public Node(Object data)
- {
- Data = data;
- }
- }
模拟双向链表的代码如下:
- package 数据结构.链表.双向链表;
-
-
- public class Test
- {
- public static void main(String[] args)
- {
- Node n1 = new Node("aaa");
- Node n2 = new Node("bbb");
- Node n3 = new Node("ccc");
- Node n4 = new Node("ddd");
- Node n5 = new Node("eee");
- n1.next = n2;//记录下一个元素
- //头节点没有上一个元素,prev赋值为null
-
-
- n2.next = n3;//记录下一个元素
- n2.prev = n1;//记录上一个元素
-
-
- n3.next = n4;//记录下一个元素
- n3.prev = n2;//记录上一个元素
-
-
- n4.next = n5;//记录下一个元素
- n4.prev = n3;//记录上一个元素
-
-
- n5.prev = n4;//记录上一个元素
- //尾节点没有下一个元素,next赋值为null
- }
- }
- class Node
- {
- Object Data;//用于记录本节点的数据
- Node prev;//用于记录上一个元素
- Node next;//用于记录下一个元素
-
-
- public Node()
- {
- }
-
-
- public Node(Object data)
- {
- Data = data;
- }
- }
模拟二叉树的代码如下:
- package 数据结构.二叉树;
-
-
- public class Test
- {
- public static void main(String[] args)
- {
- TreeNode t1 = new TreeNode("aaa");
- TreeNode t2 = new TreeNode("bbb");
- TreeNode t3 = new TreeNode("ccc");
- TreeNode t4 = new TreeNode("ddd");
- TreeNode t5 = new TreeNode("eee");
- TreeNode t6 = new TreeNode("fff");
- TreeNode t7 = new TreeNode("ggg");
- t1.left = t2;//左分支
- t1.right = t3;//右分支
-
-
- t2.parent = t1;//父节点
- t2.left = t4;//左分支
- t2.right = t5;//右分支
-
-
- t3.parent = t1;//父节点
- t3.left = t6;//左分支
- t3.right = t7;//右分支
-
-
- t4.parent = t2;//父节点
- t5.parent = t2;//父节点
-
-
- t6.parent = t3;//父节点
- t7.parent = t7;//父节点
- }
- }
- class TreeNode
- {
- Object Data;//本节点信息
- TreeNode left;//左分支
- TreeNode right;//右分支
- TreeNode parent;//父节点
-
-
- public TreeNode()
- {
- }
-
-
- public TreeNode(Object data)
- {
- Data = data;
- }
- }
结构图如图:

最先进入的数据被压入栈底,最后的数据在栈顶。每次删除(退栈),删除的总是当前栈中最后进入(进栈)的元素,而最先插入的数据在栈底,最后退栈。(后进先出,先进后出)
·属于抽象数据类型。
·可以使用数组或链表来构建
栈的模拟代码如下:
- package 数据结构.栈;
-
-
- import java.util.Arrays;
-
-
- public class Test
- {
- public static void main(String[] args)
- {
- Stack ss = new Stack(5);
- ss.push("abc");
- ss.push("def");
- ss.push("ghi");
- System.out.println(Arrays.toString(ss.values));
- ss.pop();
- System.out.println(Arrays.toString(ss.values));
- }
- }
- class Stack{
- Object[] values;//栈中的元素
- int size;//用来记录存储元素的个数
-
-
- public Stack(int length)
- {
- values = new Object[length];
- }
- //入栈
- public void push(Object ele)
- {
- if(size >= values.length)
- {
- throw new RuntimeException("栈空间已满");
- }
- values[size] = ele;
- size++;
- }
- //出栈
- public Object pop()
- {
- if(size <= 0)
- {
- throw new RuntimeException("栈空间已空");
- }
- Object o = values[size - 1];
- values[size - 1] = null;
- size--;
- return o;
- }
- }
·属于抽象数据类型
·元素的添加获取满足“先进先出”。
队列的模拟代码如下:
- package 数据结构.队列;
-
-
- public class Test
- {
-
- }
- class Queue
- {
- Object[] values;
- int size;//记录村存储的数据的个数
- public Queue(int length)
- {
- values = new Object[length];
- }
- public void add(Object ele)//添加
- {
- if(size >= values.length)
- {
- throw new RuntimeException("队列已满");
- }
- values[size] = ele;
- size++;
- }
- public Object get()//获取
- {
- if(size <= 0)
- {
- throw new RuntimeException("队列已空");
- }
- Object o = values[0];
- //数据前移
- for (int i = 0; i < size - 1; i++)
- {
- values[i] = values[i + 1];
- }
- //最后一个元素置空
- values[size - 1] = null;
- return o;
- }
- }