Java算法技术文章:深入解析排序、搜索与数据结构

引言
在软件开发的世界里,算法不仅是程序设计的基础,更是提升软件性能、优化用户体验的关键。Java,作为一种广泛使用的编程语言,提供了丰富的API和标准库来支持各种算法的实现。本文将深入探讨Java中的排序算法、搜索算法以及一些常见的数据结构,旨在帮助读者从基础到高级理解这些算法的原理、实现和应用。

第一部分:排序算法

  1. 冒泡排序(Bubble Sort)

冒泡排序是一种简单的排序算法,时间复杂度为O(n^2)。它的原理是通过重复地遍历要排序的数列,每次比较相邻的两个元素,如果它们的顺序错误就把它们交换过来。

public class BubbleSort {public static void sort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {// 交换元素int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}
}
  1. 选择排序(Selection Sort)

选择排序的工作原理是每次从未排序的元素中选择最小(或最大)的元素,放在已排序序列的末尾。它的时间复杂度也是O(n^2)。

public class SelectionSort {public static void sort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {int minIdx = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIdx]) {minIdx = j;}}// 交换元素int temp = arr[minIdx];arr[minIdx] = arr[i];arr[i] = temp;}}
}
  1. 插入排序(Insertion Sort)

插入排序的基本操作是将一个数据插入到已排序的有序数据中,从而得到一个新的、元素数增1的有序数据。它的时间复杂度在最坏和平均情况下为O(n^2),但在接近有序的数据序列中表现出色。

public class InsertionSort {public static void sort(int[] arr) {int n = arr.length;for (int i = 1; i < n; ++i) {int key = arr[i];int j = i - 1;// 将key插入到已排序的子序列中while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}}
}
  1. 快速排序(Quick Sort)

快速排序使用分治策略,通过选择一个元素作为"基准"(pivot),将数组分成小于基准和大于基准的两部分,然后递归地对这两部分进行排序。其平均时间复杂度为O(n log n)。

public class QuickSort {public static void sort(int[] arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);sort(arr, low, pi - 1);sort(arr, pi + 1, high);}}private static int partition(int[] arr, int low, int high) {int pivot = arr[high];  int i = (low - 1);  for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;// 交换元素int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 将pivot放到正确的位置int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;}
}
  1. 归并排序(Merge Sort)

归并排序也是基于分治策略的工作原理。首先将数组分成两半,分别排序,然后将两个有序数组合并成一个有序数组。它的时间复杂度为O(n log n)。

public class MergeSort {public static void sort(int[] arr, int left, int right) {if (left < right) {// 找出中间索引int middle = (left + right) / 2;sort(arr, left, middle);sort(arr, middle + 1, right);// 合并两个子数组merge(arr, left, middle, right);}}private static void merge(int[] arr, int left, int middle, int right) {// 临时数组用于存储合并后的数据int[] temp = new int[right - left + 1];int i = left, j = middle + 1, k = 0;while (i <= middle && j <= right) {if (arr[i] <= arr[j]) {temp[k++] = arr[i++];} else {temp[k++] = arr[j++];}}// 如果左边子数组还有剩余while (i <= middle) {temp[k++] = arr[i++];}// 如果右边子数组还有剩余while (j <= right) {temp[k++] = arr[j++];}// 将排序好的数据复制回原数组for (i = left; i <= right; i++) {arr[i] = temp[i - left];}}
}

第二部分:搜索算法

  1. 线性搜索(Linear Search)

线性搜索是最简单的搜索算法,它遍历数组中的每个元素,直到找到目标值或遍历完所有元素。时间复杂度为O(n)。

public class LinearSearch {public static int search(int[] arr, int target) {for (int i = 0; i < arr.length; i++) {if (arr[i] == target) {return i; // 返回目标所在的索引}}return -1; // 目标不在数组中}
}
  1. 二分查找(Binary Search)

二分查找适用于已排序的数组。它的原理是将数组分成两半,如果查找值等于中间元素,则返回该位置;如果查找值小于中间元素,则在左半部继续搜索;如果大于,则在右半部继续搜索。其时间复杂度为O(log n)。

public class BinarySearch {public static int search(int[] arr, int target) {int left = 0;int right = arr.length - 1;while (left <= right) {int mid = left + (right - left) / 2;// 如果查找值等于中间元素,则返回该位置if (arr[mid] == target) {return mid;}if (arr[mid] < target) {left = mid + 1; // 在右半部继续搜索} else {right = mid - 1; // 在左半部继续搜索}}return -1; // 目标不在数组中}
}

第三部分:数据结构

