数据结构(三)循环链表 约瑟夫环

文章目录

  • 一、循环链表
    • (一)概念
    • (二)示意图
    • (三)操作
      • 1. 创建循环链表
        • (1)函数声明
        • (2)注意点
        • (3)代码实现
      • 2. 插入(头插,尾插,任意位置插入)
        • (1)头插
          • ① 函数声明
          • ② 注意点
          • ③ 代码实现
        • (2)尾插
          • ① 函数声明
          • ② 注意点
          • ③ 代码实现
        • (3)任意位置插入
          • ① 函数声明
          • ② 注意点
          • ③ 代码实现
      • 3. 删除(头删,尾删,任意位置删除)
        • (1)头删
          • ① 函数声明
          • ② 注意点
          • ③ 代码实现
        • (2)尾删
          • ① 函数声明
          • ② 注意点
          • ③ 代码实现
        • (3)任意位置删除
          • ① 函数声明
          • ② 注意点
          • ③ 代码实现
      • 4. 修改
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 5. 查询
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 6. 清空和销毁
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 7. 打印链表(方便查看实验现象)
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 8. 排序(以正序排序为例)
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
      • 9.剔重
        • (1)函数定义
        • (2)注意点
        • (3)代码实现
    • (四)应用:实现约瑟夫环
      • 1.问题描述
      • 2. 问题分析
      • 3. 代码实现
      • 4. 使用前面的循环链表实现
  • 二、代码源码已上传资源

一、循环链表

(一)概念

操作和单向链表的操作基本一样
只是判断链表结束的条件不同

循环链表又分为有头循环链表和无头循环链表,其中无头结点的循环链表相对更常见些,因此下文以实现无头循环链表为例。

(二)示意图

在这里插入图片描述

(三)操作

结构体定义:

//数据元素结构体
typedef struct circle_node
{int data;struct circle_node *next;
}nd_t;//数据对象结构体
typedef struct circle_list
{nd_t *phead; //指向头节点//还可以添加其他成员
}list_t;

1. 创建循环链表

(1)函数声明

int create_list(list_t **my_list);

创建循环链表的第一个节点,
第一个节点的next指向它自己
将第一个节点的堆区地址传给main函数中的指针

(2)注意点
  1. 入参不能为空
  2. 因为需要将申请的第一个节点的地址写入main函数中的指针变量中,因此必须传入二级指针
  3. 申请内存空间后检查是否申请成功
(3)代码实现
int create_list(list_t **my_list){if(NULL==my_list){return -1;}*my_list=(list_t *)malloc(sizeof(list_t));if(NULL==*my_list){return -1;}(*my_list)->phead=NULL;return 0;
}

2. 插入(头插,尾插,任意位置插入)

(1)头插
① 函数声明

int insert_list_by_head(list_t *my_list,int num);

创建新节点
找到尾节点,将尾节点的next指向新的节点
新节点的next指向首节点
*phead指向pnew

② 注意点
  1. 入参不能为NULL
  2. 头插需要更改main函数中phead指针的值,因此需要传二级指针
  3. 需要保证链表中至少有一个节点,无头链表中只要phead不为NULL,就说明至少有一个节点
③ 代码实现
int insert_list_by_head(list_t *my_list,int num){//入参不合理if(NULL==my_list)return -1;//创建新节点nd_t *pnew=(nd_t *)malloc(sizeof(nd_t));if(NULL==pnew)return -1;pnew->data=num;//插入首节点if(NULL==my_list->phead){my_list->phead=pnew;pnew->next=pnew;return 0;}//如果插入的不是第一个节点//先找到尾节点nd_t *ptemp=my_list->phead;while(ptemp->next!=my_list->phead){ptemp=ptemp->next;}//插入ptemp->next=pnew;pnew->next=my_list->phead;my_list->phead=pnew;return 0;
}
(2)尾插
① 函数声明

int insert_list_by_tail(list_t *my_list,int num);

创建新节点
找到尾节点,将尾节点的next指向新的节点
新节点的next指向首节点

② 注意点
  1. 头插和尾插的区别仅在于是否需要修改main函数中的指针变量
