C語言數據結構-基于單鏈表實現通訊錄

文章目錄

  • 1 基礎要求
  • 2 通訊錄功能
    • 2.1 引入單鏈表的文件
    • 2.2 定義聯系人數據結構
    • 2.3 打開通訊錄
    • 2.4 保存數據后銷毀通訊錄
    • 2.5 添加聯系人
    • 2.6 刪除聯系人
    • 2.7 修改聯系人
    • 2.8 查找聯系人
    • 2.9 查看通訊錄
  • 3 通訊錄代碼展示
    • 3.1 SeqList_copy.h
    • 3.2 SeqList_copy.c
    • 3.3 Contact.h
    • 3.4 Contact.c
    • 3.5 test.c
    • 3.6 調試控制臺截圖


1 基礎要求

單鏈表,文件操作,結構體,二級指針
思路:利用上一篇博客-單鏈表,對單鏈表簡易修改,應用到通訊錄.

2 通訊錄功能

通訊錄只能能存100個人
用戶信息:名字,性別,年齡,電話,地址
通訊錄的展示,增,刪,改,查,找.
聯系人信息存儲

2.1 引入單鏈表的文件

為了顯現區別,筆者備份單鏈表的文件并且更名為SeqList_copy.hSeqList_copy.c
創建Contact.hContact.c以及測試代碼功能的test.c
test.cContact.c引用的頭文件都是Contact.hSeqList_copy.h
在這里插入圖片描述

2.2 定義聯系人數據結構

Contact.h頭文件中
定義名字最大長度,性別最大長度,電話最大長度,地址最大長度

#define NAME_MAX 120
#define SEX_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 50
//前置聲明
typedef struct SListNode contact;
//定義結構體
typedef struct ContactInfo
{ char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}ConInfo;

2.3 打開通訊錄

void ContactInit(contact** pcon)
{FILE* pf = fopen("Contact_Info.txt", "rb");	//二進制方式打開文件if (pf == NULL){perror("fopen error.\n");  //主動報錯,打開失敗return;}ConInfo info;//回顧一下fread //size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );//從流中讀取一個由count元素組成的數組,每個元素的大小為size字節,并將它們存儲在ptr指定的內存塊中。//流的位置指示器按讀取的總字節數前進。//如果成功讀取的總字節數為(size * count)while (fread(&info, sizeof(info), 1, pf)){SLPushBack(pcon, info);}printf("歷史數據已導入通訊錄\n");
}

2.4 保存數據后銷毀通訊錄

銷毀通訊錄之前一定要保存數據,不然2.3打開有存儲聯系人的通訊錄的作用就沒有了

void ContactSave(contact* con)
{FILE* pf = fopen("Contact_Info.txt", "wb");if (pf == NULL){perror("fopen error\n");return;}contact* cur = con;while (cur){fwrite(&(cur->data), sizeof(cur->data), 1, pf);cur = cur->next;}printf("成功保存通訊錄數據\n");
}void ContactDestory(contact** pcon)
{ContactSave(*pcon);SLDestory(pcon);
}

2.5 添加聯系人

使用單鏈表一節中尾插法添加數據

void ContactAdd(contact** pcon)
{ConInfo info;printf("請輸入添加聯系人姓名:\n");scanf("%s", &info.name);printf("請輸入添加聯系人性別:\n");scanf("%s", &info.sex);printf("請輸入添加聯系人年齡:\n");scanf("%d", &info.age);printf("請輸入添加聯系人電話:\n");scanf("%s", &info.tel);printf("請輸入添加聯系人地址:\n");scanf("%s", &info.addr);SLPushBack(pcon, info);printf("已添加聯系人數據\n");
}

2.6 刪除聯系人

借助FindByName()函數,找到索引.然而缺陷明顯,找到的索引是第一次出現的輸入的姓名,同樣,只能通過姓名查找

//我們這里通過姓名刪除聯系人
contact* FindByName(contact* con, char name[])
{contact* cur = con;while (cur){if (strcmp(cur->data.name,name) == 0){return cur;}cur = cur->next;}return NULL;
}void ContactDel(contact** pcon)
{char name[NAME_MAX];printf("請輸入你要刪除的聯系人姓名:\n");scanf("%s", name);contact* pos = FindByName(*pcon, name);if (pos == NULL){printf("該聯系人不存在\n");return;}SLErase(pcon, pos);printf("已刪除該聯系人\n");
}

