【數據結構】鏈式向前星知識點&代碼


代碼:

struct NODE{
    int to;
    int nxt;
    int c;
}node[MM];//鏈式向前星
int head[NM],lcnt=1;
void add(int a,int b,int c){
    node[lcnt].to=b;
    node[lcnt].c=c;
    node[lcnt].nxt=head[a];
    head[a]=lcnt++;
}
顯示神奇代碼

 

1.使用結構體構建鏈式向前星的容器

鏈式向前星本質上是使用鏈表存邊,一條鏈表代表着一個點發出的所有邊。所以一個這個結構體代表着這條鏈表中的一項

struct NODE{
	int to;     //指向下一條邊
	int nxt;    //指向同一個點發出的另一條邊
	int c;      //邊權
}node[MM];//鏈式向前星

 

2.第一條邊——head和邊的編號

NM是一個常量,代表着點的數量;

head代表着一條鏈表的第一個項,也就是一個點所發出的第一條邊(第一的意思是可以從這鏈表的這一項一直跳完所有項),至於如何實現請看 3 部分。

lcnt是賦予邊編號的變量,之所以初始化為1,請看 4 部分。

int head[NM];
int lcnt=1;

 

3.三個變量一台戲——如何加邊(add)

a,b,c分別代表入邊,出邊,權值

這個函數設置編號為lcnt的邊,將to指向的是節點編號

重點在nxt的操作上。將nxt賦值為a節點的“第一條邊”,那么就是說這個點接下來的可以跳的邊或者說鏈表的項是 head[a]

接下來將”第一條邊”賦值為當前的編號,那么下一次添加以a為源點的邊可以跳的邊或者說鏈表的項就是現在的邊或者說項了。

那就意味着最后一次添加的邊(項),可以一直跳到第一次添加的邊(項),也就符合我們在第 2 條定義的“第一條邊”了。

別忘了將編號++,以便下次使用。

void add(int a,int b,int c){     //改變編號為lcnt的邊
	node[lcnt].to=b;         //出邊指向b
	node[lcnt].c=c;          //記錄權值
	node[lcnt].nxt=head[a];  //將其指向目前的”第一條邊“,也就是說能跳到”第一條邊”
	head[a]=lcnt++;          //“第一條邊”更新為目前的編號,那么下一條邊能夠跳到這一條邊,那么最后的head自然就是真正的“第一條邊”了;編號++一遍下次使用
}

  

 

4.遍歷某個點所連接的所有邊

要遍歷就可以利用前面求出的”第一條邊“和這些鏈表了。

自然可以用for,從一開始將循環變量i初始化為要遍歷的源點k的”第一條邊“,head[k]

在判斷的時候,判斷是否還有下一條邊,這時候就是lcnt初始化為1的作用了。如果沒有初始化為1,就會存在編號為0的點,判斷就會誤認為已經結束了。

於是判斷就必須寫i!=-1了,但是打"=1"只需要兩個字符,而"i!=-1"比起"i"要多4個字符,而且不符合我們人類的思維習慣:從1開始,所以我們采用lcnt初始化為1

(“i”在C++里的意思是簡寫的 i!=0 )

然后到每次循環結束做的改變,自然是直接跳到鏈表的下一項。

for(int i=head[k];i;i=node[i].nxt){
	int u=node[i].to;
	//u就是所連接的點
     int v=node[i].c;
     //v就是邊的權值
}

 

 

5.注意雙向邊

如果你的題目要求是雙向邊的話,加邊操作需要進行兩次:

add(a,b,c);
add(b,a,c);  

注意,這時候node數組需要開兩倍於邊數的空間

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM