從淘寶推薦到微信搜索:查找算法如何支撐億級用戶——動畫可視化

?本篇技術博文摘要 🌟

  • 本文通過動畫可視化深入解析數據結構中的核心查找算法,從基礎概念到高階應用,全面覆蓋順序查找、折半查找、分塊查找、B樹/B+樹及散列查找的核心原理與實現細節。文章以動態演示為核心工具,直觀展現算法執行過程與數據結構演化,幫助讀者突破抽象理論難點。

  • 內容核心

    • 基礎算法

      • 順序查找:從暴力遍歷到哨兵優化,結合判定樹分析ASL(平均查找長度),探討有序表場景下的效率提升策略。

      • 折半查找:通過二分思想與判定樹模型,解析有序數據的高效檢索邏輯,并給出代碼實現與時間復雜度推導。

    • 進階索引結構

      • 分塊查找:融合順序與折半查找優勢,分析塊劃分對效率的影響。

      • B樹與B+樹:從多叉查找樹的平衡規則出發,動態演示插入、刪除操作如何維持樹結構穩定;對比B+樹的特性(如葉子節點鏈表),闡釋其在數據庫索引中的核心地位。

    • 散列查找與沖突解決

      • 詳解哈希函數設計原則(如除留余數法),通過動畫模擬拉鏈法、開放定址法、再散列法的沖突處理過程,揭示哈希表動態擴容與數據分布規律。

引言 📘

  • 在這個變幻莫測、快速發展的技術時代,與時俱進是每個IT工程師的必修課。
  • 我是盛透側視攻城獅,一名什么都會一丟丟的網絡安全工程師,也是眾多技術社區的活躍成員以及多家大廠官方認可人員,希望能夠與各位在此共同成長。

上節回顧

目錄

本篇技術博文摘要 🌟

引言 📘

上節回顧

7.2數據結構與算法之查找算法題目

7.2.1題:

?

代碼算法實現思路:

核心代碼實現:

7.2.2題:?

代碼算法實現思路:

核心代碼實現:

注意:

7.2.3題:?

代碼算法實現思路:

核心代碼實現:

?

?7.3?.數據結構與算法之樹形查找算法題

7.3.1題:?

代碼算法實現思路:

核心代碼實現:

?7.3.2題:?

代碼算法實現思路:

核心代碼實現:

?7.3.3題:?

代碼算法實現思路:

核心代碼實現:

?7.3.4題:?

代碼算法實現思路:

核心代碼實現:

?7.3.5題:?

代碼算法實現思路:

核心代碼實現:

補充:

?7.3.6題:?

代碼算法實現思路:

核心代碼實現:

補充:

歡迎各位彥祖與熱巴暢游本人專欄與技術博客

你的三連是我最大的動力

點擊??指向的專欄名即可閃現


7.2數據結構與算法之查找算法題目

7.2.1題:

?

  • ?出折半查找的遞歸算法。初始調用時,low為1,high為ST.length。?

代碼算法實現思路:

  • 根據查找的起始位置和終止位置,將查找序列一分為二,判斷所查找的關鍵字在哪一部分,然后用新的序列的起始位置和終止位置遞歸求解。

核心代碼實現:

typedef struct{            //查找表的數據結構  ElemType   *elem;      //存儲空間基址,建表時按實際長度分配,0號留空  int        length;     //表的長度  
} SSTable;  
int BinSearchRec(SSTable ST, ElemType key, int low, int high){  if(low>high)  return 0;  mid=(low+high)/2;              //取中間位置  if(key>ST.elem[mid])           //向后半部分查找  BinSearchRec(ST,key,mid+1,high);  else if(key<ST.elem[mid])  //向前半部分查找  BinSearchRec(ST,key,low,mid-1);  else                         //查找成功  return mid;  
}

7.2.2題:?

  • ?線性表中各結點的檢索概率不等時,可用如下策略提高順序檢索的效率:
  • 若找到指定的結點,則將該結點和其前驅結點(若存在)交換,使得經常被檢索的結點盡量位于表的前端。
  • 試設計在順序結構和鏈式結構的線性表上實現上述策略的順序檢索算法。

代碼算法實現思路:

  • 檢索時可先從表頭開始向后順序掃描,若找到指定的結點,則將該結點和其前趨結點(若存在)交換。

核心代碼實現:

int SeqSrch(RcdType R[], ElemType k) {  //順序查找線性表,找到后和其前面的元素交換  int i=0;  while ((R[i].key !=k) && (i<n))  i++;                          //從前向后順序查找指定結點  if (i<n&&i>0) {                   //若找到,則交換  temp=R[i]; R[i]=R[i-1]; R[i-1]=temp;  return --i;                   //交換成功,返回交換后的位置  }  else return -1;                   //交換失敗  
}

注意:

  • 鏈表方式實現的基本思想與上述思想相似,但要注意用鏈表實現時,在交換兩個結點之前需要保存指向前一結點的指針。

7.2.3題:?

代碼算法實現思路:

  • 從矩陣A的右上角(最右列)開始比較,若當前元素小于目標值,則向下尋找下一個更大的元素;
  • 若當前元素大于目標值,則從右往左依次比較,若目標值存在,則只可能在該行中。

核心代碼實現:

bool findkey(int A[][], int n, int k) {  int i=0, j=n-1;  while (i<n&&j>=0) {                //離開邊界時查找結束  if (A[i][j]==k) return true;  //查找成功  else if (A[i][j]>k) j--;      //向左移動,在該行內尋找目標值  else i++;                      //向下移動,查找下一個更大的元素  }  return false;                      //查找失敗  
}
  • 比較次數不超過2n次,時間復雜度為O(n);空間復雜度為O(1)。

?7.3?.數據結構與算法之樹形查找算法題

7.3.1題:?

  • 試編寫一個算法,判斷給定的二叉樹是否是二叉排序樹。

代碼算法實現思路:

  • 對二叉排序樹來說,其中序遍歷序列為一個遞增有序序列。
  • 因此,對給定的二叉樹進行中序遍歷,若始終能保持前一個值比后一個值小,則說明該二叉樹是一棵二叉排序樹。?

核心代碼實現:

KeyType predt=-32767;              //predt 為全局變量,保存當前結點中序前驅的值,初值為-∞  
int JudgeBST(BiTree bt) {  int b1,b2;  if(bt==NULL)                     //空樹  return 1;  else{  b1=JudgeBST(bt->lchild);     //判斷左子樹是否是二叉排序樹  if(b1==0||predt>=bt->data)  //若左子樹返回值為 0 或前驅大于或等于當前結點  return 0;                //則不是二叉排序樹  predt=bt->data;              //保存當前結點的關鍵字  b2=JudgeBST(bt->rchild);     //判斷右子樹  return b2;                   //返回右子樹的結果  }  
}

?7.3.2題:?

  • ?設計一個算法,求出指定結點在給定二叉排序樹中的層次。

代碼算法實現思路:

  • 設二叉樹采用二叉鏈表存儲結構。
  • 在二叉排序樹中,查找一次就下降一層。
  • 因此,查找該結點所用的次數就是該結點在二叉排序樹中的層次。
  • 采用二叉排序樹非遞歸查找算法,用n保存查找層次,每查找一次,n就加1,直到找到相應的結點。

核心代碼實現:

int level(BiTree bt,BSTNode *p){  int n=0;                          //統計查找次數  BiTree t=bt;  if(bt!=NULL){  n++;  }  while (t->data!=p->data) {  if (p->data<t->data)         //在左子樹中查找  t=t->lchild;  else  t=t->rchild;             //在右子樹中查找  n++;                         //層次加 1  }  return n;  
}

?7.3.3題:?

  • 用二叉樹遍歷的思想編寫一個判斷二叉樹是否是平衡二叉樹的算法。?

代碼算法實現思路:

  • 設置二叉樹的平衡標記balance,以標記返回二叉樹bt是否為平衡二叉樹,若為平衡二叉樹,則返回1,否則返回0;h為二叉樹 bt 的高度。采用后序遍歷的遞歸算法:
    • 1)若 bt為空,則高度為0,balance=1。
    • 2)若 bt僅有根結點,則高度為1,balance=1。
    • 3)否則,對bt的左、右子樹執行遞歸運算,返回左、右子樹的高度和平衡標記,bt 的高度為最高子樹的高度加1。若左、右子樹的高度差大于1,則balance=0;若左、右子樹的高度差小于或等于1,且左、右子樹都平衡時,balance=1,否則 balance=0。

核心代碼實現:

void Judge_AVL(BiTree bt, int &balance, int &h) {  int bl=0, br=0, hl=0, hr=0;             //左、右子樹的平衡標記和高度  if (bt==NULL) {                          //空樹,高度為 0  h=0;  balance=1;  }  else if (bt->lchild==NULL&&bt->rchild==NULL) { //僅有根結點,則高度為 1  h=1;  balance=1;  }  else {  Judge_AVL(bt->lchild, bl, hl);      //遞歸判斷左子樹  Judge_AVL(bt->rchild, br, hr);      //遞歸判斷右子樹  h=(hl>hr?hl:hr)+1;  if (abs(hl-hr)<2)  //若子樹高度差的絕對值<2,則看左、右子樹是否都平衡  balance=bl&&br; //&&為邏輯與,即左、右子樹都平衡時,二叉樹平衡  else  balance=0;  }  
}

?7.3.4題:?

  • ?設計一個算法,求出給定二叉排序樹中最小和最大的關鍵字。

代碼算法實現思路:

  • 一棵二叉排序樹中,最左下結點即為關鍵字最小的結點,最右下結點即為關鍵字最大的結點,本算法只要找出這兩個結點即可,而不需要比較關鍵字。

核心代碼實現:

KeyType MinKey(BSTNode *bt) {  while (bt->lchild!=NULL)  bt=bt->lchild;  return bt->data;  
}  
KeyType MaxKey(BSTNode *bt) {  //求出二叉排序樹中最大關鍵字結點  while (bt->rchild!=NULL)  bt=bt->rchild;  return bt->data;  
}

?7.3.5題:?

  • ?設計一個算法,從大到小輸出二叉排序樹中所有值不小于k的關鍵字。

代碼算法實現思路:

  • 由二叉排序樹的性質可知,右子樹中所有的結點值均大于根結點值,左子樹中所有的結點值均小于根結點值。
  • 為了從大到小輸出,先遍歷右子樹,再訪問根結點,后遍歷左子樹。

核心代碼實現:

void Output(BSTNode *bt, KeyType k) {  //本算法從大到小輸出二叉排序樹中所有值不小于k的關鍵字  if (bt==NULL)  return;  if (bt->rchild!=NULL)  Output(bt->rchild, k);      //遞歸輸出右子樹結點  if (bt->data>=k)  printf("%d", bt->data);     //只輸出大于或等于k的結點值  if (bt->lchild!=NULL)  Output(bt->lchild, k);      //遞歸輸出左子樹的結點  
}

補充:

  • 本題也可采用中序遍歷加輔助棧的方法實現。

?7.3.6題:?

代碼算法實現思路:

  • 所以我們可以對左右子樹的搜索采用相同的規則,

核心代碼實現:

BSTNode *Search_Small(BSTNode*t, int k) {  //在以t為根的子樹上尋找第k小的元素,返回其所在結點的指針。k從1開始計算  //在樹結點中增加一個count數據成員,存儲以該結點為根的子樹的結點個數  if(k<1||k>t->count) return NULL;  if(t->lchild==NULL) {  if(k==1) return t;  else return Search_Small(t->rchild,k-1);  }  else{  if(t->lchild->count==k-1) return t;  if(t->lchild->count>k-1) return Search_Small(t->lchild,k);  if(t->lchild->count<k-1)  return Search_Small(t->rchild, k-(t->lchild->count+1));  }  
}

補充:

  • 最大查找長度取決于樹的高度。
  • 由于二叉排序樹是隨機生成的,其高度應是O(log2n),算法的時間復雜度為O(log2n)。

??

歡迎各位彥祖與熱巴暢游本人專欄與技術博客

你的三連是我最大的動力

點擊??指向的專欄名即可閃現

??滲透終極之紅隊攻擊行動?

??動畫可視化數據結構與算法

???永恒之心藍隊聯縱合橫防御

??華為高級網絡工程師

??華為高級防火墻防御集成部署

????未授權訪問漏洞橫向滲透利用

???逆向軟件破解工程

??MYSQL REDIS 進階實操

??紅帽高級工程師?

??紅帽系統管理員

???HVV 全國各地面試題匯總?

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

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

相關文章

圖像正向扭曲反向扭曲