2.7 修改聯系人

注意age年齡是int整型,其他四個數據結構都是數組,用scanf時,這里的數組相當于首元素地址,不用&.

void ContactModify(contact* con)
{char name[NAME_MAX];printf("請輸入你要修改的聯系人姓名:\n");scanf("%s", name);contact* pos = FindByName(con, name);if (pos == NULL){printf("該聯系人不存在\n");return;}printf("該聯系人姓名修改為:\n");scanf("%s", pos->data.name);	printf("該聯系人性別修改為:\n");scanf("%s", pos->data.sex);	printf("該聯系人年齡修改為:\n");scanf("%d", &pos->data.age);	printf("該聯系人電話修改為:\n");scanf("%s", pos->data.tel);printf("該聯系人地址修改為:\n");scanf("%s", pos->data.addr);printf("修改成功\n");
}

2.8 查找聯系人

同樣根據姓名查看詳細聯系人的通訊錄信息

void ContactFind(contact* con)
{char name[NAME_MAX];printf("請輸入你要查找的聯系人姓名:\n");scanf("%s", name);contact* pos = FindByName(con, name);if (pos == NULL){printf("該聯系人不存在\n");return;}printf("找到了\n");printf("%s %s %d %s %s\n",pos->data.name,pos->data.sex,pos->data.age,pos->data.tel,pos->data.addr);
}

2.9 查看通訊錄

第一次自己寫的時候,cur=cur->next放在while循環外面了.QAQ

void ContactShow(contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性別", "年齡", "電話", "地址");contact* cur = con;while (cur){printf("%s %s %d %s %s\n", cur->data.name, cur->data.sex, cur->data.age, cur->data.tel, cur->data.addr);cur = cur->next;}
}

3 通訊錄代碼展示

3.1 SeqList_copy.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include"Contact.h"//定義鏈表的結構
//typedef int SLDataType
typedef struct ContactInfo SLDataType;   //更改SLDataType的類型typedef struct SListNode
{SLDataType data;	//保存的數據struct SListNode* next;		//指針變量存放下一個節點的地址
}SLNode;//1 打印鏈表
void SLPrint(SLNode* phead);//2 尾插
void SLPushBack(SLNode** pphead, SLDataType x);
//3 頭插
void SLPushFront(SLNode** pphead, SLDataType x);//4 尾刪
void SLPopBack(SLNode** pphead);//5 頭刪
void SLPopFront(SLNode** pphead);//SLFind()找到要查找數據的下標
//找節點的函數這里傳一級實際上就可以了,因為不改變頭結點
//但是這里要寫二級指針,因為要保持接口一致性
//缺點:這個函數有一定的局限性,他找到數據x的下標是第一次出現的x的下標后,不會找后續的x的下標
SLNode* SLFind(SLNode** pphead, SLDataType x);//6 定點前插入數據
void SLInsert(SLNode** pphead, SLNode* pos, SLDataType x);//7 定點后插入數據
void SLInsertAfter(SLNode* pos, SLDataType x);//8 刪除pos節點
void  SLErase(SLNode** pphead, SLNode* pos);//9 刪除pos后的節點
void SLEraseAfter(SLNode* pos);//10 銷毀鏈表
void SLDestory(SLNode** pphead);

3.2 SeqList_copy.c

