图:邻接表

大家直接看我在wolai写的这篇邻接表的,下面文章是凑字数滴。图也放不出来

(wolai是个好软件,首月开会员还免费,大家都快去用它,不打广)

邻接表的定义

  • **邻接表(Adjacency List)**是图的一种顺序存储与链式存储结合的存储方法。
  • 对于图G中的每个顶点Vi,将所有邻接于Vi的顶点Vj链成一个单链表,这个单链表就称为顶点Vi的邻接表,再将所有顶点的邻接表表头放到数组中,就构成了图的邻接表。
  • 在邻接表表示中,包括两种结点结构
  1. 一个是顶点结点,每个顶点结点由2个域组成,其中data域存储顶点Vi的名或其相关信息,firstArc指向顶点Vi的第一个邻接点的边结点;-
  2. 第二个是边结点,边结点由3个域组成。其中abjVex域存放与Vi邻接的点的序号,nextArc指向Vi下一个邻接点的边结点,info域存储和边或弧相关的信息,如权值,如图

为什么要使用邻接表

当图中的边数相对于顶点较少时,邻接矩阵是对存储空间的极大浪费。我们可以考虑对边或弧使用链式存储的方式来避免空间浪费的问题。使用树结构的孩子表示法,将结点存入数组,并对结点的孩子进行链式存储,不管有多少孩子,也不会存在空间浪费问题。

如果想知道某个顶点的度,就去查找这个顶点的边表中结点的个数。若要判断顶点vi和vj是否存在边,只需要测试顶点vi的边表adjvex中是否存在结点vj的下标就行了 我们很容易就可以算出某个顶点的入度或出度是多少,判断两顶点是否存在弧也很容易实现。

对于带权值的图,可以在边结点定义中再增加一个weight的数据域,存储权值信息即可

  • 有向图的代码实现(点击展开)
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
 
#define MAX 100

class ListDG {
private:
  class ENode {
  public:
    int ivex;    
    ENode* nextEdge;  
  };
 
  // 邻接表中表的顶点
  class VNode {
  public:
    char data;      
    ENode* firstEdge;  
  };
 
private: // 私有成员
  int mVexNum;      
  int mEdgNum;      
  VNode mVexs[MAX];    
 
public:

  ListDG();
  
  ListDG(char vexs[], int vlen, char edges[][2], int elen);
  ~ListDG();
 

  void print();
 
private:
  char readChar();
  int getPosition(char ch);
  void linkLast(ENode* list, ENode* node);
};
 
ListDG::ListDG() {
  char c1, c2;
  int v, e;
  int i, p1, p2;
  ENode* node1, * node2;
 
  cout << "input vertex number: ";
  cin >> mVexNum;
  cout << "input edge number: ";
  cin >> mEdgNum;
  if (mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum - 1)))) {
    cout << "input error: invalid parameters! " << endl;
    return;
  }
 
  for (i = 0; i < mVexNum; ++i) {
    cout << "vertex(" << i << "):";
    mVexs[i].data = readChar();
    mVexs[i].firstEdge = nullptr;
  }
 
  for (i = 0; i < mEdgNum; ++i) {
    cout << "edge(" << i << "):";
    c1 = readChar();
    c2 = readChar();
    p1 = getPosition(c1);
    p2 = getPosition(c2);
    // 初始化node1
    node1 = new ENode();
    node1->ivex = p2;
    if (mVexs[p1].firstEdge == nullptr)
      mVexs[p1].firstEdge = node1;
    else
      linkLast(mVexs[p1].firstEdge, node1);
  }
}
 
ListDG::ListDG(char vexs[], int vlen, char edges[][2], int elen) {
  char c1, c2;
  int i, p1, p2;
  ENode* node1, * node2;
 
  mVexNum = vlen;
  mEdgNum = elen;
  
  for (i = 0; i < mVexNum; i++)
  {
    mVexs[i].data = vexs[i];
    mVexs[i].firstEdge = NULL;
  }

  for (i = 0; i < mEdgNum; ++i) {
  
    c2 = edges[i][1];
 
    p1 = getPosition(c1);
    p2 = getPosition(c2);
    // 初始化node1
    node1 = new ENode();
    node1->ivex = p2;
    
    if (mVexs[p1].firstEdge == nullptr)
      mVexs[p1].firstEdge = node1;
    else
      linkLast(mVexs[p1].firstEdge, node1);
  }
}
 

ListDG::~ListDG() {
  
}

void ListDG::linkLast(ENode* list, ENode* node) {
  ENode* p = list;
 
  while (p->nextEdge)
    p = p->nextEdge;
  p->nextEdge = node;
}
 

int ListDG::getPosition(char ch) {
  int i;
  for (i = 0; i < mVexNum; ++i) 
    if (mVexs[i].data == ch)
      return i;
    return -1;
  
}
 

char ListDG::readChar() {
  char ch;
  do {
    cin >> ch;
  } while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
  return ch;
}
 