在圖像處理領域&#xff0c;正向扭曲&#xff08;Forward Warping&#xff09;和反向扭曲&#xff08;Backward Warping&#xff09;是兩種核心的圖像坐標映射與像素重采樣技術&#xff0c;核心區別在于“像素映射的方向”——是從“原始圖像”到“目標圖像”&#xff0c;還是從…

【C語言】 第三課 函數與棧幀機制詳解

1 函數的基本概念 在C語言中&#xff0c;函數是程序的基本執行單元。一個函數的定義包括返回類型、函數名、參數列表和函數體。例如&#xff1a; int add(int x, int y) { // 函數定義int z x y;return z; }在使用函數前&#xff0c;通常需要聲明&#xff08; declaration&am…

多個大體積PDF文件怎么按數量批量拆分成多個單獨文件

在現代社會中&#xff0c;電子文檔在我們的身邊無所不在&#xff0c;而PDF文件時我們日常接觸非常多的文檔類型之一。PDF由于格式穩定、兼容性好&#xff0c;因此經常被用于各行各業。但是&#xff0c;我們平時在制作或搜集PDF文件時&#xff0c;文件太大&#xff0c;傳輸和分享…

ansible-角色

角色 一、利用角色構造ansible playbook 隨著開發更多的playbook&#xff0c;會發現有很多機會重復利用以前編寫的playbook中的代碼。或許&#xff0c;一個用于為某一應用配置MySQL數據庫的play可以改變用途。通過利用不同的主機名、密碼和用戶來為另一個應用配置MySQL數據庫。…

git命令行打patch

在 Git 里打 patch&#xff08;補丁&#xff09;其實就是把某些提交的改動導出來&#xff0c;生成一個 .patch 文件&#xff0c;方便別人用 git apply 或 git am 打進代碼里。&#x1f539; 常用方式1. 基于提交導出 patch導出最近一次提交&#xff1a;git format-patch -1 HEA…

文華財經多空提示指標公式 變色K線多空明確指標 文華wh6贏順多空買賣提示指標

XX:240C;YY:MA(C,1);A1:POW(XX,2)/360-POW(YY,2)/260;A5:EMA2(EMA2(A1,20),5),LINETHICK2;A6:A5*0.9999,COLORSTICK;A20:EMA2(EMA2(A5,20),5),LINETHICK2;A60:EMA2(EMA2(A20,20),5),LINETHICK2;支撐:HHV(A5,30),COLORRED;天數:BARSSINCE(A5HHV(A5,0));YL:REF(A5,1)2.79-天數*0.…

記錄一個防重Toast

當我們已經對某個按鈕做了防暴力點擊&#xff0c;但是依然在業務上有些復雜交互的情況&#xff0c;需要我們封裝一個防重Toast。針對這類情況&#xff0c;可以直接使用下面的showDebouncedToastdata class ToastInfo(val id: Any? null,val command: MediaCommandDebouncer.M…

在線測評系統---第n天

主要完成了退出登錄前后的代碼的實現&#xff0c;以及題目列表的查詢1.退出登錄前端引入了全局前置守衛&#xff0c;如果cookie里面沒有token則直接跳轉到login頁面&#xff1b;有則直接跳轉到layout頁面&#xff0c;無需重新登錄后端接收到退出登錄&#xff0c;將token置為無效…

機器學習從入門到精通 - 卷積神經網絡(CNN)實戰:圖像識別模型搭建指南

機器學習從入門到精通 - 卷積神經網絡(CNN)實戰&#xff1a;圖像識別模型搭建指南 各位&#xff0c;是不是覺得那些能認出照片里是貓還是狗、是停車標志還是綠燈的AI酷斃了&#xff1f;今天咱們就擼起袖子&#xff0c;親手搭建一個這樣的圖像識別模型&#xff01;別擔心不需要你…

python sqlalchemy模型的建立

SQLAlchemy 是一個功能強大的 Python SQL 工具包和對象關系映射&#xff08;ORM&#xff09;庫&#xff0c;用于管理和操作關系數據庫。它為 Python 開發者提供了一種用 Python 對象來運行和管理 SQL 數據庫的方式。 目錄 SQLAlchemy 的兩個核心組成部分 SQLAlchemy 的主要功…

