0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

常見的查找算法匯總(含詳細(xì)代碼)3

jf_78858299 ? 來源:阿Q正磚 ? 作者:阿Q正磚 ? 2023-04-24 17:20 ? 次閱讀

6、樹表查找

6.1、基本原理

樹表查找(Tree-based Search)通常是一種利用有序樹結(jié)構(gòu)進(jìn)行查找的算法,基于二叉搜索樹(BST)或其它平衡二叉搜索樹(如AVL樹、紅黑樹)等數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的查找算法。其基本原理是將查找值與樹中的某個(gè)節(jié)點(diǎn)進(jìn)行比較,根據(jù)比較結(jié)果,沿著樹的某個(gè)分支繼續(xù)向下查找,直到查找到目標(biāo)節(jié)點(diǎn)或者發(fā)現(xiàn)目標(biāo)節(jié)點(diǎn)不存在為止。

樹表查找的優(yōu)點(diǎn)是查找效率高,時(shí)間復(fù)雜度為 O(log n),其中 n 是節(jié)點(diǎn)的總數(shù)。它的主要缺點(diǎn)是需要維護(hù)樹的平衡性,增加和刪除節(jié)點(diǎn)會(huì)導(dǎo)致樹的平衡性被破壞,需要進(jìn)行旋轉(zhuǎn)操作來恢復(fù)平衡,這樣會(huì)增加操作的時(shí)間復(fù)雜度。

實(shí)現(xiàn)樹表查找算法,需要定義一個(gè)樹結(jié)構(gòu),每個(gè)節(jié)點(diǎn)包括一個(gè)鍵和一個(gè)值。鍵用于比較大小,值是存儲(chǔ)的數(shù)據(jù)。具體實(shí)現(xiàn)可以使用遞歸或者迭代的方式,對(duì)于每個(gè)節(jié)點(diǎn)進(jìn)行比較,并根據(jù)比較結(jié)果決定向左子樹或者右子樹繼續(xù)查找,直到找到目標(biāo)節(jié)點(diǎn)或者發(fā)現(xiàn)目標(biāo)節(jié)點(diǎn)不存在為止。

6.2、代碼示例

方法一:基于BST實(shí)現(xiàn)

#include 
#include 


// 定義二叉搜索樹節(jié)點(diǎn)結(jié)構(gòu)體
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};


// BST的插入操作
struct TreeNode* insert(struct TreeNode* root, int val) {
    if (root == NULL) {
        struct TreeNode* new_node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
        new_node->val = val;
        new_node->left = NULL;
        new_node->right = NULL;
        return new_node;
    } else {
        if (val < root->val) {
            root->left = insert(root->left, val);
        } else if (val > root->val) {
            root->right = insert(root->right, val);
        }
        return root;
    }
}


// BST的查找操作
struct TreeNode* search(struct TreeNode* root, int val) {
    if (root == NULL || root->val == val) {
        return root;
    } else if (val < root->val) {
        return search(root->left, val);
    } else {
        return search(root->right, val);
    }
}


// 中序遍歷BST(用于驗(yàn)證BST的正確性)
void inorderTraversal(struct TreeNode* root) {
    if (root != NULL) {
        inorderTraversal(root->left);
        printf("%d ", root->val);
        inorderTraversal(root->right);
    }
}


int main() {
    struct TreeNode* root = NULL;
    root = insert(root, 5);
    root = insert(root, 3);
    root = insert(root, 7);
    root = insert(root, 2);
    root = insert(root, 4);
    root = insert(root, 6);
    root = insert(root, 8);


    inorderTraversal(root); // 輸出:2 3 4 5 6 7 8


    struct TreeNode* node = search(root, 6);
    if (node != NULL) {
        printf("找到了:%d\\n", node->val); // 輸出:找到了:6
    } else {
        printf("未找到\\n");
    }


    return 0;
}

該代碼定義了一個(gè)二叉搜索樹的結(jié)構(gòu)體TreeNode,包含了該節(jié)點(diǎn)的值val、左子節(jié)點(diǎn)指針left、右子節(jié)點(diǎn)指針right。同時(shí),實(shí)現(xiàn)了BST的插入和查找操作,其中插入操作是遞歸實(shí)現(xiàn)的,查找操作也是遞歸實(shí)現(xiàn)的。最后,利用中序遍歷函數(shù)inorderTraversal驗(yàn)證了BST的正確性,以及利用查找函數(shù)search查找了節(jié)點(diǎn)6。

方法二:基于紅黑樹