void ListDG::print() {
  int i, j;
  ENode* node;
  cout << "List Graph: " << endl;
  for (i = 0; i < mVexNum; ++i) {
    cout << i << "(" << mVexs[i].data << "):";
    node = mVexs[i].firstEdge;
    while (node != nullptr) {
      cout << node->ivex << "(" << mVexs[node->ivex].data << ") ";
      node = node->nextEdge;
    }
    cout << endl;
  }
}
int main() {
  char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
  char edges[][2] = {
    {'A', 'B'},
    {'B', 'C'},
    {'B', 'E'},
    {'B', 'F'},
    {'C', 'E'},
    {'D', 'C'},
    {'E', 'B'},
    {'E', 'D'},
    {'F', 'G'} 
  };
  int vlen = sizeof(vexs) / sizeof(vexs[0]);
  int elen = sizeof(edges) / sizeof(edges[0]);
  ListDG* pG;
 
  pG = new ListDG(vexs, vlen, edges, elen);
 
  pG->print();
  return 0;
  
}
  • 无向图的代码实现(点击展开)
#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;
 
constexpr auto MAX = 100;
class ListUDG {
private:

  
  class ENode {
  public:
    int ivex;    
    ENode* nextEdge;
  };
  class VNode {
  public:
    char data;   
    ENode* firstEdge;
  };
private:
  int mVexNum;    
  int mEdgNum;    
  VNode mVexs[MAX];  
public:
  
  ListUDG();
  
  ListUDG(char vexs[], int vlen, char edges[][2], int elen);
 
  ~ListUDG();
 
  void print();
private:
 
  char readChar();

  int getPosition(char ch);

  void linkLast(ENode* list, ENode* node);
};

ListUDG::ListUDG() {
  char c1, c2;
  
  int i, p1, p2;
  ENode* node1, * node2;
 
  cout << "input vertex number: ";
  cin >> mVexNum;
  cout << "input edge number: ";
  cin >> mEdgNum;
  if (mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum - 1)))) {
  cout << "input error: invalid parameters!" << endl;
  return;
}
 
  for (i = 0; i < mVexNum; ++i) {
    cout << "vertex(" << i << "):";
    mVexs[i].data = readChar();
    mVexs[i].firstEdge = nullptr;
  }
 
  for (i = 0; i < mEdgNum; ++i) {
 
    cout << "edge(" << i << "):";
    c1 = readChar();
    c2 = readChar();
 
    p1 = getPosition(c1);
    p2 = getPosition(c2);

    node1 = new ENode();
    node1->ivex = p2;

    if (mVexs[p1].firstEdge == nullptr)
      mVexs[p1].firstEdge = node1;
    else
      linkLast(mVexs[p1].firstEdge, node1);

    node2 = new ENode();
    node2->ivex = p1;
  
    if (mVexs[p2].firstEdge == nullptr)
      mVexs[p2].firstEdge = node2;
    else
      linkLast(mVexs[p2].firstEdge, node2);
  }
}

ListUDG::ListUDG(char vexs[], int vlen, char edges[][2], int elen) {
  char c1, c2;
  int i, p1, p2;
  ENode* node1, * node2;

  mVexNum = vlen;
  mEdgNum = elen;

  for (i = 0; i < mVexNum; ++i) {
    mVexs[i].data = vexs[i];
    mVexs[i].firstEdge = nullptr;
  }

  for (i = 0; i < mEdgNum; ++i) {

    c1 = edges[i][0];
    c2 = edges[i][1];
 
    p1 = getPosition(c1);
    p2 = getPosition(c2);
  
    node1 = new ENode();
    node1->ivex = p2;
  
    if (mVexs[p1].firstEdge == nullptr)
      mVexs[p1].firstEdge = node1;
    else
      linkLast(mVexs[p1].firstEdge, node1);
   
    node2 = new ENode();
    node2->ivex = p1;
  
    if (mVexs[p2].firstEdge == nullptr)
      mVexs[p2].firstEdge = node2;
    else
      linkLast(mVexs[p2].firstEdge, node2);
  }
}

ListUDG::~ListUDG() {
 
}

void ListUDG::linkLast(ENode* list, ENode* node) {
  ENode* p = list;
  while (p->nextEdge)
    p = p->nextEdge;
  p->nextEdge = node;
}

int ListUDG::getPosition(char ch) {
  int i;
  for (i = 0; i < mVexNum; ++i) 
    if (mVexs[i].data == ch)
      return i;
  return -1;
}

char ListUDG::readChar() {
  char ch;
  do {
    cin >> ch;
  } while  (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
  return ch;
}
 
void ListUDG::print() {
  int i, j;
  ENode* node;
  cout << "List Graph:" << endl;
  for (i = 0; i < mVexNum; ++i) {
    cout << i << "(" << mVexs[i].data << ")";
    node = mVexs[i].firstEdge;
    while (node != nullptr) {
      cout << node->ivex << "(" << mVexs[node->ivex].data << ")";
      node = node->nextEdge;
    }
    cout << endl;
  }
}
int main(){
  char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
  char edges[][2] = {
    {'A', 'C'},
    {'A', 'D'},
    {'A', 'F'},
    {'B', 'C'},
    {'C', 'D'},
    {'E', 'G'},
    {'F', 'G'} };
  int vlen = sizeof(vexs) / sizeof(vexs[0]);
  int elen = sizeof(edges) / sizeof(edges[0]);
  ListUDG* pG;
  pG = new ListUDG(vexs, vlen, edges, elen);
 
  pG->print();   
  
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值