久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

圖的幾種存儲方式

 hdzgx 2019-11-19

圖的幾種存儲結構:

1,、鄰接矩陣

2,、鄰接表

3、鏈式前向星

4,、C++中vector的鄰接表實現(xiàn)(補充)

(一)鄰接矩陣

鄰接矩陣是表示頂點之間相鄰關系的矩陣,。

鄰接矩陣的好處:

(1)直觀、簡單,、好理解

(2)方便檢查任意一對定點間是否存在邊

(3)方便找任一頂點的所有“鄰接點”(有邊直接相連的頂點)

(4)方便計算任一頂點的度

對于無向圖,,鄰接矩陣的第i行(或第i列)非零元素(或非∞元素)的個數(shù)正好是第i個頂點的度。

對于有向圖,,鄰接矩陣的第i行(或第i列)非零元素(或非∞元素)的個數(shù)正好是第i個頂點的出度(或入度)。

鄰接矩陣的局限性:時間復雜度O(n^2),,空間復雜度O(n^2)

(1)浪費空間,。對于稠密圖還是很合算的。

                          但是對于稀疏圖(點很多而邊很少)有大量無效元素,。

(2)浪費時間,。要確定圖中有多少條邊,,則必須按行、按列對每個元素進行檢測,,所花費的時間代價很大,。

bb這么多,我們直接來以OJ此專題第一題為例

這題二維數(shù)組map不能用int,,會爆內存,,bool可以自己百度,簡而言之就是用于邏輯判斷,,只有true和false兩種情況,。

bool類型在存儲二值變量,或者說只有真假時,,更具優(yōu)勢,,因為只有0和1即false和true,省空間

(int型的0和1都是4字節(jié),,bool都是1字節(jié))

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdbool.h>
  4. bool map[5001][5001];
  5. int main()
  6. {
  7. int n,m;
  8. int u,v;
  9. int q;
  10. while(~scanf("%d %d",&n,&m))
  11. {
  12. memset(map,false,sizeof(map));
  13. while(m--)
  14. {
  15. scanf("%d %d",&u,&v);
  16. map[u][v]=true;
  17. }
  18. scanf("%d",&q);
  19. while(q--)
  20. {
  21. scanf("%d %d",&u,&v);
  22. if(map[u][v])
  23. {
  24. printf("Yes\n");
  25. }else
  26. {
  27. printf("No\n");
  28. }
  29. }
  30. }
  31. return 0;
  32. }

(二)鄰接表

圖的鄰接表存儲方法是一種順序分配與鏈式分配相結合的存儲方法,。

在鄰接表中,對圖中每個頂點建立一個單鏈表,,第i個單鏈表中的節(jié)點表示依附于頂點i的邊(對有向圖是以頂點i為尾的邊),。每個單鏈表上附設一個表頭節(jié)點。

鄰接表的特點如下:

(1)鄰接表表示不唯一,。這是因為在每個頂點對應的單鏈表中,,各邊節(jié)點的鏈接次序可以是任意的,取決于建立鄰接表的算法以及邊的輸入次序,。

(2)對于有n個頂點和e條邊的無向圖,,其鄰接表有n個頂點節(jié)點和2e個邊節(jié)點。顯然,,在總的邊數(shù)小于n(n-1)/2的情況下,,鄰接表比鄰接矩陣要節(jié)省空間。

(3)對于無向圖,,鄰接表的頂點i對應的第i個鏈表的邊節(jié)點數(shù)目正好是頂點i的度,。

