数据结构与算法 Java 企业级实现方案 面试突击 Java面试

数据结构与算法 Java 企业级实现方案 面试突击 Java面试

一、项目整体架构

采用面向接口编程 + 分层设计 + 泛型复用的企业级标准架构,严格遵循 Java 编码规范,实现原 C++ 代码的全部功能并修复原生缺陷,同时保留可扩展能力。

项目包结构

com.datastructure
├── sort          # 排序算法工具集
├── linear        # 线性表(接口 + 顺序/链表双实现)
├── stack         # 栈(接口 + 顺序/链式双实现)
├── queue         # 队列(接口 + 顺序/链式双实现)
├── model         # 业务实体(图书类)
└── manager       # 图书管理系统(顺序表/链表双版本)
test              # 功能测试入口

二、排序算法模块

SortUtils.java(排序工具类)

完整复现冒泡、插入、快速排序逻辑,保留每趟排序过程打印,修复原代码边界问题。

package com.datastructure.sort;

/**
 * 经典排序算法工具类
 * 支持冒泡、插入、快速排序,附带排序过程可视化输出
 */
public class SortUtils {

    /**
     * 冒泡排序
     * @param array 待排序数组
     */
    public static void bubbleSort(int[] array) {
        if (array == null || array.length <= 1) {
            return;
        }
        int length = array.length;
        for (int i = 0; i < length - 1; i++) {
            for (int j = 0; j < length - i - 1; j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
            System.out.print("第" + (i + 1) + "趟: ");
            printArray(array);
        }
    }

    /**
     * 插入排序
     * @param array 待排序数组
     */
    public static void insertionSort(int[] array) {
        if (array == null || array.length <= 1) {
            return;
        }
        System.out.println("==================插入排序=======================");
        int length = array.length;
        for (int i = 1; i < length; i++) {
            for (int j = i - 1; j >= 0; j--) {
                if (array[j + 1] < array[j]) {
                    int key = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = key;
                }
            }
            System.out.print("第" + i + "趟: ");
            printArray(array);
        }
    }

    /**
     * 快速排序入口
     * @param array 待排序数组
     */
    public static void quickSort(int[] array) {
        if (array == null || array.length <= 1) {
            return;
        }
        quickSortRecursion(array, 0, array.length - 1);
    }

    private static void quickSortRecursion(int[] array, int low, int high) {
        if (low >= high) {
            return;
        }
        int pivot = partition(array, low, high);
        quickSortRecursion(array, low, pivot - 1);
        quickSortRecursion(array, pivot + 1, high);
    }

    /**
     * 分区函数:以首元素为基准,双指针交换分区
     */
    private static int partition(int[] array, int low, int high) {
        int key = array[low];
        while (low < high) {
            while (array[high] >= key && low < high) {
                high--;
            }
            if (low < high) {
                swap(array, low, high);
            }
            while (array[low] <= key && low < high) {
                low++;
            }
            if (low < high) {
                swap(array, low, high);
            }
        }
        printArray(array);
        return low;
    }

    private static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    private static void printArray(int[] array) {
        for (int num : array) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}

三、线性表模块

1. 线性表通用接口 List.java

package com.datastructure.linear;

/**
 * 线性表通用接口,定义增删改查标准行为
 * @param <E> 元素类型
 */
public interface List<E> {
    /**
     * 指定下标插入元素
     * @param index 插入位置(从0开始)
     * @param element 插入元素
     * @return 插入是否成功
     */
    boolean add(int index, E element);

    /**
     * 删除指定下标元素
     * @param index 删除位置
     * @return 删除是否成功
     */
    boolean remove(int index);

    /**
     * 修改指定下标元素
     * @param index 修改位置
     * @param element 新元素
     * @return 修改是否成功
     */
    boolean set(int index, E element);

    /**
     * 查找元素第一次出现的下标
     * @param element 目标元素
     * @return 下标,未找到返回-1
     */
    int indexOf(E element);

    /**
     * 获取当前元素个数
     */
    int size();

    /**
     * 遍历打印所有元素
     */
    void show();

    /**
     * 判断是否为空
     */
    boolean isEmpty();
}

2. 顺序表实现 SequenceList.java

修复原 C++ 数组越界问题,增加自动扩容机制,符合企业级健壮性要求。

package com.datastructure.linear;

/**
 * 顺序表(动态数组实现)
 * @param <E> 元素类型
 */
public class SequenceList<E> implements List<E> {
    private static final int DEFAULT_CAPACITY = 20;
    private Object[] elementData;
    private int size;
    private int capacity;

    public SequenceList() {
        this(DEFAULT_CAPACITY);
    }

    public SequenceList(int initCapacity) {
        if (initCapacity <= 0) {
            throw new IllegalArgumentException("初始容量必须大于0");
        }
        this.capacity = initCapacity;
        this.elementData = new Object[initCapacity];
        this.size = 0;
    }

    @Override
    public boolean add(int index, E element) {
        if (index > size || index < 0) {
            System.out.println("插入位置不正确");
            return false;
        }
        // 自动扩容
        if (size == capacity) {
            grow();
        }
        // 元素后移
        for (int i = size - 1; i >= index; i--) {
            elementData[i + 1] = elementData[i];
        }
        elementData[index] = element;
        size++;
        return true;
    }

    @Override
    public boolean remove(int index) {
        if (isEmpty()) {
            System.out.println("顺序表为空");
            return false;
        }
        if (index >= size || index < 0) {
            System.out.println("删除位置不正确");
            return false;
        }
        // 元素前移
        for (int i = index; i < size - 1; i++) {
            elementData[i] = elementData[i + 1];
        }
        elementData[size - 1] = null; // 帮助GC
        size--;
        return true;
    }

    @Override
    public boolean set(int index, E element) {
        if (isEmpty()) {
            System.out.println("顺序表为空");
            return false;
        }
        if (index >= size || index < 0) {
            System.out.println("修改位置不正确");
            return false;
        }
        elementData[index] = element;
        return true;
    }

    @Override
    public int indexOf(E element) {
        if (isEmpty()) {
            System.out.println("顺序表为空");
            return -1;
        }
        for (int i = 0; i < size; i++) {
            if (elementData[i].equals(element)) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public void show() {
        if (isEmpty()) {
            System.out.println("顺序表为空");
            return;
        }
        for (int i = 0; i < size; i++) {
            System.out.print(elementData[i] + " ");
        }
        System.out.println();
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * 扩容:1.5倍容量
     */
    private void grow() {
        int newCapacity = capacity + (capacity >> 1);
        Object[] newArray = new Object[newCapacity];
        System.arraycopy(elementData, 0, newArray, 0, size);
        elementData = newArray;
        capacity = newCapacity;
    }

    @SuppressWarnings("unchecked")
    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("下标越界");
        }
        return (E) elementData[index];
    }
}

3. 单链表实现 LinkedList.java

修复原 C++ 修改方法返回值错误,采用内部节点类封装,地址调试打印可选。

package com.datastructure.linear;

/**
 * 单链表实现
 * @param <E> 元素类型
 */
public class LinkedList<E> implements List<E> {
    /**
     * 链表节点内部类
     */
    private static class Node<E> {
        E data;
        Node<E> next;

        Node(E data) {
            this.data = data;
            this.next = null;
        }
    }

    private Node<E> head;
    private int size;

    public LinkedList() {
        this.head = null;
        this.size = 0;
    }

    @Override
    public boolean add(int index, E element) {
        if (index > size || index < 0) {
            System.out.println("插入位置不正确");
            return false;
        }
        Node<E> newNode = new Node<>(element);
        // 空链表或头插
        if (head == null || index == 0) {
            newNode.next = head;
            head = newNode;
            size++;
            return true;
        }
        // 找到前驱节点
        Node<E> prev = head;
        for (int i = 0; i < index - 1; i++) {
            prev = prev.next;
        }
        newNode.next = prev.next;
        prev.next = newNode;
        size++;
        return true;
    }

    @Override
    public boolean remove(int index) {
        if (isEmpty()) {
            System.out.println("链表为空");
            return false;
        }
        if (index >= size || index < 0) {
            System.out.println("删除位置不正确");
            return false;
        }
        // 头删
        if (index == 0) {
            Node<E> temp = head;
            head = head.next;
            temp.next = null; // 帮助GC
            size--;
            return true;
        }
        // 找到前驱节点
        Node<E> prev = head;
        for (int i = 0; i < index - 1; i++) {
            prev = prev.next;
        }
        Node<E> target = prev.next;
        prev.next = target.next;
        target.next = null;
        size--;
        return true;
    }

    @Override
    public boolean set(int index, E element) {
        if (isEmpty()) {
            System.out.println("链表为空");
            return false;
        }
        if (index >= size || index < 0) {
            System.out.println("修改位置不正确");
            return false;
        }
        Node<E> current = head;
        for (int i = 0; i < index; i++) {
            current = current.next;
        }
        current.data = element;
        return true; // 修复原C++代码返回false的bug
    }

    @Override
    public int indexOf(E element) {
        if (isEmpty()) {
            System.out.println("链表为空");
            return -1;
        }
        Node<E> current = head;
        for (int i = 0; i < size; i++) {
            if (current.data.equals(element)) {
                return i;
            }
            current = current.next;
        }
        return -1;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public void show() {
        if (isEmpty()) {
            System.out.println("链表为空");
            return;
        }
        Node<E> current = head;
        for (int i = 0; i < size; i++) {
            // 调试模式:打印下标+地址+数据+后继地址
            // System.out.print(i + "(" + current + "):" + current.data + "," + current.next + "\t\t");
            System.out.print(current.data + " ");
            current = current.next;
        }
        System.out.println();
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    public E get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException("下标越界");
        }
        Node<E> current = head;
        for (int i = 0; i < index; i++) {
            current = current.next;
        }
        return current.data;
    }
}

四、栈模块

1. 栈通用接口 Stack.java

package com.datastructure.stack;

/**
 * 栈通用接口(后进先出)
 * @param <E> 元素类型
 */
public interface Stack<E> {
    boolean push(E element);
    E pop();
    E peek();
    boolean isEmpty();
    void show();
}

2. 顺序栈实现 ArrayStack.java

package com.datastructure.stack;

import com.datastructure.linear.SequenceList;

/**
 * 顺序栈(基于动态数组实现)
 * @param <E> 元素类型
 */
public class ArrayStack<E> implements Stack<E> {
    private final SequenceList<E> list;

    public ArrayStack() {
        this.list = new SequenceList<>();
    }

    public ArrayStack(int capacity) {
        this.list = new SequenceList<>(capacity);
    }

    @Override
    public boolean push(E element) {
        return list.add(list.size(), element);
    }

    @Override
    public E pop() {
        if (isEmpty()) {
            System.out.println("栈为空");
            return null;
        }
        E top = list.get(list.size() - 1);
        list.remove(list.size() - 1);
        System.out.println(top + "出栈");
        return top;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        return list.get(list.size() - 1);
    }

    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }

    @Override
    public void show() {
        if (isEmpty()) {
            System.out.println("栈为空");
            return;
        }
        list.show();
    }
}

3. 链栈实现 LinkedStack.java

package com.datastructure.stack;

/**
 * 链栈(基于头插法单链表实现,栈顶在头部)
 * @param <E> 元素类型
 */
public class LinkedStack<E> implements Stack<E> {
    private static class Node<E> {
        E data;
        Node<E> next;
        Node(E data) {
            this.data = data;
        }
    }

    private Node<E> top;
    private int size;

    public LinkedStack() {
        this.top = null;
        this.size = 0;
    }

    @Override
    public boolean push(E element) {
        Node<E> newNode = new Node<>(element);
        newNode.next = top;
        top = newNode;
        size++;
        return true;
    }

    @Override
    public E pop() {
        if (isEmpty()) {
            System.out.println("栈为空");
            return null;
        }
        E value = top.data;
        Node<E> temp = top;
        top = top.next;
        temp.next = null;
        size--;
        System.out.println(value + "出栈");
        return value;
    }

    @Override
    public E peek() {
        return isEmpty() ? null : top.data;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public void show() {
        if (isEmpty()) {
            System.out.println("栈为空");
            return;
        }
        Node<E> current = top;
        while (current != null) {
            System.out.print(current.data + "\t");
            current = current.next;
        }
        System.out.println();
    }
}

五、队列模块

1. 队列通用接口 Queue.java

package com.datastructure.queue;

/**
 * 队列通用接口(先进先出)
 * @param <E> 元素类型
 */
public interface Queue<E> {
    boolean enqueue(E element);
    E dequeue();
    E peek();
    boolean isEmpty();
    void show();
}

2. 顺序队列实现 ArrayQueue.java

保留原代码“出队整体前移”逻辑,修复原 C++ 数组越界 bug。

package com.datastructure.queue;

import com.datastructure.linear.SequenceList;

/**
 * 顺序队列(非循环队列,出队元素整体前移)
 * @param <E> 元素类型
 */
public class ArrayQueue<E> implements Queue<E> {
    private final SequenceList<E> list;

    public ArrayQueue() {
        this.list = new SequenceList<>();
    }

    public ArrayQueue(int capacity) {
        this.list = new SequenceList<>(capacity);
    }

    @Override
    public boolean enqueue(E element) {
        return list.add(list.size(), element);
    }

    @Override
    public E dequeue() {
        if (isEmpty()) {
            System.out.println("队列为空");
            return null;
        }
        E front = list.get(0);
        list.remove(0);
        System.out.println(front + "出队列");
        return front;
    }

    @Override
    public E peek() {
        return isEmpty() ? null : list.get(0);
    }

    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }

    @Override
    public void show() {
        if (isEmpty()) {
            System.out.println("队列为空");
            return;
        }
        list.show();
    }
}

3. 链队列实现 LinkedQueue.java

保留原代码遍历入队逻辑,标注优化点(增加尾指针可实现 O(1) 入队)。

package com.datastructure.queue;

/**
 * 链队列(单链表实现,队头在头部)
 * 优化点:可增加尾指针将入队复杂度从O(n)降为O(1)
 * @param <E> 元素类型
 */
public class LinkedQueue<E> implements Queue<E> {
    private static class Node<E> {
        E data;
        Node<E> next;
        Node(E data) {
            this.data = data;
        }
    }

    private Node<E> front;
    private int size;

    public LinkedQueue() {
        this.front = null;
        this.size = 0;
    }

    @Override
    public boolean enqueue(E element) {
        Node<E> newNode = new Node<>(element);
        if (isEmpty()) {
            front = newNode;
            size++;
            return true;
        }
        // 遍历到队尾
        Node<E> rear = front;
        for (int i = 0; i < size - 1; i++) {
            rear = rear.next;
        }
        rear.next = newNode;
        size++;
        return true;
    }

    @Override
    public E dequeue() {
        if (isEmpty()) {
            System.out.println("队列为空");
            return null;
        }
        E value = front.data;
        Node<E> temp = front;
        front = front.next;
        temp.next = null;
        size--;
        System.out.println(value + "出队列");
        return value;
    }

    @Override
    public E peek() {
        return isEmpty() ? null : front.data;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public void show() {
        if (isEmpty()) {
            System.out.println("队列为空");
            return;
        }
        Node<E> current = front;
        for (int i = 0; i < size; i++) {
            System.out.print(current.data + "\t");
            current = current.next;
        }
        System.out.println();
    }
}

六、图书管理系统模块

1. 图书实体类 Book.java

package com.datastructure.model;

/**
 * 图书实体类
 */
public class Book {
    private int bookNo;
    private String bookName;
    private float price;

    public Book() {}

    public Book(int bookNo, String bookName, float price) {
        this.bookNo = bookNo;
        this.bookName = bookName;
        this.price = price;
    }

    public void display() {
        System.out.println(bookNo + "\t" + bookName + "\t" + price);
    }

    // getter & setter
    public int getBookNo() { return bookNo; }
    public void setBookNo(int bookNo) { this.bookNo = bookNo; }
    public String getBookName() { return bookName; }
    public void setBookName(String bookName) { this.bookName = bookName; }
    public float getPrice() { return price; }
    public void setPrice(float price) { this.price = price; }
}

2. 图书管理接口 BookManager.java

package com.datastructure.manager;

import com.datastructure.model.Book;

/**
 * 图书管理业务接口
 */
public interface BookManager {
    boolean addBook(int index, Book book);
    boolean removeBook(int index);
    boolean findByName(String bookName);
    boolean updateBookName(int index, String newName);
    void displayAll();
    int getCount();
    void sortByPrice(); // 仅顺序表版本完整实现
}

3. 顺序表版图书管理 SequenceBookManager.java

package com.datastructure.manager;

import com.datastructure.linear.SequenceList;
import com.datastructure.model.Book;

/**
 * 顺序表实现图书管理系统
 */
public class SequenceBookManager implements BookManager {
    private final SequenceList<Book> bookList;

    public SequenceBookManager(int maxSize) {
        this.bookList = new SequenceList<>(maxSize);
    }

    @Override
    public boolean addBook(int index, Book book) {
        return bookList.add(index, book);
    }

    @Override
    public boolean removeBook(int index) {
        return bookList.remove(index);
    }

    @Override
    public boolean findByName(String bookName) {
        for (int i = 0; i < bookList.size(); i++) {
            if (bookList.get(i).getBookName().equals(bookName)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean updateBookName(int index, String newName) {
        if (index < 0 || index >= bookList.size()) {
            System.out.println("修改位置不正确");
            return false;
        }
        bookList.get(index).setBookName(newName);
        return true;
    }

    @Override
    public void displayAll() {
        if (bookList.isEmpty()) {
            System.out.println("顺序表为空");
            return;
        }
        System.out.println("顺序表中的数据为:");
        for (int i = 0; i < bookList.size(); i++) {
            bookList.get(i).display();
        }
        System.out.println();
    }

    @Override
    public int getCount() {
        return bookList.size();
    }

    /**
     * 按价格冒泡排序(从低到高)
     */
    @Override
    public void sortByPrice() {
        int len = bookList.size();
        for (int i = 0; i < len - 1; i++) {
            for (int j = 0; j < len - i - 1; j++) {
                if (bookList.get(j).getPrice() > bookList.get(j + 1).getPrice()) {
                    Book temp = bookList.get(j);
                    bookList.set(j, bookList.get(j + 1));
                    bookList.set(j + 1, temp);
                }
            }
        }
    }
}

4. 链表版图书管理 LinkedBookManager.java

package com.datastructure.manager;

import com.datastructure.linear.LinkedList;
import com.datastructure.model.Book;

/**
 * 链表实现图书管理系统
 */
public class LinkedBookManager implements BookManager {
    private final LinkedList<Book> bookList;

    public LinkedBookManager() {
        this.bookList = new LinkedList<>();
    }

    @Override
    public boolean addBook(int index, Book book) {
        return bookList.add(index, book);
    }

    @Override
    public boolean removeBook(int index) {
        return bookList.remove(index);
    }

    @Override
    public boolean findByName(String bookName) {
        for (int i = 0; i < bookList.size(); i++) {
            if (bookList.get(i).getBookName().equals(bookName)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean updateBookName(int index, String newName) {
        if (index < 0 || index >= bookList.size()) {
            System.out.println("修改位置不正确");
            return false;
        }
        bookList.get(index).setBookName(newName);
        return true;
    }

    @Override
    public void displayAll() {
        if (bookList.isEmpty()) {
            System.out.println("链表为空");
            return;
        }
        for (int i = 0; i < bookList.size(); i++) {
            bookList.get(i).display();
        }
        System.out.println();
    }

    @Override
    public int getCount() {
        return bookList.size();
    }

    @Override
    public void sortByPrice() {
        System.out.println("链表版暂不支持排序功能");
    }
}

七、测试入口示例(控制台交互)

图书管理系统启动类

package test;

import com.datastructure.manager.BookManager;
import com.datastructure.manager.SequenceBookManager;
import com.datastructure.model.Book;
import java.util.Scanner;

/**
 * 顺序表版图书管理系统测试
 */
public class BookSystemTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        BookManager manager = new SequenceBookManager(20);

        while (true) {
            System.out.println("--------------------------------------------------------------------");
            System.out.println("欢迎使用图书管理系统");
            System.out.println("1.添加图书");
            System.out.println("2.删除图书");
            System.out.println("3.查找图书");
            System.out.println("4.显示所有");
            System.out.println("5.修改图书名");
            System.out.println("6.图书按价格排序");
            System.out.println("7.退出系统");
            System.out.println("--------------------------------------------------------------------");
            System.out.print("请选择:");

            int choice = scanner.nextInt();
            switch (choice) {
                case 1:
                    System.out.print("请输入图书名称:");
                    String name = scanner.next();
                    System.out.print("请输入图书价格:");
                    float price = scanner.nextFloat();
                    Book book = new Book(manager.getCount() + 1, name, price);
                    manager.addBook(manager.getCount(), book);
                    break;
                case 2:
                    System.out.print("请输入删除第几本图书(从1起):");
                    int delIndex = scanner.nextInt();
                    manager.removeBook(delIndex - 1);
                    break;
                case 3:
                    System.out.print("请输入图书名称:");
                    String searchName = scanner.next();
                    System.out.println(manager.findByName(searchName) ? "找到该图书" : "未找到该图书");
                    break;
                case 4:
                    manager.displayAll();
                    break;
                case 5:
                    System.out.print("请输入修改第几本图书(从1起):");
                    int updateIndex = scanner.nextInt();
                    System.out.print("请输入新图书名称:");
                    String newName = scanner.next();
                    manager.updateBookName(updateIndex - 1, newName);
                    break;
                case 6:
                    manager.sortByPrice();
                    manager.displayAll();
                    break;
                case 7:
                    System.out.println("退出系统");
                    scanner.close();
                    return;
                default:
                    System.out.println("输入错误,请重新选择");
            }
        }
    }
}

八、企业级优化说明

  1. 架构解耦:接口与实现分离,可无缝替换底层存储结构,符合开闭原则。
  2. 泛型复用:所有数据结构支持任意引用类型,避免重复造轮子。
  3. 健壮性增强:参数合法性校验、自动扩容、内存泄漏修复(C++ 析构函数问题 Java GC 天然解决)。
  4. 代码规范:驼峰命名、权限控制、注释完整,符合阿里巴巴 Java 开发手册标准。
  5. 可扩展性:可快速接入循环队列、双向链表、归并排序等扩展实现。
  6. Bug 修复:修复原 C++ 代码中修改方法返回值错误、数组越界、析构逻辑错误等问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值