zoukankan      html  css  js  c++  java
  • 数据结构--散列(分离链接法解决冲突)

         散列方法的主要思想是根据结点的关键码值来确定其存储地址:以关键码值K为自变量,通过一定的函数关系h(K)(称为散列函数),计算出对应的函数值来,把这个值解释为结点的存储地址,将结点存入到此存储单元中。检索时,用同样的方法计算地址,然后到相应的

    单元里去取要找的结点。通过散列方法可以对结点进行快速检索。散列(hash,也称“哈希”)是一种重要的存储方式,也是一种常见的检索方法。

        因此,散列函数更像是一种映射,散列函数的选择有很多种,下面以散列函数为关键值对10取余为例,说明散列的插入关键字,删除关键字为例说明。

        代码如下:

    #include<iostream>
    using namespace std;
    
    struct ListNode;
    typedef struct ListNode *Position;
    struct Hash_table;
    typedef Hash_table *Hashtab;
    typedef Position List;
    
    #define Min_table_size 10
    
    struct ListNode
    {
       int Emelent;
       Position Next;
    };
    
    struct Hash_table
    {
       int Table_size;
       List *Thelist;
    };
    
    //////////////相关函数声明//////////////////////
    Hashtab Inittable (int Table_size);     //初始化一个散列
    Position Find (int x,Hashtab H);      //查找元素x,返回对应的位置
    int Hash (int x,int Table_size);  //散列函数
    void Insert (int Key, Hashtab H);   //在散列中插入元素Key
    void Delete (int Key, Hashtab H);   //在散列中删除元素Key
    
    
    
    ///////////////相关函数定义////////////////////
    Hashtab Inittable (int table_size)
    {
    	Hashtab H;
    	if(table_size < Min_table_size)
    	{
    	    cout << "Table size is too small" << endl;
    		return NULL;
    	}
    
    	H = (Hashtab)malloc(sizeof(Hash_table));
    	if(H == NULL)  cout << "out of space" << endl;
    	H->Table_size = table_size;
    	H->Thelist  = (List*)malloc(sizeof(Position) * H->Table_size);
    	if(H->Thelist == NULL) cout << "out of space" << endl;
    	for(int i = 0; i != H->Table_size; ++i)
    	{
    	   H->Thelist[i] = (Position)malloc(sizeof(ListNode));
    	   if(H->Thelist[i] == NULL) cout << "out of space" << endl;
    	   else
    	   {
    	      H->Thelist[i]->Next = NULL;
    		  H->Thelist[i]->Emelent = i;
    	   }
    		   
    	}
    	return H;
    }
    
    int Hash (int x)   //对10取余数
    {
       return x % 10;
    }
    
    Position Find (int x,Hashtab H)
    {
      Position P;
      List L;
    
      L = H->Thelist[Hash(x)];  //指向含有那个元素的表头
      P = L->Next;
      while(P != NULL && P->Emelent != x)
    	  P = P->Next;
      return P;
    }
    
    void Insert (int Key, Hashtab H)
    {
       Position Pos, Newcell;
       List L;
       Pos = Find(Key, H);  //先找找看,有没有Key,有就算了
       if(Pos == NULL )
       {
          Newcell = (Position)malloc(sizeof(ListNode));
    	  if(Newcell == NULL)  cout << "out of space" << endl;
    	  else    //插入到槽后面的第一个位置
    	  {
    	     L = H->Thelist[Hash(Key)];
    		 Newcell->Next = L->Next ;
    		 Newcell->Emelent = Key;
    		 L->Next = Newcell;
    	  }
       }
    }
    
    void Delete (int Key, Hashtab H)
    {
       Position p,Tmpcell;
       List L;
       p = Find(Key,H);
       if(p == NULL)
    	   cout << "not find the " << Key << endl;
       else
       {
          L = H->Thelist[Hash(Key)];
    	  p = L ;
    	  while(p->Next != NULL && p->Next->Emelent != Key)   //寻找Key的前驱节点
    	  {
    	     p = p->Next;
    	  }
    	  //
    	  Tmpcell = p->Next;
    	  p->Next = Tmpcell->Next;
    	  free(Tmpcell);
       }
    
    }
    int main ()
    {
      Hashtab H = Inittable (11);
      Insert (1, H);
      Insert (4, H);
      Insert (9, H);
      Insert (16, H);
      Insert (25, H);
       Insert (19, H);
       Insert (29, H);
       Delete(19,H);
     
      cout << H->Thelist[9]->Next->Next->Emelent << endl;
       return 0;
    }
    

      因为关键字和散列值不是一一对应的,这也正是散列函数的意义所在,所有就会产生冲突,上述代码解决冲突的办法为分离链接法。

          夜深了,,,

         

         她的背影犹如白色的影子。

         

         她一次都没有回头。

  • 相关阅读:
    IE8 "开发人员工具" 无法使用,无法显示
    Python中用OpenPyXL处理Excel表格
    calendar函数使用说明【转】
    python之fabric2.0模块学习
    Day9
    Day8
    深入super,看Python如何解决钻石继承难题——转自楚门蔡的测视界
    python/socket编程之粘包
    os模块关于目录
    Day7
  • 原文地址:https://www.cnblogs.com/1242118789lr/p/6809651.html
Copyright © 2011-2022 走看看