一、线性表的底层代码实现
1.1、线性表的基本特性
- 有序性:线性表中的元素按特定顺序排列,可以通过索引(对于数组)或指针(对于链表)访问。
- 可重复性:线性表中的元素可以重复,允许不同元素具有相同的值。
- 动态性:线性表的长度可以变化,特别是使用链表实现时,可以根据需要动态增加或减少元素。
1.2、线性表的基本操作
线性表的基本操作通常包括:
- 插入:在指定位置插入一个新元素。
- 删除:删除指定位置的元素。
- 查找:根据元素值或索引查找元素。
- 遍历:访问线性表中的每个元素。
1.3、线性表的表示方法
线性表可以通过以下两种主要方式表示:
顺序表(Array List):
- 通过数组实现,元素在内存中连续存储。
- 优点:支持快速随机访问,查找时间复杂度为 O(1)。
- 缺点:插入和删除操作需要移动元素,时间复杂度为 O(n)。
链表(Linked List):
- 通过节点实现,每个节点包含数据和指向下一个节点的指针。
- 优点:插入和删除操作效率高,时间复杂度为 O(1)。
- 缺点:不支持快速随机访问,查找时间复杂度为 O(n)。
I、ArrayList(数组)
ArrayList的基本结构:
ArrayList
主要依赖于动态数组实现。它的基本结构包括一个用于存储数据的数组和一个代表已存储数据个数的size
属性。ArrayList
的特点是数据的物理存储是连续的。
特点:数据连续存储
优点:数据连续存储,可以根据一个地址推测出其他任意元素位置的地址
缺点:为保持数据的连续性,在插入和删除数据的时候,会伴随着大量的数据元素的移动
代码基础功能实现:
import java.util.Arrays;
/**
* @program: Pay.java
* @ClassName ArrayList
* @description:
* @author: 苏芮溪
* @create: 2024−11-02 09:21
* @Version 1.0
**/
public class ArrayList {
Object []data;
int size;
//无参构造一个大小为10的List
public ArrayList() {
data = new Object[10];
}
//指定构造list的大小
public ArrayList(int size) {
data = new Object[size];
}
//移动元素,flag == false 左移,否则右移
private void moveArrayList(int index,boolean flag){
if(!flag){
for (int i = index; i < size-1; i++){//是否越界呢?
data[i] = data[i+1];
}
//数据个数减少
size--;
}else { //右移,空出插入的位置
//检查是否需要扩容
if (size == data.length) {
grow(MIN_SIZE); //需不需要先判断一下?
}
//进行右移
for (int i = size; i > index; i--){
data[i] = data[i-1];
}
size++;
}
}
//根据元素删除对应元素并返回元素所在的索引
public int deleteIndexofData(Object data){
for (int i = 0; i < size; i++){
if (this.data[i].equals(data)){
deleteOfIndex(i);
return i;
}
}
//未找到
return -1;
}
//获取元素的索引
public int getIndexofData(Object data){
for (int i = 0; i < size; i++){
if (this.data[i].equals(data)){
return i;
}
}
//未找到
return -1;
}
//根据索引删除元素
public Object deleteOfIndex(int index){
if (index >=size && index < 0){
return null;
}
else {
Object temp = data[index];
moveArrayList(index,false);
return temp;
}
}
//根据索引获取元素
public Object getOfIndex(int index) {
if (index >=size && index < 0){
return null;
}else {
return data[index];
}
}
//数组扩容
private boolean grow(int minLength){
//1.5倍扩容
int newLength = data.length + (data.length>>1);//记得带括号
//确保最小的扩容长度
newLength = Math.max(newLength, minLength);
try{
//copy数组,copyof自带数组越界处理能力
data = Arrays.copyOf(data, newLength);
}catch(Exception e){
System.out.println("扩容失败,内存空间不足");
return false;
}
//扩容成功
return true;
}
//在尾部添加元素
public boolean add(Object o) {
//检查是否需要扩容
if (size == data.length) {
grow(MIN_SIZE);
}
data[size++] = o;
return true;
}
//打印ArrayList
public void printArrayList(){
if (size == 0){
System.out.println("{}");
}else {
System.out.print("{");
for (int i = 0; i < size; i++){
System.out.print(data[i]+",");
}
System.out.println("}");
}
}
//最小扩容长度
private static final int MIN_SIZE = 10;
}
II、LinkedList(链表)
LinkedList的基本结构:
LinkedList
是通过节点来实现的,每个节点包含数据和指向下一个节点的引用。链表的优点在于插入和删除操作时不需要移动其他元素。
特点:数据存储不连续
优点:数据的插入和删除速度快,无需移动大量元素
缺点:数据的查找无法直接查找,需要一个节点一个节点遍历
代码基本功能实现:
/**
* @program: Pay.java
* @ClassName LinkedList
* @description:
* @author: 苏芮溪
* @create: 2024−11-02 10:13
* @Version 1.0
**/
class Node{
Object data;
Node next;
public Node(){
data = null;
next = null;
}
}
public class LinkedList {
private Node head;//头指针
private Node tail;//尾指针
private int size;//链表大小
//无参构造
public LinkedList(){
head = new Node();
tail = head;
size = 0;
}
//删除元素
public Node delete(Object data) {
Node temp = head;
Node prev = head.next;
//遍历查询
while(prev!=null){
if(prev.data.equals(data)){
temp.next = prev.next;
size--;
break;
}
prev = prev.next;
temp = temp.next;
}
return prev;
}
//获取长度
public int getSize()
{
return size;
}
//空出头节点,头插法
public void insertHead(Object data){
Node newNode = new Node();
newNode.data = data;
newNode.next = head.next;
head.next = newNode;
size++;
//第一次插入时,更新尾节点
if(head == tail){
tail = newNode;
}
}
//空出头节点,尾插法
public void insertTail(Object data){
Node newNode = new Node();
newNode.data = data;
//插入节点
tail.next = newNode;
size++;
//更新尾巴节点
tail = newNode;
}
//打印链表
public void display(){
Node temp = head.next;
System.out.print("Head->");
while(temp != null){
System.out.print(temp.data+"->");
temp = temp.next;
}
System.out.println("null");
}
}
二、树的实现
树是一种非线性数据结构,由节点(Node)组成,并且每个节点包含一个值和指向其子节点的指针。树结构广泛应用于计算机科学中,例如在数据库和文件系统中。以下是二叉树(Binary Tree)和二叉搜索树(Binary Search Tree, BST)以及平衡二叉树(Balanced Binary Tree)的基本实现。
2.1、二叉树
2.1.1、二叉树的定义
二叉树(Binary Tree)是一种数据结构,它由节点(Node)组成,每个节点最多有两个子节点,通常称为左子节点(Left Child)和右子节点(Right Child)。二叉树的每个节点都包含一个值(或数据)以及指向其子节点的指针。
2.1.2、二叉树的基本属性
节点:树的基本单位,包含数据和指向子节点的指针。
根节点:树的最上层节点,没有父节点。
叶节点:没有子节点的节点。
高度:树的高度是从根节点到叶节点的最长路径上的节点数。
深度:某个节点到根节点的路径长度。
子树:任何节点及其后代构成的树被称为这个节点的子树。
2.1.3、二叉树的类型
满二叉树(Full Binary Tree):每个节点要么是叶节点,要么有两个子节点。
完全二叉树(Complete Binary Tree):除了最后一层外,其他层的节点都被填满,最后一层的节点从左到右填充。
二叉搜索树(Binary Search Tree, BST):对于每个节点,左子树中的所有节点值小于该节点值,右子树中的所有节点值大于该节点值。
平衡二叉树(Balanced Binary Tree):任何节点的左右子树高度差不超过1,保证了树的平衡性,从而使得查找、插入和删除操作的时间复杂度为 O(log n)。
2.2、二叉搜索树(BST树)
转跳链接:二叉搜索树(BST树)-优快云博客
2.3、平衡二叉树(BVL树)
转跳链接: 平衡二叉树-优快云博客
三、JAVA的特殊数据排序
Java中最常见的比较就是比较运算符,例如:“==”,“>”,“>=”,“!=”等等,但是这些基本都是只能用来比较Java中提供的基本数据类型的数据,对于像是我们自己写的类等无法进行我们想要的比较,只能比较其存储的数据的内存地址,这时候就需要我们去实现Java中的比较了。