树的几种存储方法
作者:互联网
本文参考https://oi-wiki.org/graph/tree-basic/
理论上说,树作为图的一种,可以由图表示方法完全表示,那为什么要特地给出树的存储方法?因为树具有一个很特别的性质:每个节点要么没有父节点(根节点),要么有且只有一个根节点。这个性质为我们的树存储提供了新思路。下面提供几种树存储方法。
①只记录父节点
即只给出一个parent[N]数组来记录每个节点的父亲节点。这种方式可以获得的信息较少,不便于进行自顶向下的遍历。常用于自底向上的递推问题中。
②邻接表表示法
即记录与每个节点相连的子节点(利用vector数据结构),同时,如果节点存在较明显的上下层级关系,亦可再添加多余的parent[N]数组来存储父节点信息。
③左孩子右兄弟法
即给出child[N]与sib[N]数组,其中child记录自己的一个孩子,sib记录自己的一个兄弟。下面给出示例代码。
1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 using namespace std; 5 int child[100]; 6 int sib[100]; 7 int vis1[100]; 8 int vis2[100]; 9 int k;//树的枝节数 10 void dfs (int m){ 11 if (vis1[m]) return ; 12 cout<<m<<" "; 13 vis1[m]=1; 14 for (int i=child[m];i!=-1;i=sib[i]){ 15 dfs(i); 16 } 17 }//深度优先遍历 18 void bfs(int m){ 19 queue<int> q; 20 vis2[m]=1; 21 cout<<m<<" "; 22 q.push(m); 23 while(!q.empty()){ 24 int u=q.front(); 25 q.pop(); 26 for (int i=child[u];i!=-1;i=sib[i]){ 27 if (!vis2[i]){ 28 q.push(i); 29 vis2[i]=1; 30 cout<<i<<" "; 31 } 32 } 33 } 34 }//广度优先遍历 35 int main(){ 36 memset(child,-1,sizeof(child)); 37 memset(sib,-1,sizeof(sib)); 38 cin>>k; 39 for (int i=1;i<=k;i++){ 40 int u,v; 41 cin>>u>>v; 42 if (child[u]==-1){ 43 child[u]=v; 44 } 45 else{ 46 sib[v]=child[u]; 47 child[u]=v; 48 } 49 } 50 dfs(1); 51 cout<<endl; 52 bfs(1); 53 return 0; 54 }
④二叉树
设定child数组,child[N][1]为左孩子,child[N][2]为右孩子。
标签:存储,int,几种,sib,child,100,方法,节点 来源: https://www.cnblogs.com/johnsonstar/p/16646165.html