日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

邻接表十字链表

發布時間:2023/12/10 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 邻接表十字链表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鄰接表:


每一行都可以看成一個單鏈表,第一行中,v0-1-3可以得到,v0的出度為v1和v3。

鄰接表完整代碼:

#include <iostream> using namespace std;const int MAX_V = 15;//邊節點 typedef struct Edge_node {char data;Edge_node *next; }Enode,*pEnode;//表節點 typedef struct List_node {char data;Edge_node *firstEdge; }Lnode, *pLnode;int main() {void AddEdge( char v1, char v2, pLnode list, int V );void display( pLnode list, int V );void clear( pLnode list, int V);int V,E;cout << "input vertex number and edge number:\n";//輸入頂點數和邊數cin >> V >> E;Lnode list[MAX_V];//建立數組for( int i=0; i<V; ++i ){list[i].firstEdge = NULL;}cout << "input vertex:\n";//輸入頂點for( int i=0; i<V; ++i )cin >> list[i].data;cout << "input edges, eg: a b \n";char v1,v2;for( int i=0; i<E; ++i ){cin >> v1 >> v2;AddEdge( v1, v2, list, V);}//輸出cout <<"display:\n";display( list, V );cout << "clear:\n";clear( list, V );return 0; }void AddEdge( char v1, char v2, pLnode list, int V ) {for( int i=0; i<V; ++i ){if( v1==list[i].data ){//生成新的邊節點pEnode newEdge = new Enode;newEdge->data = v2;newEdge->next = NULL;newEdge->next = list[i].firstEdge;list[i].firstEdge = newEdge;break;}} }void display( pLnode list, int V ){for( int i=0; i<V; ++i ){cout << list[i].data <<": ";pEnode p = list[i].firstEdge;while( p ){cout << p->data << ' ';p = p->next;}cout <<endl;} }void clear( pLnode list, int V){for( int i=0; i<V; ++i ){pEnode p = list[i].firstEdge;pEnode todel;while( NULL!=p ){todel = p;cout <<"delete is "<< todel->data << ' ';p = p->next;delete todel;}cout << endl;}}

但對于有向圖來說,鄰接表是有缺陷的,關心了出度問題,想了解入度就必須要遍歷整個圖才能知道,反之,逆鄰接表解決了入度的情況。
而十字鏈表可以同時解決出度和入度的問題。

十字鏈表

重新定義表節點結構:增加了兩個指針firstIn,firstOut。分別用來指向該頂點的入(出)邊表中第一個結點。


firstin表示入邊表頭指針,指向該頂點的入邊表中第一個結點;

firstout表示出邊表頭指針,指向該頂點的出邊表中第一個結點;

tailvex是指弧起點在頂點的下標,

headvex是指弧終點在頂點表中的下標,

headlink是指入邊表指針域,指向終點相同的一下條邊

taillink是指出邊表指針域,指向起點相同的下一條邊。

對比

與鄰接表相比,這里的 tailLink 指針就相當于鄰接表里的那個指針,指向出度的下一個節點。而這里的 headLink 就是新增加的用來記錄入度的指針。

首先,橫著看:每一行都可以看出單鏈表,把從 firstOut 出來的串起來就是出度(類似鄰接表);
豎著看(不太明顯):從 headLink 出來的指針指向串起來,都是入度節點。

那為什么要重復存儲節點信息呢?例如圖中的0存了2次,1存了3次等。這是為了方便找入度節點。試想,鄰接表用一個指針一個節點信息來存儲方便找出度,那么要是出度入度都方便找,自然要給入度也加上一個指針(headLink)和一個數據域(tailVex)。這樣當找到入度的邊接節點,取出 headLink 就找到入度節點了。

將邊節點結構分割:
入度:headLink + tailVex;
出度:tailLink + headVex;

十字鏈表代碼:

#include <iostream> #include <cstring> using namespace std;const int MAX_V = 15; //邊節點 typedef struct Edge_node {char tailVex,headVex; //tailvex是指弧起點在頂點的下標,headvex是指弧終點在頂點表中的下標,Edge_node *tailLink, *headLink;//headlink指向弧頭相同的下一條弧。taillink指向弧尾相同的下一條弧. }Enode,*pEnode;//表節點 typedef struct List_node {char data;Edge_node *firstIn, *firstOut;//firstin表示入邊表頭指針,指向該頂點的入邊表中第一個結點. }Lnode, *pLnode;int main() {void AddEdge( char v1, char v2, pLnode list, int V );void display( pLnode list, int V );void clear( pLnode list, int V);int V,E;cout << "input vertex number and edge number:\n";//輸入頂點數和邊數cin >> V >> E;Lnode list[MAX_V];//建立數組for( int i=0; i<V; ++i ){list[i].firstIn = NULL;list[i].firstOut = NULL;}//輸入頂點cout << "input vertex:\n";for( int i=0; i<V; ++i )cin >> list[i].data;//輸入邊cout << "input edges, eg: a b \n";char v1,v2;for( int i=0; i<E; ++i ){cin >> v1 >> v2;AddEdge( v1, v2, list, V);}//輸出cout <<"display:\n";display( list, V );cout << "clear:\n";clear( list, V );return 0; }void AddEdge( char v1, char v2, pLnode list, int V ){int getIndex( char x , pLnode list , int V );int v1_index = getIndex( v1 , list, V );int v2_index = getIndex( v2, list ,V );pEnode newEdge = new Enode;newEdge->tailVex = v1;newEdge->headVex = v2;//添加出度newEdge->tailLink = list[v1_index].firstOut;list[v1_index].firstOut = newEdge;//添加入度newEdge->headLink = list[v2_index].firstIn;list[v2_index].firstIn = newEdge; } int getIndex( char x, pLnode list, int V ){for( int i=0; i<V; ++i ){if( x==list[i].data )return i;} }void display( pLnode list, int V ){for( int i=0; i<V; ++i ){cout << list[i].data <<" out : ";pEnode p = list[i].firstOut;while( p ){cout << p->headVex << ' ';p = p->tailLink;}cout <<endl;cout << list[i].data <<" in : ";p = list[i].firstIn;while( p ){cout << p->tailVex << ' ';p = p->headLink;}cout <<endl;}}void clear( pLnode list, int V){for( int i=0; i<V; ++i ){pEnode p = list[i].firstOut;pEnode todel;while( NULL!=p ){todel = p;cout <<"delete is "<< todel->headVex << ' ';p = p->tailLink;delete todel;}cout << endl;} }

總結

以上是生活随笔為你收集整理的邻接表十字链表的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。