CPP 数据结构学习 邻接表

终于弄明白邻接表这玩意了,说白了还是链表,只是存在多个头结点而已。

所以写法上大可以参照链表,用一个head数组保存头结点。

邻接表的好处还是挺多的,像这几天遇到的图论问题,使用邻接阵可能会引起MLE,或者,由于遍历了太多不必要的点,效率上也没有使用邻接表存储来的高。邻接阵最大好处,我想应该就是容易写,不易出错了吧。

于是,结合自己的理解,写了三套模板。一套使用指针(普通的动态链表,可扩展,但也容易出错),第二套套为静态链表,第三套是STL实现。

 

第一种动态链表:

 1 #include <iostream>
2 #include <cstdlib>
3 #include <ctime>
4 using namespace std;
5
6 const int MAXN = 1000;
7
8 struct NODE {
9 int v; //data field
10 struct NODE *prev; //pointer field
11 };
12 struct NODE* head[MAXN];
13
14 struct NODE* CreateChildNode(int v, struct NODE *prev)
15 {
16 struct NODE *node = (struct NODE*)malloc(sizeof(struct NODE));
17 node->v = v;
18 node->prev = prev;
19 return node;
20 }
21
22 void ClearAllNodes(int u)
23 {
24 struct NODE *p = head[u], *prev;
25 while(p != NULL)
26 {
27 prev = p->prev;
28 free(p);
29 p = prev;
30 }
31 head[u] = NULL;
32 }
33
34 void AppendNode(int u, int v)
35 {
36 if(head[u] == NULL)
37 {
38 head[u] = CreateChildNode(v, NULL); //create a head node
39 }
40 else
41 {
42 head[u] = CreateChildNode(v, head[u]); //create a child node belong to u
43 }
44 }
45
46 int main()
47 {
48 for(int i = 0; i < 500000; i++)
49 {
50 AppendNode(2, i);
51 }
52 ClearAllNodes(2);
53 //All operations will complete in 230ms, may a bit slow
54    //Clear all used nodes is required, or will cause memory leak.
55
56 return 0;
57 }


第二种静态链表:

 1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4
5 const int MAXN = 205;
6 const int MAXE = 500015;
7 struct NODE {
8 int v, next;
9 } e[MAXE];
10 int head[MAXN], k;
11
12 void AddEdge(int u, int v)
13 {
14 e[k].v = v;
15 e[k].next = head[u];
16 head[u] = k++;
17 }
18
19 int main()
20 {
21 k = 0;
22 memset(head, -1, sizeof(e));
23 for(int i = 0; i < 500005; i++)
24 {
25 AddEdge(2, i);
26 }
27 //An high efficient way, but it's not easy to insert a new element or delete one
28 return 0;
29 }


第三种用STL vector容器实现:

 1 #include <iostream>
2 #include <vector>
3 using namespace std;
4
5 vector<int> v[2000]; //由vector的数组形式构造邻接表
6
7 int main()
8 {
9 int head = 0, find = 4;
10 vector<int>::iterator it; //声明迭代器
11 //插入链表
12 for(int i = 0; i < 10; i++)
13 v[head].push_back(i);
14 //删除所有值为find的结点
15 for(it = v[head].begin(); it != v[head].end(); it++)
16 {
17 if(*it == find)
18 {
19 v[head].erase(it);
20 //请注意,当完成erase后,迭代器也就失效,变成野指针,RE
21 //如果要继续删除值为find的结点,需要重新初始化迭代器
22 it = v[head].begin();
23 }
24 }
25 //输出内容
26 for(it = v[head].begin(); it != v[head].end(); it++)
27 cout << *it << endl;
28 return 0;
29 }

 

posted @ 2012-03-04 15:10  dgsrz  阅读(244)  评论(0编辑  收藏  举报