③ 代码实现
int insert_list_by_tail(list_t *my_list,int num){if(NULL==my_list)return -1;//创建新节点nd_t *pnew=(nd_t *)malloc(sizeof(nd_t));if(NULL==pnew)return -1;pnew->data=num;//插入首节点if(NULL==my_list->phead){my_list->phead=pnew;pnew->next=pnew;return 0;}//找到尾节点nd_t *ptemp=my_list->phead;while(ptemp->next!=my_list->phead){ptemp=ptemp->next;}//插入ptemp->next=pnew;pnew->next=my_list->phead;return 0;
}
(3)任意位置插入
① 函数声明

int insert_list_by_pos(list_t *my_list,int pos,int num);

找到要插入的位置的前一个节点
创建新节点
插入节点

② 注意点
  1. 不支持插入在第一个位置
  2. 如果插入的前一个位置在最后一个可以,但是在第一个就不合理了
③ 代码实现
int insert_list_by_pos(list_t *my_list,int pos,int num){if(NULL==my_list)return -1;if(pos<0)return -1;//找到要插入的节点的前一位nd_t *ptemp=my_list->phead;int i=0;//记录ptemp移动了几步while(ptemp->next!=my_list->phead){if(i==pos-1) break; ptemp=ptemp->next;i++;}//如果已经到尾节点了还没移动到pos位置就说明位置不合理if(i<pos-1){printf("位置不合理\n");return -1;}//创建新节点nd_t *pnew=(nd_t *)malloc(sizeof(nd_t));if(NULL==pnew)return -1;pnew->data=num;//插入第一个节点if(NULL==my_list->phead){my_list->phead=pnew;pnew->next=pnew;return 0;}//插入到头节点if(0==pos){nd_t *ptail=my_list->phead;while(ptail->next!=my_list->phead)ptail=ptail->next;ptail->next=pnew;pnew->next=my_list->phead;my_list->phead=pnew;return 0;}//插入节点pnew->next=ptemp->next;ptemp->next=pnew;return 0;
}

3. 删除(头删,尾删,任意位置删除)

(1)头删
① 函数声明

delete_list_by_head(list_t *my_list);

找到尾节点
尾节点的next置成*phead->next
*phead=*phead->next
free(pdef)

② 注意点
  1. 需要传入二级指针
  2. 当表中只有一个节点时,进行删除操作时相当于将表销毁了。
③ 代码实现
int delete_list_by_head(list_t *my_list){//传参为空或者表为空if(NULL==my_list||NULL==my_list->phead)return -1;//只有一个节点if(my_list->phead->next==my_list->phead){free(my_list->phead);my_list->phead=NULL;printf("表已清空\n");return 0;}//多个节点//找到尾节点nd_t *ptemp=my_list->phead->next;while(ptemp->next!=my_list->phead){ptemp=ptemp->next;}//头删nd_t *pdel=my_list->phead;my_list->phead=my_list->phead->next;ptemp->next=my_list->phead;free(pdel);pdel=NULL;return 0;
}
(2)尾删
① 函数声明

int delete_list_by_tail(list_t *my_list);

找到尾节点的前一节点,
尾删操作

② 注意点
  1. 需要传入二级指针
  2. 当表中只有一个节点时,进行删除操作时相当于将表销毁了。
③ 代码实现
int delete_list_by_tail(list_t *my_list){//传参为空或者表为空if(NULL==my_list||NULL==my_list->phead)return -1;//只有一个节点if(my_list->phead->next==my_list->phead){free(my_list->phead);my_list->phead=NULL;printf("表已清空\n");return 0;}//多个节点//找到尾节点的前一个节点nd_t *ptemp=my_list->phead->next;while(ptemp->next->next!=my_list->phead){ptemp=ptemp->next;}//尾删nd_t *pdel=ptemp->next;ptemp->next=my_list->phead;free(pdel);pdel=NULL;return 0;
}
(3)任意位置删除
① 函数声明

int delete_list_by_pos(list_t *my_list,int pos);

② 注意点
  1. 链表中至少有一个节点
  2. 如果只有一个节点时要删除第0个位置可以成功,此时链表销毁;其他位置均为不合理
  3. 如果多个节点时,需要区分是不是要删除头节点
  4. ptemp是要删除的节点的前一个节点,它不能是尾节点