Rust中使用RocksDB索引進行高效范圍查詢的實踐指南

在當今海量數據處理場景下,高效的范圍查詢能力成為許多系統的關鍵需求。RocksDB作為一款高性能的嵌入式鍵值存儲引擎,其獨特的LSM樹結構和索引設計為范圍查詢提供了底層支持。本文將深入探討如何在Rust中利用RocksDB的特性來實現高效范圍查詢,從鍵的設計原則到迭代器的工程實…

怎么做到這一點:讓 Agent 可以像人類一樣 邊聽邊想、邊說,而不是“等一句話 → 一次性返回”

要實現“邊聽邊想、邊說”&#xff0c;核心是把整條鏈路做成全雙工、分片流式、可中斷的流水線&#xff1a; ASR 連續吐字 →&#xff08;短緩沖&#xff09;→ LLM 連續出 token&#xff08;可搶斷&#xff09;→ TTS 連續合成并播放&#xff08;可打斷/續播&#xff09;。 下…

Ubuntu 22.04 網絡服務安裝配置

Ubuntu 22.04 網絡服務安裝配置 一鍵安裝所有服務 # 更新系統 sudo apt update# 安裝所有服務 sudo apt install -y openssh-server vsftpd telnetd inetutils-inetd ftp telnet# 啟動所有服務 sudo systemctl start ssh vsftpd inetutils-inetd sudo systemctl enable ssh vsf…

【Unity知識分享】Unity實現全局監聽鍵鼠調用

1、實現該功能前&#xff0c;優先學習Unity接入dll調用Window系統接口教程 【Unity知識分享】Unity接入dll調用Window系統接口 2、初始化動態連接庫后&#xff0c;進行腳本功能實現 2.1 創建腳本KeyBoardHook.h和KeyBoardHook.cpp&#xff0c;實現功能如下 KeyBoardHook.h …

深度學習篇---MNIST:手寫數字數據集

下面我將詳細介紹使用 PyTorch 處理 MNIST 手寫數字數據集的完整流程&#xff0c;包括數據加載、模型定義、訓練和評估&#xff0c;并解釋每一行代碼的含義和注意事項。整個流程可以分為五個主要步驟&#xff1a;準備工作、數據加載與預處理、模型定義、模型訓練和模型評估。# …

k8s集群搭建(二)-------- 集群搭建

安裝 containerd 需要在集群內的每個節點上都安裝容器運行時&#xff08;containerd runtime&#xff09;&#xff0c;這個軟件是負責運行容器的軟件。 1. 啟動 ipv4 數據包轉發 # 設置所需的 sysctl 參數&#xff0c;參數在重新啟動后保持不變 cat <<EOF | sudo tee …

【Docker】P1 前言:容器化技術發展之路

目錄容器發展之路物理服務器時代&#xff1a;一機一應用的局限虛擬化時代&#xff1a;突破與局限并存容器化時代&#xff1a;輕量級的革新技術演進的價值體現各位&#xff0c;歡迎來到容器化時代。 容器發展之路 現代業務的核心是應用程序&#xff08;Application&#xff09;…

WPF依賴屬性和依賴屬性的包裝器:

依賴屬性是WPF&#xff08;Windows Presentation Foundation&#xff09;中的一種特殊類型的屬性&#xff0c;特別適用于內存使用優化和屬性值繼承。依賴屬性的定義包括以下幾個步驟&#xff1a; 使用 DependencyProperty.Register 方法注冊依賴屬性。 該方法需要四個參數&…

圖生圖算法

圖生圖算法研究細分&#xff1a;技術演進、應用與爭議 1. 基于GAN的傳統圖生圖方法 定義&#xff1a;利用生成對抗網絡&#xff08;GAN&#xff09;將輸入圖像轉換為目標域圖像&#xff08;如語義圖→照片、草圖→彩圖&#xff09;。關鍵發展與趨勢&#xff1a; Pix2Pix&#…

Go 自建庫的使用教程與測試

附加一個Go庫的實現&#xff0c;相較于Python&#xff0c;Go的實現更較為日常&#xff0c;不需要額外增加setup.py類的文件去額外定義,計算和并發的性能更加。 1. 創建 Go 模塊項目結構 首先創建完整的項目結構&#xff1a; gomathlib/ ├── go.mod ├── go.sum ├── cor…