1. 程式人生 > >第十五週專案1-驗證演算法

第十五週專案1-驗證演算法

問題及程式碼:

/* 
* Copyright (c)2016,煙臺大學計算機與控制工程學院 
* All rights reserved. 
* 檔名稱:1.cpp 
* 作    者:張相如 
* 完成日期:2016年12月8日 
* 版 本 號:v1.0 
 
* 問題描述:認真閱讀並驗證雜湊表實施查詢的相關演算法,寫程式建立序列{16, 74, 60, 43, 54, 90, 46, 31, 29, 88, 77} 
            的雜湊表,裝填因子定為0.8,雜湊函式為h(k)=key%p,p=11,採用線性探查法解決衝突。測試中:  
             
            (1)輸出建立的雜湊表;  
            (2)完成關鍵字為29的元素的查詢;  
            (3)在上述雜湊表中刪除關鍵字為77的元素,再顯示雜湊表。 
 
* 輸入描述:無 
* 程式輸出:測試資料 
*/ 

#include <stdio.h>  
#define MaxSize 100         //定義最大雜湊表長度  
#define NULLKEY -1          //定義空關鍵字值  
#define DELKEY  -2          //定義被刪關鍵字值  
typedef int KeyType;        //關鍵字型別  
typedef char * InfoType;    //其他資料型別  
typedef struct  
{  
    KeyType key;            //關鍵字域  
    InfoType data;          //其他資料域  
    int count;          //探查次數域  
} HashData;  
  
typedef HashData HashTable[MaxSize];        //雜湊表型別  
  
void InsertHT(HashTable ha,int &n,KeyType k,int p)  //將關鍵字k插入到雜湊表中  
{  
    int i,adr;  
    adr=k % p;  
    if (ha[adr].key==NULLKEY || ha[adr].key==DELKEY)    //x[j]可以直接放在雜湊表中  
    {  
        ha[adr].key=k;  
        ha[adr].count=1;  
    }  
    else                    //發生衝突時採用線性探查法解決衝突  
    {  
        i=1;                //i記錄x[j]發生衝突的次數  
        do  
        {  
            adr=(adr+1) % p;  
            i++;  
        }  
        while (ha[adr].key!=NULLKEY && ha[adr].key!=DELKEY);  
        ha[adr].key=k;  
        ha[adr].count=i;  
    }  
    n++;  
}  
void CreateHT(HashTable ha,KeyType x[],int n,int m,int p)  //建立雜湊表  
{  
    int i,n1=0;  
    for (i=0; i<m; i++)         //雜湊表置初值  
    {  
        ha[i].key=NULLKEY;  
        ha[i].count=0;  
    }  
    for (i=0; i<n; i++)  
        InsertHT(ha,n1,x[i],p);  
}  
int SearchHT(HashTable ha,int p,KeyType k)      //在雜湊表中查詢關鍵字k  
{  
    int i=0,adr;  
    adr=k % p;  
    while (ha[adr].key!=NULLKEY && ha[adr].key!=k)  
    {  
        i++;                //採用線性探查法找下一個地址  
        adr=(adr+1) % p;  
    }  
    if (ha[adr].key==k)     //查詢成功  
        return adr;  
    else                    //查詢失敗  
        return -1;  
}  
int DeleteHT(HashTable ha,int p,int k,int &n)   //刪除雜湊表中關鍵字k  
{  
    int adr;  
    adr=SearchHT(ha,p,k);  
    if (adr!=-1)        //在雜湊表中找到該關鍵字  
    {  
        ha[adr].key=DELKEY;  
        n--;            //雜湊表長度減1  
        return 1;  
    }  
    else                //在雜湊表中未找到該關鍵字  
        return 0;  
}  
void DispHT(HashTable ha,int n,int m)    //輸出雜湊表  
{  
    float avg=0;  
    int i;  
    printf(" 雜湊表地址:\t");  
    for (i=0; i<m; i++)  
        printf(" %3d",i);  
    printf(" \n");  
    printf(" 雜湊表關鍵字:\t");  
    for (i=0; i<m; i++)  
        if (ha[i].key==NULLKEY || ha[i].key==DELKEY)  
            printf("    ");         //輸出3個空格  
        else  
            printf(" %3d",ha[i].key);  
    printf(" \n");  
    printf(" 搜尋次數:\t");  
    for (i=0; i<m; i++)  
        if (ha[i].key==NULLKEY || ha[i].key==DELKEY)  
            printf("    ");         //輸出3個空格  
        else  
            printf(" %3d",ha[i].count);  
    printf(" \n");  
    for (i=0; i<m; i++)  
        if (ha[i].key!=NULLKEY && ha[i].key!=DELKEY)  
            avg=avg+ha[i].count;  
    avg=avg/n;  
    printf(" 平均搜尋長度ASL(%d)=%g\n",n,avg);  
}  
int main()  
{  
    int x[]= {16,74,60,43,54,90,46,31,29,88,77};  
    int n=11,m=13,p=13,i,k=29;  
    HashTable ha;  
    CreateHT(ha,x,n,m,p);  
    printf("\n");  
    DispHT(ha,n,m);  
    i=SearchHT(ha,p,k);  
    if (i!=-1)  
        printf(" ha[%d].key=%d\n",i,k);  
    else  
        printf(" 未找到%d\n",k);  
    k=77;  
    printf(" 刪除關鍵字%d\n",k);  
    DeleteHT(ha,p,k,n);  
    DispHT(ha,n,m);  
    i=SearchHT(ha,p,k);  
    if (i!=-1)  
        printf(" ha[%d].key=%d\n",i,k);  
    else  
        printf(" 未找到%d\n",k);  
    printf(" 插入關鍵字%d\n",k);  
    InsertHT(ha,n,k,p);  
    DispHT(ha,n,m);  
    printf("\n");  
    return 0;  
}  
執行結果:

知識點總結:

學習對雜湊表的運用