③ 代码实现
int delete_list_by_pos(list_t *my_list,int pos){//传参为空或者表为空if(NULL==my_list||NULL==my_list->phead)return -1;if(0>pos){return -1;}//如果链表中只有一个节点if(my_list->phead->next==my_list->phead){//删除第一个位置的节点if(0==pos){free(my_list->phead);my_list->phead=NULL;return 0;}//删除其他位置节点,均是位置不合理printf("位置不合理\n");return -1;}//链表有多个节点nd_t *pdel=my_list->phead;//删除第一个位置的节点//找到尾节点nd_t *ptemp=my_list->phead;while(ptemp->next!=my_list->phead){ptemp=ptemp->next;}if(0==pos){my_list->phead=my_list->phead->next;ptemp->next=my_list->phead;free(pdel);pdel=NULL;return 0;}//删除其他位置节点//找到要删除的节点的前一个节点ptemp=my_list->phead;for(int i=0;i<pos-1;i++){//要删除的节点的前一个节点不能是尾节点if(ptemp->next->next==my_list->phead){printf("删除位置不合理\n");return -1;}ptemp=ptemp->next;}pdel=ptemp->next;ptemp->next=pdel->next;free(pdel);pdel=NULL;return 0;
}

4. 修改

(1)函数定义

int modify_list_by_pos(list_t *my_list,int pos,int num);

遍历链表找到第pos个位置

(2)注意点
  1. 如果已经到达尾节点就不能再继续向下遍历修改
(3)代码实现
int modify_list_by_pos(list_t *my_list,int pos,int num){//至少有一个节点if(NULL==my_list||NULL==my_list->phead)return -1;if(0>pos){return -1;}//找到第pos个位置nd_t *ptemp=my_list->phead;for(int i=0;i<pos;i++){if(ptemp->next==my_list->phead){printf("位置不合理\n");return -1;}ptemp=ptemp->next;}ptemp->data=num;return 0;
}

5. 查询

(1)函数定义

int search_list_by_pos(list_t *my_list,int pos,int *num);

找到第pos个位置
读取数据域数据

(2)注意点
  1. 查询和修改的唯一区别是对数据的处理,修改是将新的数据写到第pos尾的数据域;修改是将pos位的数据域写到num中
  2. 循环结束条件与修改和删除一样
(3)代码实现
int search_list_by_pos(list_t *my_list,int pos,int *num){//至少有一个节点if(NULL==my_list||NULL==my_list->phead||NULL==num)return -1;if(0>pos){return -1;}//找到第pos个位置nd_t *ptemp=my_list->phead;for(int i=0;i<pos;i++){if(ptemp->next==my_list->phead){printf("位置不合理\n");return -1;}ptemp=ptemp->next;}*num=ptemp->data;return 0;
}

6. 清空和销毁

(1)函数定义

int clean_list(list_t *my_list);
int destory_list(list_t **my_list);

先判断是不是只有一个节点
采用尾删(使用头删的话还要一直修改main函数中的指针变量的值)

(2)注意点
  1. 使用二级指针
  2. 入参不能为空
(3)代码实现
int clean_list(list_t *my_list){if(NULL==my_list){return -1;}//不止一个节点//采用头删,先找到尾节点前一个节点while(my_list->phead!=NULL){delete_list_by_head(my_list);}return 0;
}
int destory_list(list_t **my_list){if(NULL==my_list||NULL==*my_list){return -1;}clean_list(*my_list);//此时只有一个节点了free(*my_list);*my_list=NULL;return 0;
}

7. 打印链表(方便查看实验现象)

(1)函数定义

int print_list(list_t *my_list);

先打印出第一个节点,
遍历链表,直到ptemp->next==phead时结束

(2)注意点
  1. 在无头链表中phead为NULL,则说明表为空。phead->next==NULL,说明没有第二个节点。
(3)代码实现
int print_list(list_t *my_list){if(NULL==my_list)return -1;nd_t *ptemp=my_list->phead->next;//打印头节点printf("%d ",my_list->phead->data);//当ptemp==mylist->phead时,说明回到了开头while(ptemp!=my_list->phead){printf("%d ",ptemp->data);ptemp=ptemp->next;}putchar(10);return 0;
}

8. 排序(以正序排序为例)

(1)函数定义

int sort_list(list_t *my_list);;

选择排序思路

(2)注意点
  1. 外层循环可以不比较最后一个元素
(3)代码实现
int sort_list(list_t *my_list){if(NULL==my_list||NULL==my_list->phead){return -1;}nd_t *p=my_list->phead;nd_t *q=NULL;while(p->next!=my_list->phead){q=p->next;while(q!=my_list->phead){if(p->data>q->data){int temp=p->data;p->data=q->data;q->data=temp;}q=q->next;}p=p->next;}return 0;
}