#include"SList_copy.h"//1 創建新的節點的函數
SLNode* SLBuyNode(SLDataType x)
{SLNode* node = (SLNode*)malloc(sizeof(SLNode));node->data = x;node->next = NULL;return node;
}//2 尾插
void SLPushBack(SLNode** pphead, SLDataType x)	//保存第一個節點的指針的地址
{assert(pphead);//創建一個節點SLNode* node = SLBuyNode(x);if (*pphead == NULL){*pphead = node;return;}//鏈表不為空,找尾SLNode* pcur = *pphead;while (pcur->next)//相當于pcur->next!=NULL{pcur = pcur->next;}pcur->next = node;
}//3 頭插
void SLPushFront(SLNode** pphead, SLDataType x)
{assert(pphead);SLNode* node = SLBuyNode(x);//新結點跟頭結點連接起來node->next = *pphead;//讓新節點成為頭結點*pphead = node;
}//4 尾刪
void SLPopBack(SLNode** pphead)
{assert(pphead);assert(*pphead);	//第一個節點不能為空//判斷只有一個結點的情況if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;return;}//找到尾節點和尾節點的前一個節點SLNode* pre = NULL;SLNode* ptail = *pphead;while (ptail->next){pre = ptail;ptail = ptail->next;}//pre的next指針不指向ptail,而是指向ptail的下一個節點//pre->next = NULL;pre->next = ptail->next;//因為在SLPrint(SLNode* phead)函數中有判斷節點是否為空while (pcur),所以置空free(ptail);ptail = NULL;}//5 頭插
void SLPopFront(SLNode** pphead)
{assert(pphead);assert(*pphead);	//第一個節點不能為空SLNode* del = *pphead;*pphead = (*pphead)->next;free(del);del = NULL;
}//6 定點前插入數據
void SLInsert(SLNode** pphead, SLNode* pos, SLDataType x)
{assert(pphead);assert(pos);	//pos不能為空assert(*pphead);  //NULL前插入數據是荒謬的,所以assert第一個節點SLNode* node = SLBuyNode(x);//當只有一個結點(pos就是第一個節點)//if (((*pphead)->next) == NULL||pos==*pphead),可以簡化成以下代碼if (pos == *pphead) {node->next = *pphead;*pphead = node;return;}//找到pos的前一個節點SLNode* pre = *pphead;while (pre->next != pos){pre = pre->next;}//處理pre node pos的位置node->next = pos;pre->next = node;
}//7 定點后插入數據
void SLInsertAfter(SLNode* pos, SLDataType x)
{assert(pos);SLNode* node = SLBuyNode(x);node->next = pos->next;pos->next = node;
}//8 刪除pos節點
void SLErase(SLNode** pphead, SLNode* pos)
{assert(*pphead);assert(pphead);assert(pos);//pos是頭結點if (pos == *pphead){*pphead = (*pphead)->next;free(pos);return;}//pos不是頭結點,找pos的前一個節點SLNode* pre = *pphead;while (pre->next != pos){pre = pre->next;}pre->next = pos->next;free(pos);pos = NULL;   //代碼規范
}//9 刪除pos后的節點
void SLEraseAfter(SLNode* pos)
{//刪除pos之后的節點也不能空assert(pos && pos->next);SLNode* del = pos->next;pos->next = del->next;free(del);
}void SLDestory(SLNode** pphead)
{assert(pphead);SLNode* pcur = *pphead;while (pcur){SLNode* next = pcur->next;free(pcur);pcur = next;}//頭結點記得置空*pphead = NULL;
}

3.3 Contact.h

#pragma once
//創建保存聯系人數據的結構
#define NAME_MAX 120
#define SEX_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 50typedef struct ContactInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}ConInfo;
//前置聲明
typedef struct SListNode contact;//1.打開通訊錄
void ContactInit(contact** pcon);//2.保存數據后銷毀通訊錄
void ContactDestory(contact** pcon);//3.添加聯系人
void ContactAdd(contact** pcon);//4.刪除聯系人
void ContactDel(contact** pcon);//5.修改聯系人
void ContactModify(contact* con);//6.查找聯系人
void ContactFind(contact* pcon);//7.查看通訊錄
void ContactShow(contact* pcon);

3.4 Contact.c

#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"
#include"SList_copy.h"//1.打開通訊錄
void ContactInit(contact** pcon)
{FILE* pf = fopen("Contact_Info.txt", "rb");if (pf == NULL){perror("fopen error.\n");  //主動報錯,打開失敗return;}ConInfo info;//回顧一下fread //size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );//從流中讀取一個由count元素組成的數組,每個元素的大小為size字節,并將它們存儲在ptr指定的內存塊中。//流的位置指示器按讀取的總字節數前進。//如果成功讀取的總字節數為(size * count)while (fread(&info, sizeof(info), 1, pf)){SLPushBack(pcon, info);}printf("歷史數據已導入通訊錄\n");
}void ContactSave(contact* con)
{FILE* pf = fopen("Contact_Info.txt", "wb");if (pf == NULL){perror("fopen error\n");return;}contact* cur = con;while (cur){fwrite(&(cur->data), sizeof(cur->data), 1, pf);cur = cur->next;}printf("成功保存通訊錄數據\n");
}void ContactDestory(contact** pcon)
{ContactSave(*pcon);SLDestory(pcon);
}void ContactAdd(contact** pcon)
{ConInfo info;printf("請輸入添加聯系人姓名:\n");scanf("%s", &info.name);printf("請輸入添加聯系人性別:\n");scanf("%s", &info.sex);printf("請輸入添加聯系人年齡:\n");scanf("%d", &info.age);printf("請輸入添加聯系人電話:\n");scanf("%s", &info.tel);printf("請輸入添加聯系人地址:\n");scanf("%s", &info.addr);SLPushBack(pcon, info);printf("已添加聯系人數據\n");
}//我們這里通過姓名刪除聯系人
contact* FindByName(contact* con, char name[])
{contact* cur = con;while (cur){if (strcmp(cur->data.name,name) == 0){return cur;}cur = cur->next;}return NULL;
}void ContactDel(contact** pcon)
{char name[NAME_MAX];printf("請輸入你要刪除的聯系人姓名:\n");scanf("%s", name);contact* pos = FindByName(*pcon, name);if (pos == NULL){printf("該聯系人不存在\n");return;}SLErase(pcon, pos);printf("已刪除該聯系人\n");
}void ContactModify(contact* con)
{char name[NAME_MAX];printf("請輸入你要修改的聯系人姓名:\n");scanf("%s", name);contact* pos = FindByName(con, name);if (pos == NULL){printf("該聯系人不存在\n");return 1;}printf("該聯系人姓名修改為:\n");scanf("%s", pos->data.name);	printf("該聯系人性別修改為:\n");scanf("%s", pos->data.sex);	printf("該聯系人年齡修改為:\n");scanf("%d", &pos->data.age);	printf("該聯系人電話修改為:\n");scanf("%s", pos->data.tel);printf("該聯系人地址修改為:\n");scanf("%s", pos->data.addr);printf("修改成功\n");
}void ContactFind(contact* con)
{char name[NAME_MAX];printf("請輸入你要查找的聯系人姓名:\n");scanf("%s", name);contact* pos = FindByName(con, name);if (pos == NULL){printf("該聯系人不存在\n");return;}printf("找到了\n");printf("%s %s %d %s %s\n",pos->data.name,pos->data.sex,pos->data.age,pos->data.tel,pos->data.addr);
}void ContactShow(contact* con)
{printf("%s %s %s %s %s\n", "姓名", "性別", "年齡", "電話", "地址");contact* cur = con;while (cur){printf("%s %s %d %s %s\n", cur->data.name, cur->data.sex, cur->data.age, cur->data.tel, cur->data.addr);cur = cur->next;}
}

3.5 test.c

test()我封裝了五個函數,都是用來測試通訊錄功能的,調試結束后,就將函數封裝在一起,寫一個菜單完成通訊錄功能.

#define _CRT_SECURE_NO_WARNINGS
#include"Contact.h"
#include"SList_copy.h"void test1()
{contact *pcontact=NULL;ContactInit(&pcontact);
}void test2()
{contact* pcontact = NULL;ContactInit(&pcontact);ContactAdd(&pcontact);ContactDel(&pcontact);ContactShow(pcontact);}void test3()
{contact* pcontact = NULL;ContactInit(&pcontact);ContactShow(pcontact);ContactAdd(&pcontact);ContactShow(pcontact);ContactDel(&pcontact);ContactShow(pcontact);
}
void test4()
{contact* pcontact = NULL;ContactInit(&pcontact);ContactAdd(&pcontact);ContactAdd(&pcontact);ContactShow(pcontact);ContactFind(pcontact);ContactShow(pcontact);}void test5()
{contact* pcontact = NULL;ContactInit(&pcontact);ContactAdd(&pcontact);ContactShow(pcontact);ContactModify(pcontact);ContactShow(pcontact);ContactDestory(&pcontact);
}void menu()
{printf("\n");printf("****************************\n");printf("****************************\n");printf("************通訊錄***********\n");printf("*********1.添加聯系人********\n");printf("*********2.刪除聯系人********\n");printf("*********3.修改聯系人********\n");printf("*********4.查找聯系人********\n");printf("*********5.查看通訊錄********\n");printf("*********0.退  出************\n");printf("****************************\n");printf("****************************\n");
}int main()
{//test1();//test2();//test3();//test4();//test5();int op = 0;contact* con=NULL;ContactInit(&con);do {menu();printf("請選擇:\n");scanf("%d", &op);switch (op){case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(con);break;case 4:ContactFind(con);break;case 5:ContactShow(con);break;case 0:printf("退出了哈\n");break;default:printf("輸入錯誤\n");break;}} while (op!=0);ContactDestory(&con);return 0;
}

3.6 調試控制臺截圖

在這里插入圖片描述

這里忘記啥問題了,一轉眼就忘了
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

在多次語法錯誤,死循環,輸出亂碼,代碼崩潰后,終于簡單完成通訊錄的功能!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210357.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210357.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210357.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

模塊化機房在大數據時代的角色:高效、可擴展的數據存儲和處理平臺

隨著大數據時代的到來&#xff0c;數據已經成為企業競爭的核心資源。然而&#xff0c;傳統的數據中心已經無法滿足現代業務的需求&#xff0c;尤其是在數據存儲和處理方面。模塊化機房作為一種新型的數據中心建設模式&#xff0c;具有高效、可擴展等優勢&#xff0c;逐漸成為大…

PyCharm編輯器結合Black插件,輕松實現Python代碼格式化

大家好&#xff0c;使用Black對Python代碼進行格式化&#xff0c;可使代碼看起來更美觀。但是&#xff0c;隨著項目規模不斷變大&#xff0c;對每個文件運行Black變得很繁瑣。本文就來介紹在PyCharm中實現這一目標的方法。 1.安裝Black 首先&#xff0c;在虛擬環境中安裝Blac…

二叉樹的鋸齒形層序遍歷[中等]

優質博文&#xff1a;IT-BLOG-CN 一、題目 給你二叉樹的根節點 root &#xff0c;返回其節點值的 鋸齒形層序遍歷 。&#xff08;即先從左往右&#xff0c;再從右往左進行下一層遍歷&#xff0c;以此類推&#xff0c;層與層之間交替進行&#xff09;。 示例 1&#xff1a; 輸…

認識線程和創建線程

目錄 1.認識多線程 1.1線程的概念 1.2進程和線程 1.2.1進程和線程用圖描述關系 1.2.2進程和線程的區別 1.3Java 的線程和操作系統線程的關系 2.創建線程 2.1繼承 Thread 類 2.2實現 Runnable 接口 2.3匿名內部類創建 Thread 子類對象 2.4匿名內部類創建 Runnable 子類對…

使用貝葉斯網絡檢測因果關系,提升模型效果更科學(附Python代碼)

雖然機器學習技術可以實現良好的性能&#xff0c;但提取與目標變量的因果關系并不直觀。換句話說&#xff0c;就是&#xff1a;哪些變量對目標變量有直接的因果影響&#xff1f; 機器學習的一個分支是貝葉斯概率圖模型(Bayesian probabilistic graphical models)&#xff0c;也…

【Com通信】Com模塊詳細介紹

目錄 前言 1. Com模塊功能介紹 2.關鍵概念理解 3.功能詳細設計 3.1 Introduction 3.2 General Functionality 3.2.1 AUTOSAR COM basis 3.2.2 Signal Values 3.2.3 Endianness Conversion and Sign Extension 3.2.4 Filtering 3.2.5 Signal Gateway 3.3 Normal Ope…

2.2 網絡多線程(私聊、群發、發送文件、推送新聞、離線留言)

文章目錄 一、私聊1.1 分析1.2 客戶端1.2.1 MessageClientService 私聊類1.2.2 ClientConnectServerThread 線程類 1.3 服務端1.3.1 ServerConnectClientThread 線程類 1.4功能演示 二、群發消息2.1 分析2.2 客戶端2.2.1 MessageClientService類2.2.2 ClientConnectServerThrea…

1.1.1.多線程的發展--對cpu性能的壓榨史

一.壓榨歷史 1.單進程人工切換。紙帶機。只能解決簡單的數學問題。 2.單道批處理。多進程批處理。多個任務批量執行。解決手動操作時需要人工切換作業導致的系統利用率低的問題 3.多進程并行處理。把程序寫在不同的內存位置來回切換。當一個作業在等待I/O處理時&#xff0c;…

C語言-函數STRCPY

strcpy char *strcpy(char *restrict dst, const char *restrict src);把src的字符串拷貝到dst restrict表明src和dst不重疊&#xff08;C99&#xff09; 返回dst 為了能鏈起代碼來 復制一個字符串 char dst (char)malloc(strlen(src) 1); strcpy(dst, src);

從單向鏈表中刪除指定值的節點

輸入一個單向鏈表和一個節點的值&#xff0c;從單向鏈表中刪除等于該值的節點&#xff0c;刪除后如果鏈表中無節點則返回空指針。 鏈表的值不能重復。構造過程&#xff0c;例如輸入一行數據為:6 2 1 2 3 2 5 1 4 5 7 2 2則第一個參數6表示輸入總共6個節點&#xff0c;第二個參數…

通過仿真理解完整的陣列信號噪聲模型

概要 噪聲對無線電設備的信號接收會造成影響,是通信、雷達、導航、遙感等工程應用領域中的關鍵考慮因素。通常認為陣列合成能夠提升信噪比,但忽略了這一論斷的前提,即不同通道引入的噪聲互不相關。但實際應用中,接收的噪聲不僅僅包含信道引入的不相關噪聲,還包含從外界環…

1-6、編程語言排行榜

語雀原文鏈接 https://www.tiobe.com/tiobe-index/

IntelliJ IDEA創建一個Maven項目

在IDEA中創建Maven項目&#xff0c;前提是已經安裝配置好Maven環境 。 本文主要使用的是IntelliJ IDEA 2022.2.1 (Community Edition) 1.創建一個新project:File>Project 2.修改Maven配置&#xff1a;File>Settings>搜索maven 創建好的工程如下&#xff1a; src/main…

使用NanoPi NEO4進行rtsp拉流

使用系統&#xff1a;FriendlyDesktop系統 使用python進行編程&#xff0c;分別使用opencv與ffmpeg進行功能實現&#xff0c;折騰了挺長時間&#xff0c;代碼很簡單&#xff0c;主要是環境搭建。主要是python、opencv-python、ffmpeg-python、numpy之間的版本兼容&#xff0c;…

Chart 8 內核優化

文章目錄 前言8.1 內核融合和拆分8.2 編譯選項8.3 Conformant&#xff08;規范&#xff09; vs. fast vs. native math functions8.4 Loop unrolling8.5 避免分支發散8.6 Handle image boundaries8.7 Avoid the use of size_t8.8 通用 vs. 具名內存地址空間8.9 Subgroup8.10 Us…

七個常用<python裝飾器>---足夠改進代碼質量 (保姆詳解)

前言: 寫代碼嘛&#xff0c;關鍵是得讓它既好用又好看&#xff0c;這不&#xff0c;Python裝飾器就擺在那兒。咱們程序員有時也得有那么點藝術家的腔調&#xff1a;講求效率&#xff0c;追求代碼的簡潔優雅&#xff0c;偶爾還得裝裝X&#xff0c;不是嗎&#xff1f; 翻開人家…

SpringSecurity6 | 自定義認證規則

?作者簡介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;熱愛Java后端開發者&#xff0c;一個想要與大家共同進步的男人&#x1f609;&#x1f609; &#x1f34e;個人主頁&#xff1a;Leo的博客 &#x1f49e;當前專欄&#xff1a; Java從入門到精通 ?特色專欄&#xf…

移相干涉技術1-多種干涉條紋仿真模擬生成(原理轉載+代碼實現 包括模擬生成干涉條紋圖)

過去的干涉測量技術是通過人的肉眼或者相機拍攝&#xff0c;來直觀判斷干涉圖中條紋特征進而完成測量&#xff0c;該方法的不穩定因素&#xff08;比如人的主觀意志&#xff09;很多&#xff0c;其精度誤差在/10左右38]&#xff1b;現代干涉測量技術通過將電子技術、計算機技術…

智能優化算法應用:基于廚師算法無線傳感器網絡(WSN)覆蓋優化 - 附代碼

智能優化算法應用&#xff1a;基于廚師算法無線傳感器網絡(WSN)覆蓋優化 - 附代碼 文章目錄 智能優化算法應用&#xff1a;基于廚師算法無線傳感器網絡(WSN)覆蓋優化 - 附代碼1.無線傳感網絡節點模型2.覆蓋數學模型及分析3.廚師算法4.實驗參數設定5.算法結果6.參考文獻7.MATLAB…

代碼隨想錄-刷題第二十一天

530.二叉搜索樹的最小絕對差 題目鏈接&#xff1a;530. 二叉搜索樹的最小絕對差 思路&#xff1a;二叉搜索樹的中序遍歷是有序的。根據二叉搜索樹的這個特性來解題。 class Solution {// 同樣利用二叉樹中序遍歷是一個有序數組。private List<Integer> list new Arra…