(4)對于有向圖,鄰接表的頂點i對應的第i個鏈表的邊節(jié)點數(shù)目僅僅是頂點i的出度,。其入度為鄰接表中所有adjvex域值為i的邊節(jié)點數(shù)目,。
 

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. struct node
  5. {
  6. int data;
  7. struct node *next;
  8. };
  9. int main()
  10. {
  11. int n, u, j, i, v;
  12. struct node *p, *a[5050];
  13. while(~scanf("%d", &n))
  14. {
  15. for(i = 0; i < n; i++)
  16. a[i] = NULL;
  17. for(i = 0; i < n; i++)
  18. {
  19. for(j = 0; j < n; j++)
  20. {
  21. scanf("%d", &u); //審清題意
  22. if(u == 1)
  23. {
  24. if(a[i] == NULL)
  25. {
  26. p = (struct node *)malloc(sizeof(struct node));
  27. p -> data = j;
  28. p -> next = NULL;
  29. a[i] = p;
  30. }
  31. else
  32. {
  33. p = (struct node *)malloc(sizeof(struct node));
  34. p -> next = a[i] -> next;
  35. p -> data = j;
  36. a[i] -> next = p;
  37. }
  38. }
  39. }
  40. }
  41. int q;
  42. scanf("%d", &q);
  43. while(q--)
  44. {
  45. scanf("%d%d", &u, &v);
  46. p = a[u];
  47. int flag = 0;
  48. while(p)
  49. {
  50. if(p -> data == v)
  51. {
  52. flag = 1;
  53. break;
  54. }
  55. p = p -> next;
  56. }
  57. if(flag)
  58. printf("Yes\n");
  59. else
  60. printf("No\n");
  61. }
  62. }
  63. return 0;
  64. }

(三)鏈式前向星

 https://blog.csdn.net/Binary_Heap/article/details/78209086

1. 結構

這里用兩個東西:

1 結構體數(shù)組edge存邊,edge[i]表示第i條邊,

2 head[i]存以i為起點的第一條邊(在edge中的下標)

  1. struct edge{
  2. int to; //這條邊的終點
  3. int w; //權值
  4. int next; //下一條邊的存儲下標(默認0)
  5. }e[500010];

 

2.增邊

若以點u為起點的邊新增了一條,,在edge中的下標為cnt.

那么edge[++cnt].next=head[u];然后head[u]=cnt.

即每次新加的邊作為第一條邊,,最后倒序遍歷

  1. void add(int u, int v, int w)
  2. {
  3. e[cnt].to = v;
  4. e[cnt].w = w;
  5. e[cnt].next = head[u];//cnt為邊的計數(shù),從1開始計
  6. head[u] = cnt++; //第一條邊為當前邊
  7. }

 

3. 遍歷

遍歷以st為起點的邊

for(int i=head[st]; i!=0; i=edge[i].next)

 i 開始為第一條邊,每次指向下一條(以0為結束標志)  (若下標從0開始,,next應初始化-1)

鏈式前向星主要是用來優(yōu)化的,,可以用來優(yōu)化BFS,SPFA算法等等,。在做最短路的時候一直T就是因為沒有用鏈式前向星存邊導致的超時,,所以這個坑我先和你們說下。

(四)vector的鄰接表(補充)

vector是C++STL里面的一個東西,,簡單的來說就是一個可變長的數(shù)組,,你可以通過往它里面壓入數(shù)據(jù)來使它變長,

想深入了解的可以自己百度一波,,還是以這道題為例:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<vector>//注意這個頭文件不能丟,,要么你就去用萬能頭
  4. using namespace std;
  5. #define N 500001
  6. vector<int>MAP[N];//可以理解為二維的,每個MAP可以包含若干項,,這些項是以當前編號點為起點
  7. int main()
  8. {
  9. int n,m,u,v,i;
  10. while(~scanf("%d %d",&n,&m))
  11. {
  12. while(m--)
  13. {
  14. scanf("%d %d",&u,&v);
  15. MAP[u].push_back(v);//擴充
  16. }
  17. int q;
  18. scanf("%d",&q);
  19. while(q--)
  20. {
  21. scanf("%d %d",&u,&v);
  22. int len=MAP[u].size();
  23. int flag=0;
  24. for(i=0;i<len;i++)
  25. {
  26. if(MAP[u][i]==v)
  27. {
  28. flag=1;
  29. }
  30. }
  31. if(flag)
  32. {
  33. cout<<"Yes"<<endl;
  34. }else
  35. {
  36. cout<<"No"<<endl;
  37. }
  38. }
  39. for(int i=0; i<N; i++)
  40. {
  41. MAP[i].clear();
  42. }
  43. }
  44. return 0;
  45. }

嗯,,目前我用過的圖的幾種存儲方式就這樣啦,謝謝大家觀賞拙作,。

    本站是提供個人知識管理的網絡存儲空間,,所有內容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多