9.剔重

(1)函数定义

int dedup_list(list_t *my_list);

动静指针配合
选择排序思路

(2)注意点
  1. 此时外层循环使用p->next!=phead或者p!=phead均可,循环链表此刻不会报段错误,但是用第一种效率会相对略高
(3)代码实现
int dedup_list(list_t *my_list){//至少有一个元素if(NULL==my_list||NULL==my_list->phead){return -1;}nd_t *p=my_list->phead;nd_t *q=NULL;nd_t *m=NULL;while(p->next!=my_list->phead){m=p;q=p->next;while(q!=my_list->phead){if(p->data==q->data){m->next=q->next;free(q);q=m->next;}else{m=q;q=q->next;}}p=p->next;}
}

(四)应用:实现约瑟夫环

1.问题描述

有一位叫约瑟夫的将军,在一次战斗中,连同手下的士兵一起被俘虏了。手下的士兵都非常爱国,宁死不投降,约瑟夫将军想了个办法:
让大家站成一圈,开始数数,从1开始数,数到7的人就自杀,
下一个人重新从1开始数,数到7再自杀,依次类推
直到只剩下一个人为止,最终剩下的就是约瑟夫将军,
然后他不想死,他投降了。这种“圈”,我们称之为“约瑟夫环”

要求:编写代码,模拟约瑟夫环淘汰人的过程,
命令行输入 ./a.out 总人数 数到几自杀 (总人数>1 数到几自杀>1 )
要求程序输出:
第x次 淘汰的是y号
以及最终剩下的是几号
如:输入 ./a.out 5 3 则程序输出
第1次 淘汰的是3号
第2次 淘汰的是1号
第3次 淘汰的是5号
第4次 淘汰的是2号
最后剩下的是 4 号

2. 问题分析

首先需要检查参数的合理性,参数都是以字符串形式保存的,需要转换成int型数据;
无头链表创建链表时就是创建第一个节点,即编号为1的人,之后依次开始创建节点

3. 代码实现

#include <stdio.h>
#include <stdlib.h>typedef struct _Node{int data;struct _Node *next;
}node_t;node_t *create_circle(int num){//创建第一个节点node_t *phead=(node_t *)malloc(sizeof(node_t));if(NULL==phead) return NULL;phead->data=1;phead->next=phead;//创建剩余节点node_t *pnew=NULL;node_t *ptemp=phead;for(int i=1;i<num;i++){pnew=(node_t *)malloc(sizeof(node_t));pnew->data=i+1;if(NULL==pnew) return NULL;//找到尾节点while (ptemp->next!=phead)ptemp=ptemp->next;pnew->next=ptemp->next;ptemp->next=pnew;}return phead;
}int print_circle(node_t *phead){if(NULL==phead) return -1;node_t *ptemp=phead;while(ptemp->next!=phead){printf("%d ",ptemp->data);ptemp=ptemp->next;}printf("%d ",ptemp->data);putchar(10);return 0;
}int del_circle(node_t *phead,int count){if(NULL==phead) return -1;int c=1;int sum=0;node_t *pprev=NULL;while(phead->next!=phead){if(c==count){sum++;c=1;printf("第%d次淘汰%d号\n",sum,phead->data);pprev->next=phead->next;free(phead);phead=pprev->next;continue;}c++;pprev=phead;phead=phead->next;}printf("第%d号存活\n",phead->data);return 0;
}int main(int argc, char const *argv[])
{if (argc!=3){printf("./a/out 总人数 数到几\n");return -1;}int sum=atoi(argv[1]); //人数 int num=atoi(argv[2]); //数到几node_t *my_list=NULL;my_list=create_circle(sum);print_circle(my_list);del_circle(my_list,num);return 0;
}

4. 使用前面的循环链表实现

main.c文件:

