utHash.hインターフェイスの学習例

構造体{ChainNodeのtypedef
    構造体*次ChainNode;
    CHAR *データ; //ファイルパス+ファイル名
} ChainNode。

typedefは構造体チェーン{
    構造体ChainNode *ヘッド。
    int型のカウント;
}鎖;

MAX_CONTEXT_LEN 50の#define

typedefは構造体のハッシュ{
    チャーキー[MAX_CONTEXT_LEN + 2]。
    チェーンチェーン。
    UT_hash_handle HH;
}ハッシュ;

ハッシュ* strHash = NULL;

ボイドAddChainNode(CHAR *データ、チェーン*鎖)
{
    ChainNode *ノード=(ChainNode *)はmalloc(はsizeof(ChainNode))。
    ノード- >次= 0。
    ノード- >データ=(CHAR *)はmalloc(はsizeof(CHAR)*(STRLEN(データ)+ 1))。
    strcpyの(ノード- >データ、データ)。

    鎖- >数++;
    IF(鎖- >ヘッド== 0){
        鎖- >ヘッド=ノード。
    } {他
        ノード- >次=鎖- >ヘッド。
        鎖- >ヘッド=ノード。
    }
    を返します。
}

ボイドAddHashNode(CHAR *キー、CHAR *データ)
{
    ハッシュ* hashNode。
    HASH_FIND_STR(strHash、キー、hashNode)。
    IF(hashNode == 0){
        hashNode =(ハッシュ*)のmalloc(はsizeof(ハッシュ))。
        strcpyの(hashNode->キー、キー)。
        hashNode-> chain.count = 0;
        hashNode-> chain.head = 0;
        AddChainNode(データ、&​​hashNode->鎖);
        HASH_ADD_STR(strHash、キー、hashNode)。
    }他{
        AddChainNode(データ、&​​hashNode->鎖);
    }
    を返します。
}

/ **
 *サイズ* returnSizeの配列の配列を返します。
 *アレイのサイズは* returnColumnSizesアレイとして返されます。
 *注:どちらも返される配列と* columnSizes配列をmallocされなければならない、無料の発信者の通話を想定()。
 * /
の#define MAX_PATH_LENGTH 10000
の#define MAX_CONTEXT_LEN 50

INT GETPATH(CHAR *パスチャー* pathBuffer)
{
    int型のPOS。
    {(; POS <STRLEN(パス)POS ++ POS = 0)のための
        IF(パス[POS] == '「){
            ブレーク。
        }
        pathBuffer [POS] =パス[POS]。
    }
    pathBuffer [POS ++] = '/'。
    POSを返します。
}

fileprocボイド(INT pathLenを少なくとも、pathBufferチャー*、CHAR *パスの)
{
    ; INT = pathLenを少なくともCOUNTの
    チャーコンテキスト[MAX_CONTEXT_LEN + 2];
    //ルート/ A 1.TXT(ABCD)2.txt(EFGH)
    // pathBuffer [COUNT ++ ] = '/';
    のための(少なくともINT I = pathLenをする; I <strlenを(パス); I ++){
        IF(パス[I] == '('){
            pathBuffer [COUNT ++] = 0; //パス+ファイル名
            INT = 0 contextLen;
            一方(パス[I ++] =! '')){
                コンテキスト[contextLen ++] =パス[I];
            }
            コンテキスト[contextLen ++] = 0; //ファイルの内容
            //ファイルの内容は、挿入されたハッシュを除去されています
            AddHashNode(コンテキスト、pathBuffer);
            挿入が完了し//後、パスのみを含むようにバックオフ・カウントが空間濾過、この場合i)のまま
            I ++;
            カウント= pathLenを。
            継続する;
        }他{
            pathBufferは=パス[I] [++カウント]。
        }
    }
}

ボイドDestroyHashNode(ハッシュ・ノード)
{
    チェーンチェーン=ノード- >チェーン。
    ChainNode *ヘッド、* TEMP。
    ヘッド= chain.head。

    一方、(ヘッド){
        TEMP =頭部>次。
        無料(頭部>データ);
        無料(ヘッド);
        ヘッド=温度;
    }
    フリー(ノード)。
    リターン;
}