  1. 数组(Array)

数组是最基本的数据结构,在Java中,数组可以是基本类型数组或对象数组。数组允许直接通过索引访问元素,效率高,但大小固定。

int[] arr = new int[10];
arr[0] = 1;
  1. 链表(Linked List)

链表是一种线性结构,元素通过指针连接。Java的集合框架提供了LinkedList类,适用于插入和删除操作频繁的场景。

LinkedList<Integer> list = new LinkedList<>();
list.add(1);
list.add(2);
  1. 栈(Stack)

栈是一种后进先出(LIFO)的数据结构。Java中可以通过Stack类或使用Deque接口的实现来实现栈。

Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
int popElement = stack.pop();
  1. 队列(Queue)

队列是一种先进先出(FIFO)的数据结构。Java中可以使用Queue接口及其实现类,如LinkedList。

Queue<Integer> queue = new LinkedList<>();
queue.offer(1);
queue.offer(2);
int pollElement = queue.poll();
  1. 树(Tree)和二叉搜索树(Binary Search Tree, BST)

树是一种层次结构的数据结构。BST是一种特殊的二叉树,左子节点的值小于根节点,右子节点的值大于根节点。

class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) { val = x; }
}// 插入方法示例
public void insert(TreeNode root, int value) {if (root == null) {root = new TreeNode(value);return;}if (value < root.val) {if (root.left == null) {root.left = new TreeNode(value);} else {insert(root.left, value);}} else {if (root.right == null) {root.right = new TreeNode(value);} else {insert(root.right, value);}}
}
  1. 图(Graph)

图由节点和连接这些节点的边组成。在Java中,图可以用邻接矩阵或邻接表表示。

class Graph {private int V; // 节点数private List<List<Integer>> adj; // 邻接表Graph(int v) {V = v;adj = new ArrayList<>(v);for (int i = 0; i < v; ++i)adj.add(new ArrayList<>());}void addEdge(int v, int w) {adj.get(v).add(w); // 添加边 v -> w}
}

以下是一些额外的Java代码示例,涵盖了更多算法和数据结构的实现,以补充前文中的内容:

排序算法补充
6. 堆排序(Heap Sort)

堆排序利用堆这种数据结构进行排序。堆是一种完全二叉树,父节点的键值总是保持在子节点之上(最大堆)或之下(最小堆)。这里我们将实现一个最大堆排序。

public class HeapSort {public static void sort(int[] arr) {int n = arr.length;// 构建最大堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 一个一个地从堆中提取元素for (int i = n - 1; i > 0; i--) {// 将当前最大值 (根节点) 移到数组末尾int temp = arr[0];arr[0] = arr[i];arr[i] = temp;// 重新调整堆heapify(arr, i, 0);}}// 调整为最大堆private static void heapify(int[] arr, int n, int i) {int largest = i; // 初始化最大值为根节点int left = 2 * i + 1;int right = 2 * i + 2;// 如果左子节点比根节点大,则设置最大值为左子节点if (left < n && arr[left] > arr[largest]) {largest = left;}// 如果右子节点比当前最大值大,则设置最大值为右子节点if (right < n && arr[right] > arr[largest]) {largest = right;}// 如果最大值不是根节点,则交换它们if (largest != i) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;// 递归调整受影响的子树heapify(arr, n, largest);}}
}

搜索算法补充
3. 跳跃搜索(Jump Search)

跳跃搜索适用于排序数组,它通过跳跃一定步长(通常是\sqrt{n})来搜索元素,然后在找到的块中进行线性搜索。

public class JumpSearch {public static int search(int[] arr, int x) {int n = arr.length;// 计算步长int step = (int)Math.floor(Math.sqrt(n));int prev = 0;// 找到块,其中元素可能存在while (arr[Math.min(step, n) - 1] < x) {prev = step;step += (int)Math.floor(Math.sqrt(n));if (prev >= n) {return -1;}}// 执行线性搜索while (arr[prev] < x) {prev++;if (prev == Math.min(step, n)) {return -1;}}// 如果找到元素,则返回其索引if (arr[prev] == x) {return prev;}return -1;}
}

数据结构补充
7. 哈希表(HashMap)

Java中的HashMap是基于哈希表的数据结构,提供快速的存取操作。以下是如何使用HashMap来实现一个简单的字频统计功能:

import java.util.HashMap;
import java.util.Map;public class WordFrequency {public static void main(String[] args) {String text = "Java is fun. Java is simple. Java is powerful.";Map<String, Integer> wordFrequency = new HashMap<>();// 清洗文本,转换为小写并按空格分割String[] words = text.toLowerCase().split("\\s+");// 统计每个单词的频率for (String word : words) {// 移除标点符号word = word.replaceAll("[^a-zA-Z]", "");if (!word.isEmpty()) {wordFrequency.put(word, wordFrequency.getOrDefault(word, 0) + 1);}}// 输出结果for (Map.Entry<String, Integer> entry : wordFrequency.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());}}
}
  1. 二叉堆(Binary Heap)

二叉堆可以用于实现优先级队列。下面是实现一个最小堆(Min Heap)的例子:

import java.util.ArrayList;
import java.util.List;public class MinHeap {private List<Integer> heap;public MinHeap() {this.heap = new ArrayList<>();}public void insert(int value) {heap.add(value);int current = heap.size() - 1;while (current > 0 && heap.get(parent(current)) > heap.get(current)) {swap(current, parent(current));current = parent(current);}}public int extractMin() {if (heap.isEmpty()) {throw new IllegalStateException("Heap is empty");}int min = heap.get(0);int last = heap.remove(heap.size() - 1);if (!heap.isEmpty()) {heap.set(0, last);heapifyDown(0);}return min;}private void heapifyDown(int index) {int minIndex = index;int left = leftChild(index);if (left < heap.size() && heap.get(left) < heap.get(minIndex)) {minIndex = left;}int right = rightChild(index);if (right < heap.size() && heap.get(right) < heap.get(minIndex)) {minIndex = right;}if (index != minIndex) {swap(index, minIndex);heapifyDown(minIndex);}}private void swap(int i, int j) {int temp = heap.get(i);heap.set(i, heap.get(j));heap.set(j, temp);}private int parent(int i) {return (i - 1) / 2;}private int leftChild(int i) {return 2 * i + 1;}private int rightChild(int i) {return 2 * i + 2;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/895026.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Spring】什么是Spring?

什么是Spring&#xff1f; Spring是一个开源的轻量级框架&#xff0c;是为了简化企业级开发而设计的。我们通常讲的Spring一般指的是Spring Framework。Spring的核心是控制反转(IoC-Inversion of Control)和面向切面编程(AOP-Aspect-Oriented Programming)。这些功能使得开发者…

学习笔记:机器学习中的数学原理(一)

1. 集合 集合分为有限集和无限集&#xff1b; 对于有限集&#xff0c;两集合元素数相等即为等势&#xff1b; 对于无限集&#xff0c;两集合元素存在一一映射关系即为等势&#xff1b; 无限集根据是否与正整数集等势分为可数集和不可数集。 2. sigmoid函数&#xff08;也叫…

【信息系统项目管理师-案例真题】2016下半年案例分析答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一【问题1】4 分【问题2】12 分【问题3】3 分【问题4】6 分试题二【问题1】3 分【问题2】4 分【问题3】8 分【问题4】5 分【问题5】5 分试题三【问题1】4 分【问题2】8 分【问题3】5 分【问题4】8 分试题一…

基于javaweb的SpringBoothis智能医院管理系统(源码+文档+部署讲解)

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 运行环境开发工具适用功能说明一、项目运行 环境配置&#xff1a; 运行环境 Java≥8、MySQL≥5.7、Node.js≥14 开发工具 后端&…

JS实现灯光闪烁效果

在 JS中&#xff0c;我们可以实现灯光闪烁效果&#xff0c;这里主要用 setInterval 和 clearInterval 两个重要方法。 效果图 源代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>灯闪烁效果<…

7.PPT:“中国梦”学习实践活动【20】

目录 NO1234​ NO5678​ NO9\10\11 NO1234 考生文件夹下创建一个名为“PPT.pptx”的新演示文稿Word素材文档的文字&#xff1a;复制/挪动→“PPT.pptx”的新演示文稿&#xff08;蓝色、黑色、红色&#xff09; 视图→幻灯片母版→重命名&#xff1a;“中国梦母版1”→背景样…

学习笔记十九:K8S生成pod过程

K8S生成pod过程 流程图具体生成过程用户提交 Pod 定义API Server 处理请求调度器分配节点&#xff08;Scheduling&#xff09;目标节点上的 Pod 创建网络配置状态上报与监控控制器管理&#xff08;Controller Manager&#xff09;就绪与服务发现 关键错误场景高级特性 流程图 具…

封装descriptions组件,描述,灵活

效果 1、组件1&#xff0c;dade-descriptions.vue <template><table><tbody><slot></slot></tbody> </table> </template><script> </script><style scoped>table {width: 100%;border-collapse: coll…

21.2.6 字体和边框

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 通过设置Rang.Font对象的几个成员就可以修改字体&#xff0c;设置Range.Borders就可以修改边框样式。 【例 21.6】【项目&#xff…

360手机刷机 360手机解Bootloader 360手机ROOT

360手机刷机 360手机解Bootloader 360手机ROOT 问&#xff1a;360手机已停产&#xff0c;现在和以后&#xff0c;能刷机吗&#xff1f; 答&#xff1a;360手机&#xff0c;是肯定能刷机的 360手机资源下载网站 360手机-360手机刷机RootTwrp 360os.top 360rom.github.io 一、…

链表专题-02

链表专题 /*** 链表的节点* param <E>*/ public class ListNode<E> {public E element;public ListNode<E> next;public ListNode() {}public ListNode(E element) {this.element element;}public ListNode(E element, ListNode<E> next) {this.eleme…

外部中断实验 #STM32F407

外部中断实验 此实验将外部中断配置为按键输入&#xff0c;通过按键输入触发外部中断&#xff0c;在外部中断里面实施相应的处理&#xff0c;具体功能&#xff1a; 按下KEY0&#xff0c;翻转LED0状态按下KEY1&#xff0c;翻转LED1状态按下KEY2&#xff0c;同时翻转LED0和LED1…

机器学习8-卷积和卷积核1

机器学习8-卷积和卷积核1 卷积与图像去噪卷积的定义与性质定义性质卷积的原理卷积步骤卷积的示例与应用卷积的优缺点优点缺点 总结 高斯卷积核卷积核尺寸的设置依据任务类型考虑数据特性实验与调优 高斯函数标准差的设置依据平滑需求结合卷积核尺寸实际应用场景 总结 图像噪声与…

SVN 提交与原有文件类型不一样的文件时的操作

SVN 提交与原有文件类型不一样的文件时的操作 背景 SVN 服务器上原本的文件是软链接类型的&#xff0c;但是我将它改成普通文件再上传。出现了以下提示&#xff1a; 解决过程 本来想着通过 svn rm 和 svn add 来解决&#xff0c;但是行不通。 最终解决方案 svn rm --keep-…

阿里云专有云网络架构学习

阿里云专有云网络架构 叶脊&#xff08;spine-leaf&#xff09;网络和传统三层网络拓扑对比 阿里云网络架构V3拓扑角色介绍推荐设备设备组网举例带外管理网络带外网和带内网对比设备介绍 安全网络设备介绍 参考 后续更新流量分析叶脊&#xff08;spine-leaf&#xff09;网络和传…

Deepseek本地部署指南:在linux服务器部署,在mac远程web-ui访问

1. 在Linux服务器上部署DeepSeek模型 要在 Linux 上通过 Ollama 安装和使用模型&#xff0c;您可以按照以下步骤进行操作&#xff1a; 步骤 1&#xff1a;安装 Ollama 安装 Ollama&#xff1a; 使用以下命令安装 Ollama&#xff1a; curl -sSfL https://ollama.com/download.…

3D数字化营销:重塑家居电商新生态

随着电商的蓬勃发展&#xff0c;网上订购家具已成为众多消费者的首选。然而&#xff0c;线上选购家具的诸多挑战&#xff0c;如风格不匹配、尺寸不合适、定制效果不如预期以及退换货不便等&#xff0c;一直困扰着消费者。为解决这些问题&#xff0c;家居行业急需一种全新的展示…

重塑“景区+商业”模式,打造特色文旅新体验

重塑“景区商业”模式&#xff0c;打造特色文旅新体验 近年来&#xff0c;旅游业蓬勃发展&#xff0c;旅游热潮不断升温&#xff0c;游客消费观念也随之升级。为顺应这一趋势&#xff0c;各大景区纷纷探索打造特色文旅项目&#xff0c;以期吸引更多游客。然而&#xff0c;“景…

在亚马逊云科技上云原生部署DeepSeek-R1模型(下)

在本系列的上篇中&#xff0c;我们介绍了如何通过Amazon Bedrock部署并测试使用了DeepSeek模型。在接下来的下篇中小李哥将继续介绍&#xff0c;如何利用亚马逊的AI模型训练平台SageMaker AI中的&#xff0c;Amazon Sagemaker JumpStart通过脚本轻松一键式部署DeepSeek预训练模…

Kubernetes是什么?为什么它是云原生的基石

从“手工时代”到“自动化工厂” 想象一下&#xff0c;你正在经营一家工厂。在传统模式下&#xff0c;每个工人&#xff08;服务器&#xff09;需要手动组装产品&#xff08;应用&#xff09;&#xff0c;效率低下且容易出错。而Kubernetes&#xff08;k8s&#xff09;就像一个…