#include "circle_list.h"int del(nd_t *phead,int n);
int main(int argc, char const *argv[])
{if(3 != argc){printf("参数不合理\n");return -1;}int num=atoi(argv[1]); //保存个数int n=atoi(argv[2]);//数到几if(num<=0){printf("人数应当大于0\n");return-1;}list_t *my_list=NULL;//第一个人及其编号create_list(&my_list);//后面的人for(int i=1;i<=num;i++){if(insert_list_by_tail(my_list,i)){printf("插入失败\n");return -1;}}print_list(my_list);  del(my_list->phead,n);return 0;
}int del(nd_t *phead,int n)
{if(NULL==phead){printf("传参错误\n");return -1;}if(0>=n){printf("传参错误,n应当大于0\n");return -1;}int index=0;nd_t *pptemp=NULL;while(phead->next!=phead){for(int i=0;i<n-1;i++) //phead默认移到下一位了,故只需要再移动n-1次{pptemp=phead;phead=phead->next;}//此时phead是需要删除的节点,执行删除操作pptemp->next=phead->next; printf("第%d次删除%d\n",index+1,phead->data);free(phead);//删除完成后pead等于后一个节点phead=pptemp->next;index++;}printf("%d存活\n",phead->data);free(phead);phead=NULL;return 0;
}

二、代码源码已上传资源

链接:
C语言实现循环链表源码链接
C语言实现约瑟夫环源码链接

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

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

相关文章

【linux】运维-基础知识-认知hahoop周边

1. HDFS HDFS&#xff08;Hadoop Distributed File System&#xff09;–Hadoop分布式文件存储系统 源自于Google的GFS论文&#xff0c;HDFS是GFS的克隆版 HDFS是Hadoop中数据存储和管理的基础 他是一个高容错的系统&#xff0c;能够自动解决硬件故障&#xff0c;eg&#xff1a…

【Linux 网络编程】网络的背景、协议的分层知识!

文章目录 1. 计算机网络背景2. 认识 "协议"3. 协议分层 1. 计算机网络背景 网络互联: 多台计算机连接在一起, 完成数据共享; &#x1f34e;局域网&#xff08;LAN----Local Area Network&#xff09;: 计算机数量更多了, 通过交换机和路由器连接。 &#x1f34e; 广…

多模态模型入门:BLIP与OWL-ViT

BLIP 数据预处理 CapFilt&#xff1a;标题和过滤 由于多模态模型需要大量数据集&#xff0c;因此通常必须使用图像和替代文本 (alt-text) 对从互联网上抓取这些数据集。然而&#xff0c;替代文本通常不能准确描述图像的视觉内容&#xff0c;使其成为噪声信号&#xff0c;对于…

MAC M1 —— Install

文章目录 MAC M1 —— Install安装IDEA安装JDK安装Maven安装brew无法创建文件 /data/serverMac 修改终端用户名&#xff08;主机名&#xff09;PyCharm MAC M1 —— Install 安装IDEA 关键词&#xff1a;2020到2021.3的激活步骤。找下Download文件夹 安装JDK 在个人的电脑上…

思维+滑动窗口,LeetCode 2831. 找出最长等值子数组

目录 一、题目 1、题目描述 2、接口描述 python3 cpp JS 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 python3 cpp JS 一、题目 1、题目描述 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 如果子数组中所有元素都相等&#xff0c;则认…

TypeScript 学习笔记(十一):TypeScript 与微服务架构的结合应用

TypeScript 学习笔记(十一):TypeScript 与微服务架构的结合应用 1. 引言 在前几篇学习笔记中,我们探讨了 TypeScript 的基础知识、前后端框架的结合应用、测试与调试技巧、数据库以及 GraphQL 的结合应用。本篇将重点介绍 TypeScript 与微服务架构的结合应用,包括如何使…

mysql数据库管理-mysqlbinlog备份与恢复,主备复制分析

由于服务器生成的二进制日志文件以二进制格式保存&#xff0c;所以如果想要检查这些文件的文本格式&#xff0c; 就会用到mysqlbinlog日志管理工具。 mysqlbinlog的具体用法如下&#xff1a; shell> mysqlbinlog [options] log-files1 log-files2. . option有很多选项&…

《探索Stable Diffusion:AI绘画的创意之路与实战秘籍》

《Stable Diffusion AI 绘画从提示词到模型出图》介绍了 Stable Diffusion AI 绘画工具及其使用技巧。书中内容分为两部分&#xff1a;“基础操作篇”&#xff0c;讲解了 SD 文生图、图生图、提示词、模型、ControlNet 插件等核心技术的应用&#xff0c;帮助读者快速从新手成长…

mysql仿照find_in_set写了一个replace_in_set函数,英文逗号拼接字符串指定替换

开发中使用mysql5.7版本数据库&#xff0c;对于英文逗号拼接的字符串&#xff0c;想要替换其中指定的字符串&#xff0c;找不到数据库函数支持&#xff0c;自己写了一个&#xff0c;实测好用&#xff01; /*类似find_in_set,按英文逗号拆分字段,找出指定的旧字符串,替换成新字…

Python库之retrying的高级用法深度解析

Python库之retrying的高级用法深度解析 概述 retrying 是一个Python库&#xff0c;它通过装饰器的方式简化了代码中重试机制的实现。本文将深入探讨retrying库的高级用法&#xff0c;帮助开发者更有效地利用它来增强程序的稳定性和健壮性。 安装 首先&#xff0c;确保你已经…

java中,怎样用最简单方法实现写word文档

在跨平台环境中实现写word时&#xff0c;如果用现成的库&#xff0c;就会涉及跨平台兼容性问题&#xff0c;比如在安卓与java中实现写word的功能。还有一个问题就是&#xff0c;完全用程序生成word文档&#xff0c;工作量较大。所以采用了模板替换的方法。 docx文档本质就是一…

深度学习之学习率调度器Scheduler介绍

调度器是深度学习训练过程中非常重要的一部分,它用于动态调整模型的学习率,从而提高训练效率和最终性能。 1. 为什么需要学习率调度器? 深度学习训练中,学习率是一个非常关键的超参数。合适的学习率可以确保模型快速收敛并获得良好的性能。 但是在训练过程中,最优的学习率会随…

算法与数据结构:二叉排序树与AVL树

ACM大牛带你玩转算法与数据结构-课程资料 本笔记属于船说系列课程之一&#xff0c;课程链接&#xff1a; 哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep66799?csourceprivate_space_class_null&spm_id_from333.999.0.0 你也可以选择购买『船说系列课程-年度会…

python判断字符串有无小数点有的话去掉小数点后面的数

python判断字符串有无小数点有的话去掉小数点后面的数 可以使用Python的字符串方法split()和strip()来判断和去除字符串中小数点后的数。 def remove_decimal_part(s):parts s.split(.)if len(parts) > 1:return parts[0]else:return s# 示例代码 s1 "123.456"…

javascript极简Date对象总结

new Date()和Date.now() new Date() 返回的是一个包含年月日时分秒的时间Date.now() 返回的是1970年1月1日0时0分0秒&#xff0c;到现在的时间毫秒数 时间格式化 let date new Date();let y date.getFullYear(); let m date.getMonth(); //返回值1真实月份 let d date.g…

# AI作画原理:生成对抗网络(GAN)的原理与应用

AI作画原理&#xff1a;生成对抗网络&#xff08;GAN&#xff09;的原理与应用 现在&#xff0c;AI已经可以画出非常逼真的图像了。那么&#xff0c;AI是怎么做到这一点的呢&#xff1f; 深度学习与生成对抗网络&#xff08;GAN&#xff09; AI画画的核心技术之一是深度学习&…

从java.util.Date到java.time.LocalDateTime:Java日期时间处理的现代进化

在深入探究Java日期时间管理的进化轨迹中&#xff0c;java.time.LocalDateTime与传统java.util.Date之间的差异凸显了现代软件工程对时间处理精准度与灵活性的更高要求。本文旨在通过详尽分析两者特性与实践案例&#xff0c;展现Java 8引入的日期时间API如何革新了这一基础而又…

java-开发验证码

### 3. 图像渲染 在上面的代码中&#xff0c;我们使用了 Graphics2D 类来绘制图像。这个类提供了很多绘图功能&#xff0c;包括绘制字符、线条、矩形等。在这个例子中&#xff0c;我们使用了 drawString 方法来绘制验证码字符串&#xff0c;并且使用 setFont 方法设置了字体和大…

日期转换运算工具类

一、日期转换运算 Java 中的日期常用转换 二、工具类 代码如下&#xff1a; package com.common.utils.time;import org.apache.commons.lang3.time.DateFormatUtils;import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.Sim…

关于MySQL数据库和数据表的基础

目录 一. 数据库的基础SQL 1. 创建数据库 2. 查看当前有哪些数据库 3. 选中数据库 4. 删除数据库 5. 小结 二. 数据表的基础SQL 1. 创建数据表 2. 查看当前数据库中有哪些表 3. 查看指定表的详细情况(查看表的结构) 4. 删除表 5. 小结 一. 数据库的基础SQL 1. 创建…