CHAR ***出力(INT * retuenSize、int型** returnColSize)
{
    int型のカウント= 0;
    ハッシュ* CURRENT_USER、* TMP;
    HASH_ITER(HH、strHash、CURRENT_USER、TMP){
        IF(current_user-> chain.count> 1){
            ++数えます。
        }他{
            HASH_DEL(strHash、CURRENT_USER)。/ *削除します。次の* /へのユーザの進歩
            DestroyHashNode(CURRENT_USER)。/ *オプション-あなたが解放したい場合* /
        }
    }
    * retuenSize =数えます。
    文字***出力=(文字***)はmalloc(はsizeof(文字**)*数)。
    int型* retCol =(int型*)はmalloc(はsizeof(int型)*数)。
    * returnColSize = retCol。

    カウント= 0;
    ChainNode *ヘッド。
    HASH_ITER(HH、strHash、CURRENT_USER、TMP){
        IF(current_user-> chain.count> 1){
            出力[カウント] =(CHAR **)はmalloc(はsizeof(文字*)*(current_user-> chain.count)) ;
            ヘッド= current_user-> chain.head。
            int型FILENUM = 0;
            (ヘッド){ながら
                出力[カウント] [FILENUM] =(CHAR *)はmalloc(はsizeof(CHAR)*(STRLEN(頭部>データ)+ 1))。
                strcpyの(出力[カウント] [FILENUM]、頭部>データ)。
                FILENUM ++;
                ヘッド=頭部>次。
            }
            retCol [カウント] = current_user-> chain.count。
            ++数えます。
            HASH_DEL(strHash、CURRENT_USER)。
            DestroyHashNode(CURRENT_USER)。
        }
    }
    strHash = NULL;
    出力を返します。
}

チャー*** findDuplicate(チャー**パス、INT pathsSize、INT * returnSize、INT ** returnColumnSizes){
    チャーpathBuffer [MAX_PATH_LENGTH]。
    int型pathLenを;
    int型pathLoop;

    //好都合入力のそれぞれの行、経路を取っファイルパス
    のために(pathLoop = 0; pathLoop <pathsSize; pathLoop ++){
        //ルート/ A 1.TXT(ABCD)2.txt(EFGH)
        pathLenを少なくともGETPATH =(パス[pathLoop]の、 pathBuffer); //レコードのファイルパスの長さ、0がCOUNTに格納されている- 1。
        fileproc少なくともの(pathLenを、pathBuffer、パス[pathLoop]);
    }

    // 1つの上の送信データのハッシュ数のすべてのノードをトラバース
    リターン出力(returnSize、returnColumnSizes);
}

 

https://blog.csdn.net/qq_23091073/article/details/86485095

 

使用uthashの
初期化
uthashは、UT_hash_handle HH含む構造独自のデータ構造を定義するためにユーザに要求する
値としても(オプション)キーと値を定義する必要があり、キーとしてID、名前を
構造体my_struct {
    int型のID; / * *キー/
    名char [10];
    UT_hash_handle HH; / * * /このハッシュ可能構造を作り
};
typedefは構造体my_struct HashNode;
typedefは構造体my_struct * HashHead。

。1
2
3
4
5
6
7
8
追加
ハッシュテーブルデータに追加された
キーは、HASH_ADD_INTを使用することができるintで
使用HASH_ADD_STRのであってもよく、キーは文字列で
使用HASH_ADD_PTRであってもよいし、キーがポインターであり
、すべての実際のコールこの方法の上方、HASH_ADDを使用することができる、他のしかし、パラメータの簡素化
    、ボイドhashTabel_add(HashHead *ヘッド、* HashNodeユーザー){
        //述べたID上記のキー属性名は、しかし、非常に奇妙である、実際にマクロのパラメータとして置き換えられます
        //あなたは、以下のソースコードを見ることができますが、intfieldは&に置き換え置き換えます((ADD) - >フィールド名)
        IF(find_user(ヘッド*、USERS-> ID)!)
            HASH_ADD_INT(ヘッド*、ID、ユーザ);
    }