基于紅黑樹實(shí)現(xiàn)的樹表查找,也稱為紅黑樹查找,是一種高效的查找算法。紅黑樹是一種自平衡二叉查找樹,它具有以下特點(diǎn):

  1. 每個(gè)節(jié)點(diǎn)都有顏色,紅色或黑色;
  2. 根節(jié)點(diǎn)和葉子節(jié)點(diǎn)都是黑色;
  3. 如果一個(gè)節(jié)點(diǎn)是紅色,則它的子節(jié)點(diǎn)必須是黑色;
  4. 任何一條從根節(jié)點(diǎn)到葉子節(jié)點(diǎn)的路徑上,黑色節(jié)點(diǎn)的個(gè)數(shù)必須相同。

基于紅黑樹實(shí)現(xiàn)的樹表查找的實(shí)現(xiàn)過程如下:

  1. 構(gòu)建紅黑樹,將要查找的元素插入到紅黑樹中;
  2. 對(duì)紅黑樹進(jìn)行遍歷,查找需要的元素;
  3. 如果查找成功,返回該元素的位置;
  4. 如果查找失敗,返回空指針。

紅黑樹的插入和刪除操作都會(huì)改變樹的結(jié)構(gòu),因此在進(jìn)行插入和刪除操作時(shí)需要對(duì)紅黑樹進(jìn)行重新平衡。具體的平衡方法包括左旋、右旋、變色等操作,這些操作的目的是保持紅黑樹的平衡性和有序性。在進(jìn)行查找操作時(shí),根據(jù)紅黑樹的特點(diǎn)可以快速定位到目標(biāo)元素,從而實(shí)現(xiàn)高效的查找。

rbtree.h

#ifndef _RED_BLACK_TREE_H_
#define _RED_BLACK_TREE_H_


#define RED        0    // 紅色節(jié)點(diǎn)
#define BLACK    1    // 黑色節(jié)點(diǎn)


typedef int Type;


// 紅黑樹的節(jié)點(diǎn)
typedef struct RBTreeNode{
    unsigned char color;        // 顏色(RED 或 BLACK)
    Type   key;                    // 關(guān)鍵字(鍵值)
    struct RBTreeNode *left;    // 左孩子
    struct RBTreeNode *right;    // 右孩子
    struct RBTreeNode *parent;    // 父結(jié)點(diǎn)
}Node, *RBTree;


// 紅黑樹的根
typedef struct rb_root{
    Node *node;
}RBRoot;


// 創(chuàng)建紅黑樹,返回"紅黑樹的根"!
RBRoot* create_rbtree();


// 銷毀紅黑樹
void destroy_rbtree(RBRoot *root);


// 將結(jié)點(diǎn)插入到紅黑樹中。插入成功,返回0;失敗返回-1。
int insert_rbtree(RBRoot *root, Type key);


// 刪除結(jié)點(diǎn)(key為節(jié)點(diǎn)的值)
void delete_rbtree(RBRoot *root, Type key);




// 前序遍歷"紅黑樹"
void preorder_rbtree(RBRoot *root);
// 中序遍歷"紅黑樹"
void inorder_rbtree(RBRoot *root);
// 后序遍歷"紅黑樹"
void postorder_rbtree(RBRoot *root);


// (遞歸實(shí)現(xiàn))查找"紅黑樹"中鍵值為key的節(jié)點(diǎn)。找到的話,返回0;否則,返回-1。
int rbtree_search(RBRoot *root, Type key);
// (非遞歸實(shí)現(xiàn))查找"紅黑樹"中鍵值為key的節(jié)點(diǎn)。找到的話,返回0;否則,返回-1。
int iterative_rbtree_search(RBRoot *root, Type key);


// 返回最小結(jié)點(diǎn)的值(將值保存到val中)。找到的話,返回0;否則返回-1。
int rbtree_minimum(RBRoot *root, int *val);
// 返回最大結(jié)點(diǎn)的值(將值保存到val中)。找到的話,返回0;否則返回-1。
int rbtree_maximum(RBRoot *root, int *val);


// 打印紅黑樹
void print_rbtree(RBRoot *root);


