链式邻接表与数组模拟邻接表 数组模拟哈希表与链式哈希表

#include<bits/stdc++.h>
using namespace std;
const int size=1e4;
struct edge    
{
    int to;
    edge *nxt;
};
struct ver  
{
    int head;
    edge *firsteg;
};
int vis[10000];
class alg
{
    private:
    ver hd[size]; //邻接表中的数组只有头结点数组,所挂链表所存储的只是与头结点相连的下标  
    int vernum;//顶点数
    int egnum;//边数
    public:
    alg(int a[],int n,int e)
    {
       edge *bt=nullptr;
       vernum=n;
       egnum=e;
       for(int i=0;i<vernum;i++)
       {
           hd[i].head=a[i];
           hd[i].firsteg=nullptr;
       }
       int from,to;
       for(int k=0;k<e;k++)
       {
           cin>>from>>to;// 头插法 
           bt=new edge;
           bt->to=to;
           bt->nxt=hd[from].firsteg;
           hd[from].firsteg=bt;
       }
    }
    ~alg()
    {
        edge *p=nullptr;
        edge *q=nullptr;
        for(int i=0;i<vernum;i++)
        {
            p=q=hd[i].firsteg;
            while(p!=nullptr)
            {
                p=p->nxt;
                delete q;
                q=p;
            }
        }
    }
    void bfs(int u)
    {
        int q[1000];
        int fr=-1,rear=-1;
        q[++rear]=u;
        vis[u]=1;
        edge *bt=nullptr;
        cout<<hd[u].head<<endl;
        int w;
        int v;
        while(fr!=rear)
        {
          w=q[++fr];
          cout<<hd[w].head<<endl;
          bt=hd[w].firsteg;
          while(bt!=nullptr)
          {
              v=bt->to;
              if(!vis[v])
              {
                  cout<<hd[v].head<<endl;
                  q[++rear]=v;
              }
              bt=bt->nxt;
          }
        }
    }
    int j;
    void dfs(int u)
    {
       edge *bt=nullptr;
       cout<<hd[u].head<<endl;
       vis[u]=1;
       bt=hd[u].firsteg;
       while(bt!=nullptr)
       {
           j=bt->to;
           if(vis[j]!=1)
           dfs(j);
           bt=bt->nxt;
       }
    }
};

#include<bits/stdc++.h>
using namespace std;
const int hash_size=1e4;
queue<int>q;
//数组模拟邻接表  头插法  不利于删除节点 
 //尾插法模拟可以使用vector实现 
struct node
{
    int to,nxt,val;
}mp[hash_size];
int head[hash_size];
int top;
void pre()
{
    memset(head,-1,sizeof head);
}
void add(int from,int to,int value)
{
   mp[top].to=to;
   mp[top].nxt=head[from];
   mp[top].val=value;
   head[from]=top++;
   //让head=-1是为了把mp[0]用上  如果初始化head为0的话,由于需要head的值为0做结束标志 浪费了一个空间 
}
/* 这里注意 if(-1) 的(-1) 为true ,只有if(0) 的(0)为false */
//~1 =-(1+1)=-2; ~0=-1 ~-1=0  ~-2=-(-2+1)=1;
//遍历 一个节点的所有邻接点
void bianli(int from)
{
    cout<<from<<endl;
    for(int i=head[from];~i;i=mp[i].nxt)
    {
        cout<<mp[i].to<<" "<<mp[i].val<<endl;
    }
}
void dfs(int u,int v)  //这种搜索方式在搜索树的时候可以不设vis   在搜索有环的图的时候要设立vis数组
{
    cout<<u<<endl; //单一的点上无权值  
    for(int i=head[u];~i;i=mp[i].nxt)
    {
        if(mp[i].to!=v)
        {
            cout<<mp[i].to<<" "<<mp[i].val<<endl;
            dfs(v,u);
        }
    }
}
//运用时按具体情况选用bfs还是dfs

//数组模拟哈希表
struct haxi
{
    int head[hash_size];
    int to[hash_size];
    int nxt[hash_size];
    int val[hash_size];
    int cnt;
    //to val 为映射 单射 to映射到val
    void pre()
    {
       cnt=0;
       memset(head ,-1,sizeof head);
       memset(to,0,sizeof to);
       memset(nxt,0,sizeof nxt);
       //重复使用时只有val无需初始化 
    }
    int id;
    void in(int t, int value)//插入
    {
       id=t%hash_size;
       if(~head[id])
       {
           nxt[cnt]=head[id];   //这里挂的链表和上面的邻接表模拟方法一样
       }
       head[id]=cnt;
       to[cnt]=t;
       val[cnt]=value;
       cnt++;
    }
    int i;
    int query(int t)//查询 
    {
        id=t%hash_size;
        if(~head[id])
        {
            for(i=head[id];~i;i=nxt[i])
            {
                if(t==to[i])
                {
                    return val[i];  
                }
            }
        }
        return -1;
    }
};
//   挂链表   实现拉链法哈希表------------------------
// 删除节点容易
struct dor
{
    int to;
    int val;
    dor *nxt;
};
class hx
{
   public :
   hx()
   {
     for(int i=0;i<100;i++)
     {
         ht[i]=nullptr;
     }
   }
   ~hx()
   {
       dor *p,*q;
       for(int i=0;i<100;i++)
       {
           p=q=ht[i];
           while(p!=nullptr) // p==null时不需要删除
           {
               p=p->nxt;
               delete q;
               q=p;
           }
       }
   }
   void in(int t,int v)//  头插法相比尾插法的时间较少   t与v之间建立映射
   {
       int j=t%100;
       dor *p;
       p=new dor;
       p->nxt=ht[j];
       ht[j]=p;
       p->val=v;
       p->to=t;
   }
   int query(int v) // 查询是否存在v值的映射
   {
      int j=v%100;
      dor *p=ht[j];
      while(p!=nullptr)
      {
          if(p->to==v)
          {
              return p->val;
          }
          p=p->nxt;
      }
      return -1;
   }
   int del(int v) //  删除从v到某个值的映射 
   {
      dor* bt;
      int j=v%100;
      bt=ht[j];
      dor*q;
      while(bt!=nullptr)
      {
         if(bt->to==v)
         {
             if(bt==ht[j])  // 注意头结点的特殊情况  
             {
                 ht[j]=bt->nxt;
                 delete bt;
                 return 1;
             }
             else 
             {
               q->nxt=bt->nxt;
               delete bt;
               return 1;  
             }
         }
         q=bt;
         bt=bt->nxt;
      }
      return -1;
   }
   private :
   dor* ht[100];
};
int main()
{
   pre();
   add(1,2,1);
   add(1,3,1);
   bianli(1);
   haxi hs;
   hs.pre();
   hs.in(1,2);
   hs.in(2,3);
   cout<<hs.query(0)<<endl;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值