實現雜湊表

尹成發表於2015-05-27

  1. #include<stdio.h>   
  2. #include<iostream>   
  3. #include<conio.h>   
  4.    
  5. using namespace std;   
  6.    
  7. #define HASH_LEN 50                      //雜湊表的長度            
  8. #define M 47                            //隨機數   
  9. int NAME_NO=34;                     //城市名的個數           
  10.    
  11. typedef struct         
  12. {   
  13.     char *py;    //名字的拼音   
  14.     int k;       //拼音所對應的整數   
  15. }NAME;   
  16.    
  17. NAME NameList[HASH_LEN];    //全域性變數NAME                
  18.    
  19. typedef struct    //雜湊表   
  20. {   
  21.     char *py;   //名字的拼音   
  22.     int k;      //拼音所對應的整數   
  23.     int si;     //查詢長度   
  24. }HASH;   
  25.    
  26. HASH HashList[HASH_LEN];        //全域性變數HASH                        
  27.    
  28. void InitNameList() //姓名(結構體陣列)初始化             
  29. {   
  30.     char *f;   
  31.     int r,s0,i;   
  32.     NameList[0].py="harbin";   
  33.     NameList[1].py="shijiazhuang";   
  34.     NameList[2].py="lanzhou";   
  35.     NameList[3].py="kunming";   
  36.     NameList[4].py="chengdu";   
  37.     NameList[5].py="changchun";   
  38.     NameList[6].py="shenyang";   
  39.     NameList[7].py="xining";   
  40.     NameList[8].py="xian";   
  41.     NameList[9].py="zhengzhou";   
  42.     NameList[10].py="jinan";   
  43.     NameList[11].py="taiyuan";   
  44.     NameList[12].py="hefei";   
  45.     NameList[13].py="wuhan";   
  46.     NameList[14].py="changsha";   
  47.     NameList[15].py="nanjing";   
  48.     NameList[16].py="guiyang";   
  49.     NameList[17].py="nanning";   
  50.     NameList[18].py="hangzhou";   
  51.     NameList[19].py="nanchang";   
  52.     NameList[20].py="guangzhou";   
  53.     NameList[21].py="fuzhou";   
  54.     NameList[22].py="taipei";   
  55.     NameList[23].py="haikou";   
  56.     NameList[24].py="huhhot";   
  57.     NameList[25].py="yinchuan";   
  58.     NameList[26].py="urumqi";   
  59.     NameList[27].py="lahsa";   
  60.     NameList[28].py="macau";   
  61.     NameList[29].py="beijing";   
  62.     NameList[30].py="shanghai";   
  63.     NameList[31].py="hongkong";   
  64.     NameList[32].py="tianjin";   
  65.     NameList[33].py="chongqing";   
  66.     for (i=0;i<NAME_NO;i++)   
  67.     {   
  68.         s0=0;   
  69.         f=NameList[i].py;   
  70.         for (r=0;*(f+r)!='\0';r++)   
  71.             /* 方法:將字串的各個字元所對應的ASCII碼相加,所得的整數做為雜湊表的關鍵字*/   
  72.             s0=*(f+r)+s0;   
  73.         NameList[i].k=s0;   
  74.     }    
  75. }   
  76.    
  77. void CreateHashList() //建立雜湊表      
  78. {   
  79.     int i;   
  80.     for (i=0; i<HASH_LEN;i++)    
  81.     {   
  82.         HashList[i].py="";   
  83.         HashList[i].k=0;   
  84.         HashList[i].si=0;   
  85.     }   
  86.     for (i=0;i<HASH_LEN;i++)   
  87.     {   
  88.         int sum=0;   
  89.         int adr=(NameList[i].k)%M;  //雜湊函式   
  90.         int d=adr;   
  91.         if(HashList[adr].si==0)     //如果不衝突   
  92.         {   
  93.             HashList[adr].k=NameList[i].k;   
  94.             HashList[adr].py=NameList[i].py;   
  95.             HashList[adr].si=1;   
  96.         }   
  97.         else   //衝突     
  98.         {   
  99.             do   
  100.             {   
  101.                 d=(d+NameList[i].k%10+1)%M;   //偽隨機探測再雜湊法處理衝突       
  102.                 sum=sum+1;   //查詢次數加1       
  103.             }while (HashList[d].k!=0);   
  104.             HashList[d].k=NameList[i].k;   
  105.             HashList[d].py=NameList[i].py;   
  106.             HashList[d].si=sum+1;   
  107.         }   
  108.     }   
  109. }   
  110.    
  111. int  FindList() //查詢       
  112.    
  113. {     
  114.    
  115.        char name[20]={0};    
  116.        int s0=0,r,sum=1,adr,d;   
  117.        printf("\n請輸入城市名稱:");        
  118.        scanf("%s",name);    
  119.        for (r=0;r<20;r++)   //求出姓名的拼音所對應的整數(關鍵字)   
  120.            s0+=name[r];    
  121.        adr=s0%M;   //使用雜湊函式   
  122.        d=adr;   
  123.        if(HashList[adr].k==s0)          //分3種情況進行判斷   
  124.        {   
  125.            printf("\n名稱:%s   關鍵字:%d   查詢長度為: 1",HashList[d].py,s0);    
  126.            cout<<endl;   
  127.            return 0;   
  128.        }   
  129.        else if (HashList[adr].k==0)    
  130.        {   
  131.            printf("無此記錄!");   
  132.            cout<<endl;   
  133.            return 1;   
  134.        }   
  135.        else   
  136.        {   
  137.            int g=0;   
  138.            do   
  139.            {   
  140.                d=(d+s0%10+1)%M;       //偽隨機探測再雜湊法處理衝突                        
  141.                sum=sum+1;   
  142.                if (HashList[d].k==0)   
  143.                {   
  144.                    printf("無此記錄! ");     
  145.                    cout<<endl;   
  146.                    g=1;        
  147.                    return 1;   
  148.                }   
  149.                if (HashList[d].k==s0)   
  150.                {       
  151.                    printf("\n名稱:%s   關鍵字:%d   查詢長度為:%d",HashList[d].py,s0,sum);    
  152.                    cout<<endl;   
  153.                    g=1;     
  154.                    return 0;   
  155.                }   
  156.            }while(g==0);      
  157.        }   
  158. }   
  159.    
  160. void   Display() // 顯示雜湊表          
  161. {   
  162.     int i;   
  163.     float average=0;   
  164.     for(i=0; i<HASH_LEN; i++)   
  165.     {   
  166.         if(HashList[i].k%M==0)    
  167.         HashList[i].py="";   
  168.     }   
  169.     printf("\n\n地址\t關鍵字\t\t搜尋長度\tH(key)\t 名稱\n"); //顯示的格式   
  170.     for(i=0; i<HASH_LEN; i++)   
  171.     {   
  172.         printf("%d ",i);   
  173.         printf("\t%d ",HashList[i].k);   
  174.         printf("\t\t%d ",HashList[i].si);   
  175.         printf("\t\t%d ",HashList[i].k%M);   
  176.         printf("\t %s ",HashList[i].py);   
  177.         //cout<<"      "<<HashList[i].py<<endl;   
  178.         printf("\n");     
  179.         //cout<<i<<"         "<<HashList[i].k<<"             "<<HashList[i].si<<"             "<<HashList[i].k%M<<"         "<<HashList[i].py<<endl;   
  180.     }   
  181.     for (i=0;i<HASH_LEN;i++)   
  182.         average+=HashList[i].si;    
  183.     average/=NAME_NO;   
  184.     printf("\n\n平均查詢長度:ASL(%d)=%f \n\n",NAME_NO,average);    
  185. }   
  186.    
  187. void DeleteList()   
  188. {   
  189.     char name[20]={0};    
  190.     int s0=0,r,sum=1,adr,d;   
  191.     printf("\n請輸入城市名稱:");        
  192.     scanf("%s",name);    
  193.     for (r=0;r<20;r++)   //求出姓名的拼音所對應的整數(關鍵字)   
  194.         s0+=name[r];    
  195.     adr=s0%M;   //使用雜湊函式   
  196.     d=adr;   
  197.     if(HashList[adr].k==s0)          //分3種情況進行判斷   
  198.     {   
  199.         printf("\n名稱:%s   關鍵字:%d   查詢長度為: 1",HashList[d].py,s0);   
  200.         cout<<endl;   
  201.         cout<<"刪除成功!"<<endl;   
  202.         s0=0;   
  203.         HashList[d].py="";   //名字的拼音   
  204.         HashList[d].k=0;      //拼音所對應的整數   
  205.         HashList[d].si=0;   
  206.     }   
  207.     else if (HashList[adr].k==0)    
  208.         printf("無此記錄!無法執行刪除操作!");   
  209.     else   
  210.     {   
  211.         int g=0;   
  212.         do   
  213.         {   
  214.             d=(d+s0%10+1)%M;       //偽隨機探測再雜湊法處理衝突                        
  215.             sum=sum+1;   
  216.             if (HashList[d].k==0)   
  217.             {   
  218.                 printf("無此記錄!無法執行刪除操作!");     
  219.                 g=1;        
  220.             }   
  221.             if (HashList[d].k==s0)   
  222.             {       
  223.                 printf("\n名稱:%s   關鍵字:%d   查詢長度為:%d",HashList[d].py,s0,sum);    
  224.                 cout<<endl;   
  225.                 cout<<"已刪除成功!"<<endl;   
  226.                 s0=0;   
  227.                 HashList[d].py="";   //名字的拼音   
  228.                 HashList[d].k=0;      //拼音所對應的整數   
  229.                 HashList[d].si=0;   
  230.                 //Display();   
  231.                 g=1;     
  232.             }   
  233.         }while(g==0);      
  234.     }   
  235. }   
  236.    
  237. void EnterList()   
  238. {   
  239.      /*char name[20]={0};   
  240.      int s0=0,r,sum=1,adr,d,h;  
  241.      printf("\n請輸入姓名的拼音:");       
  242.      scanf("%s",name);   
  243.      for (r=0;r<20;r++)   //求出姓名的拼音所對應的整數(關鍵字)  
  244.          s0+=name[r];*/   
  245.      char st[20];   
  246.      char *xin;   
  247.      xin=st;   
  248.      int s0=0,r,sum=1,adr,d,h;   
  249.      printf("\n請輸入城市名稱的拼音:");   
  250.      cin>>xin;   
  251.      //cout<<xin<<endl;   
  252.      for (r=0;*(xin+r)!='\0';r++)   
  253.      {   
  254.          /* 方法:將字串的各個字元所對應的ASCII碼相加,所得的整數做為雜湊表的關鍵字*/   
  255.          s0=(int)(*(xin+r))+s0;   
  256.      }   
  257.      //cout<<s0<<endl;   
  258.      adr=s0%M;   //使用雜湊函式   
  259.      d=adr;   
  260.      if(HashList[adr].k==s0)          //分3種情況進行判斷   
  261.      {   
  262.          printf("\n名稱:%s   關鍵字:%d   查詢長度為: 1",HashList[d].py,s0);   
  263.          cout<<endl;   
  264.          cout<<"已存在於表中,無需插入!"<<endl;   
  265.       }   
  266.      else if (HashList[d].k==0)    
  267.      {   
  268.          printf("插入成功!");   
  269.          HashList[d].py=xin;   
  270.          HashList[d].k=s0;   
  271.          HashList[d].si=1;   
  272.          h=1;   
  273.          cout<<endl;   
  274.       }   
  275.      else   
  276.      {   
  277.          int g=0,h=0;   
  278.          do   
  279.          {   
  280.              d=(d+s0%10+1)%M;       //偽隨機探測再雜湊法處理衝突                        
  281.              sum=sum+1;   
  282.              if (HashList[d].k==0)   
  283.              {   
  284.                  printf("插入成功!");   
  285.                  HashList[d].py=xin;   
  286.                  HashList[d].k=s0;   
  287.                  HashList[d].si=sum;   
  288.                  h=1;   
  289.                  cout<<endl;   
  290.                  g=1;        
  291.              }   
  292.              if (HashList[d].k==s0)   
  293.              {       
  294.                  printf("\n名稱:%s   關鍵字:%d   查詢長度為:%d",HashList[d].py,s0,sum);   
  295.                  cout<<endl;   
  296.                  cout<<"已存在於表中,無需插入!"<<endl;   
  297.                  g=1;     
  298.               }   
  299.          }while(g==0);      
  300.      }   
  301.      if(h==0)   
  302.          return;   
  303.      else   
  304.      {   
  305.          NAME_NO++;   
  306.          NameList[NAME_NO-1].py=xin;   
  307.          int sum=0;   
  308.          int adr=(NameList[NAME_NO-1].k)%M;  //雜湊函式   
  309.          int d=adr;   
  310.          if(HashList[adr].si==0)     //如果不衝突   
  311.          {   
  312.              HashList[adr].k=NameList[NAME_NO-1].k;   
  313.              HashList[adr].py=NameList[NAME_NO-1].py;   
  314.              HashList[adr].si=1;   
  315.          }   
  316.          else   //衝突     
  317.          {   
  318.              do   
  319.              {   
  320.                  d=(d+NameList[NAME_NO-1].k%10+1)%M;   //偽隨機探測再雜湊法處理衝突       
  321.                  sum=sum+1;   //查詢次數加1       
  322.              }while (HashList[d].k!=0);   
  323.              HashList[d].k=NameList[NAME_NO-1].k;   
  324.              HashList[d].py=NameList[NAME_NO-1].py;   
  325.              HashList[d].si=sum+1;   
  326.          }   
  327.      }   
  328. }   
  329.    
  330.    
  331. void main()   
  332.    
  333. {   
  334.     char ch1;   
  335.     printf("\n                                雜湊表\n");   
  336.     printf("               *-------------------------------------------*\n");    
  337.     printf("               |              D. 顯示雜湊表                |\n");    
  338.     printf("               |              F. 查詢                      |\n");   
  339.     printf("               |              S. 刪除                      |\n");   
  340.     printf("               |              E. 插入                      |\n");   
  341.     printf("               |              Q. 退出                      |\n");   
  342.     printf("               *-------------------------------------------*\n");    
  343.     InitNameList();                                   
  344.     CreateHashList ();                           
  345.     while(1)   
  346.     {   
  347.         printf("\n       Option-:");   
  348.         fflush(stdin);   
  349.         ch1=getchar();   
  350.         if (ch1=='D'||ch1=='d')     
  351.             Display();      
  352.         else if (ch1=='F'||ch1=='f')    
  353.             FindList();   
  354.         else if (ch1=='S'||ch1=='s')   
  355.             DeleteList();   
  356.         else if (ch1=='E'||ch1=='e')   
  357.             EnterList();   
  358.         else if (ch1=='Q'||ch1=='q')    
  359.             return;   
  360.         else    
  361.         {    
  362.             printf("\n請輸入正確的選擇!");    
  363.         }   
  364.     }   
  365. }   

相關文章