#endif

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    6715

    瀏覽量

    88316
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4671

    瀏覽量

    67771
  • 查找算法
    +關(guān)注

    關(guān)注

    0

    文章

    6

    瀏覽量

    5521
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    實(shí)現(xiàn)TCP的C代碼封裝(代碼

    實(shí)現(xiàn)TCP的C代碼封裝(代碼
    的頭像 發(fā)表于 09-28 16:03 ?2331次閱讀
    實(shí)現(xiàn)TCP的C<b class='flag-5'>代碼</b>封裝(<b class='flag-5'>含</b><b class='flag-5'>代碼</b>)

    TI資深工程師對(duì)無線連接技術(shù)經(jīng)驗(yàn)匯總、常見疑難問題詳細(xì)解答

    、資料、以及常見問題的詳細(xì)解答、低功耗解決方案。TI 為任何應(yīng)用提供跨越所有主要標(biāo)準(zhǔn)和技術(shù)的無線連接解決方案。無論是從事任何工業(yè)、汽車還是物聯(lián)網(wǎng)的設(shè)計(jì),助您輕松學(xué)習(xí)無線連接知識(shí)。 TI專家解答CC3200
    發(fā)表于 09-11 16:17

    簡單的查找算法

    ; } return 0;} 3. 有序數(shù)組表的查找:一般使用二分法查找。通過判斷查找元素與中間元素(mid)的大小來決定下一次的查找在低
    發(fā)表于 12-27 22:33

    isis 7 professional_元件查找代碼

    isis 7 professional元件查找代碼有各總isis 7 professional元件的查找代碼
    發(fā)表于 12-08 15:58 ?7次下載

    輪廓查找基礎(chǔ)_《OpenCV3編程入門》書本配套源代碼

    《OpenCV3編程入門》書本配套源代碼:輪廓查找基礎(chǔ)
    發(fā)表于 06-06 15:39 ?4次下載

    圖論算法及MATLAB程序代碼詳細(xì)資料說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是圖論算法及MATLAB程序代碼詳細(xì)資料說明。
    發(fā)表于 04-23 08:00 ?0次下載
    圖論<b class='flag-5'>算法</b>及MATLAB程序<b class='flag-5'>代碼</b>的<b class='flag-5'>詳細(xì)</b>資料說明

    MATLAB優(yōu)化算法匯總01

    MATLAB優(yōu)化算法匯總01
    發(fā)表于 10-08 10:57 ?0次下載

    MATLAB優(yōu)化算法匯總02

    MATLAB優(yōu)化算法匯總02
    發(fā)表于 10-08 10:59 ?0次下載

    MATLAB優(yōu)化算法匯總03

    MATLAB優(yōu)化算法匯總03
    發(fā)表于 10-08 11:01 ?0次下載

    A星路徑規(guī)劃算法完整代碼資料匯總

    A星路徑規(guī)劃算法完整代碼資料匯總
    發(fā)表于 12-03 17:16 ?11次下載

    匯總常見單片機(jī)原廠代碼倉庫,值得收藏

    匯總常見單片機(jī)原廠代碼倉庫,值得收藏
    發(fā)表于 12-03 16:06 ?9次下載
    <b class='flag-5'>匯總</b><b class='flag-5'>常見</b>單片機(jī)原廠<b class='flag-5'>代碼</b>倉庫,值得收藏

    常見查找算法匯總詳細(xì)代碼)1

    今天就把常見*查找算法也總結(jié)個(gè)通透, 還有詳細(xì)代碼解釋, 真的是寫完這篇感覺腦子已經(jīng)不是自己的了,還希望大家好好利用。
    的頭像 發(fā)表于 04-24 17:20 ?854次閱讀
    <b class='flag-5'>常見</b>的<b class='flag-5'>查找</b><b class='flag-5'>算法</b><b class='flag-5'>匯總</b>(<b class='flag-5'>含</b><b class='flag-5'>詳細(xì)</b><b class='flag-5'>代碼</b>)1

    常見查找算法匯總詳細(xì)代碼)2

    今天就把常見****查找算法也總結(jié)個(gè)通透, 還有詳細(xì)代碼解釋, 真的是寫完這篇感覺腦子已經(jīng)不是自己的了,還希望大家好好利用。
    的頭像 發(fā)表于 04-24 17:20 ?555次閱讀

    常見查找算法匯總詳細(xì)代碼)4

    今天就把常見****查找算法也總結(jié)個(gè)通透, 還有詳細(xì)代碼解釋, 真的是寫完這篇感覺腦子已經(jīng)不是自己的了,還希望大家好好利用。
    的頭像 發(fā)表于 04-24 17:20 ?494次閱讀

    常見查找算法匯總詳細(xì)代碼)5

    今天就把常見****查找算法也總結(jié)個(gè)通透, 還有詳細(xì)代碼解釋, 真的是寫完這篇感覺腦子已經(jīng)不是自己的了,還希望大家好好利用。
    的頭像 發(fā)表于 04-24 17:20 ?727次閱讀