1
2
3。
4。
5。
6。
の#define HASH_ADD_INT(ヘッド、intfield、ADD)\
    HASH_ADD(HH、頭、intfield、はsizeof(int型)、ADD)
の#define HASH_ADD(HH、頭、フィールド名、keylen_in、追加)\
  HASH_ADD_KEYPTR(HH、頭、&​​((追加) - >フィールド名)、keylen_in、追加)
。1
2
。3
。4
代わりに
それを追加して、新しいノードを追加するために、同一のノード鍵を削除、添加前になり
使用HASH_REPLACE_INTであってもよいし、キーがintである場合に
ボイドreplace_user(HashHead *ヘッド、HashNode * newNode){
    HashNode * oldNodeが= find_user (*ヘッド、newnode-> ID);
    IF(oldNodeが)
        HASH_REPLACE_INT(ヘッド*、ID、newNode、oldNodeが);
}
。1
2
。3
。4
。5
ルックアップ
キーに従ってノードを見つけるために
キーがintである場合、HASH_FIND_INTを使用することができます
HashNode * find_user(HashHeadヘッド、INT USER_ID){
    HashNode * S。
    HASH_FIND_INT(頭、&​​USER_ID、S)。/ * sの:出力ポインタ* /
    リターン秒;
}
1
2
3
4
5
删除
删除节点
使用HASH_DEL
空隙DELETE_USER(HashHead *ヘッド、HashNode *ユーザ){
    IF(ユーザ){
        HASH_DEL(*ヘッド、ユーザ)。/ *ユーザー:deleteeへのポインタ* /
        無料(利用者)。/ *オプション。それはあなた次第です!* /
    }
}
1
2
3
4
5
6
计数
统计节点数
使用HASH_COUNT
INT count_user(HashHeadヘッド){
    リターンHASH_COUNT(ヘッド);
}
1
2
3
遍历
遍历节点
可以用循环或者使用HASH_ITER
空隙print_user(HashHeadヘッド){
    HashNode * S。
    printf( "サイズは%D \ nは"、count_user(ヘッド))。
    用(S =ヘッド; S!= NULL; S = S-> hh.next){
        のprintf( "ユーザIDは%d、名前%S \ n"は、S-> ID、S->名);
    }
}
ボイドprint_user_iterator(HashHeadヘッド){
    HashNode * S * TMP。
    printf( "サイズは%D \ nは"、count_user(ヘッド))。
    HASH_ITER(HH、ヘッド、S、TMP){
        のprintf( "ユーザID%のD:名前%S \ n"は、S-> ID、S->名);
        / * ...



2
。3
。4
。5
。6
。7
8
9
10
11
12は
13である
14
15
ソート
キーまたは値ができ、ソートノードに
HASH_SORT使用
int型name_sort(HashNode * A * B HashNode){
    リターンのstrcmp(A->名、B->名前を);
}

INT id_sort(HashNode *、HashNode * B){
    リターン(A-> ID - B-> ID)。
}

ボイドsort_by_name(HashHead *ヘッド){
    HASH_SORT(*ヘッド、name_sort)。
}

ボイドsort_by_id(HashHead *ヘッド){
    HASH_SORT(*ヘッド、id_sort)。
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
三、完整代码
の#include <stdio.hに>
する#include <STDLIB.H>
の#include "uthash.h"

typedefは構造体my_struct {
    int型のID。/ *我々はキー* /としてこのフィールドを使用します
    文字名[10]。
    UT_hash_handle HH; / *この構造ハッシュ可能* /なり
} HashNode。
HashNode * HashHeadのtypedef。

int型count_user(HashHeadヘッド);
HashNode * find_user(HashHeadヘッド、INT USER_ID){
    HashNode * S。
    HASH_FIND_INT(頭、&​​USER_ID、S)。/ * sの:出力ポインタ* /
    リターン秒;
}
ボイドADD_USER(HashHead *ヘッド、HashNode *ユーザ){
    IF(find_user(*ヘッド、users-> ID)!)
        HASH_ADD_INT(*ヘッド、ID、ユーザ);
}
ボイドreplace_user(HashHead *ヘッド、HashNode * newNode){
    * oldNodeが= find_user HashNode(*ヘッド、newNode-> ID)。
    (oldNodeが)場合
        HASH_REPLACE_INT(*ヘッド、ID、newNode、oldNodeが)。
}
ボイドDELETE_USER(HashHead *ヘッド、HashNode *ユーザ){
    IF(ユーザ){
        HASH_DEL(*ヘッド、ユーザ)。/ *ユーザー:deleteeへのポインタ* /
        無料(利用者)。/ *オプション。それはあなた次第です!* /
    }
}
ボイドprint_user(HashHeadヘッド){
    HashNode * S。
    printf( "サイズは%D \ nは"、count_user(ヘッド))。
    用(S =ヘッド; S!= NULL; S = S-> hh.next){
        のprintf( "ユーザIDは%d、名前%S \ n"は、S-> ID、S->名);
    }
}
ボイドprint_user_iterator(HashHeadヘッド){
    HashNode * S * TMP。
    printf( "サイズは%D \ nは"、count_user(ヘッド))。
    HASH_ITER(HH、ヘッド、S、TMP){
        のprintf( "ユーザID%のD:名前%S \ n"は、S-> ID、S->名);
        / * ... * /ここでSを削除し、自由にしても安全である
    }
}
{int型のcount_user(HashHeadヘッド)
    リターンHASH_COUNT(ヘッド);
}
int型name_sort(HashNode *、HashNode * B){
       リターンのstrcmp(A->名、B->名);
}

INT id_sort(HashNode *、HashNode * B){
       リターン(A-> ID - B-> ID)。
}

ボイドsort_by_name(HashHead *ヘッド){
       HASH_SORT(*ヘッド、name_sort)。
}

ボイドsort_by_id(HashHead *ヘッド){
       HASH_SORT(*ヘッド、id_sort)。
}
int型のmain()
{
    のprintf( "-------------- INIT --------------- \ n");
    HashHeadヘッド= NULL;
    printf( "-------------- ---------------追加\ N");
    HashNode * =ノードのmalloc(はsizeof(HashNode))。
    ノード- > ID = 1。
    strcpyの(ノード- >名前、 "トム");
    ADD_USER(&ヘッド、ノード)。

    ノード= malloc関数(はsizeof(HashNode))。
    ノード- > ID = 2。
    strcpyの(ノード- >名前、 "ジェリー");
    ADD_USER(&ヘッド、ノード)。

    ノード= malloc関数(はsizeof(HashNode))。
    ノード- > ID = 3。
    strcpyの(ノード- >名前、 "ジャック");
    ADD_USER(&ヘッド、ノード)。

    ノード= malloc関数(はsizeof(HashNode))。
    ノード- > ID = 0。
    strcpyの(ノード- >名前、 "ゼロ");
    ADD_USER(&ヘッド、ノード)。

    print_user(ヘッド)

    printf( "-------------- ---------------置き換える\ N");
    HashNode * newNode = malloc関数(はsizeof(HashNode))。
    newNode-> ID = 3。
    strcpyの(newNode->名、 "バラ");
    replace_user(&ヘッド、newNode);
    print_user(ヘッド)

    printf( "削除--------------- -------------- \ N-");
    DELETE_USER(&ヘッド、find_user(ヘッド,. 1));
    print_user(ヘッド);
    のprintf( "ID --------------- \ N- ---------------ソート・バイ");
    sort_by_id(ヘッド& );
    print_user(ヘッド);
    のprintf( "ソート・バイ・名-------------- --------------- \ N-");
    sort_by_name (&ヘッド);
    print_user(ヘッド);
    戻り0;
}
----------------
免責事項:この記事はBY-SA CC 4.0に従う、CSDNブロガー「aabond「オリジナル記事です著作権の契約は、再現し、元のソースのリンクと、この文を添付してください。
オリジナルリンクします。https://blog.csdn.net/qq_23091073/article/details/86485095

公開された48元の記事 ウォンの賞賛5 ビュー11万+

おすすめ

転載: blog.csdn.net/s651665496/article/details/104342508
おすすめ