2025春新生培訓數據結構(樹,圖)

教學目標:

1,清楚什么是樹和圖,了解基本概念,并且理解其應用場景

2,掌握一種建圖(樹)方法

3,掌握圖的dfs和樹的前中后序遍歷

例題與習題

2025NENU新生培訓(樹,圖)習題

引言

恭喜各位!當你學到圖和樹的內容的時候,已經結束了萌新的狀態。

大家想來已經早就聽過了關于樹和圖的傳說,但樹和圖到底是什么呢?又有什么用呢?

大家試想一下,我們現在已知的幾種數據結構:棧,隊列,鏈表......這些結構都有一個特點,就是線性的。

這些結構里,從前到后點與點之間的關系是1v1的,而我們不妨思考一下在如下情境中我們該如何存儲數據,我們要構造一個這樣的情景:

有許多的人,我們知道a比b年齡大,a比c大,d比c大,d比e大......該如何記錄這樣的信息呢?

如果你能獨立想明白的話,我想你已經獨立想出了算法中的一大突破,那就是樹與圖。

我們想一下應該怎么辦。是不是本能地想到應該記錄一下某個人a和所有與a有關系的人?而這顯然一個一維數組我們如果用下標來表示是誰,那么一個值通常是存不下來所有和他有關系的人的。因此我們可以用二維數組來存儲,用某一維表示a,然后另一維去存與a有關系的人。

舉個例子:

已知有三個人a, b, c, 已知a > b, b > c, a > c

我們可以用一個3 * 3 的數組來記錄它,用 1 來表示大于

? ? a? b? c

a? 0? 1? 1

b? 0? 0? 1

c? 0? 0? 0

這就是一個鄰接矩陣, 我們可以從中看出 a 比 b 大, a 比 c大, b 比 c 大

然而鄰接矩陣會用節點數目的平方的空間,因此這往往并不適用于節點數目較多而邊數較少的情況,所以我們往往會采用另一種方式鄰接表,在這種數據結構中,我們記錄和每一個頂點有關系的點。

這很方便,以上圖為例,如果我們用鄰接表的方式,我們所記錄的大概是這樣:

a : b c

b : c

c :

這同樣能夠記錄圖的結構,而消耗的空間很小。

第二種方式又有兩種不同的建圖方法分別是單鏈表和動態數組,在講解建圖方式之前,我們不如先來系統地講述一下圖和樹的基本概念:

樹與圖的基本概念

一、圖 (Graph)


正如我們前面所講,圖是一種由節點(頂點)和邊組成的數據結構,通常用于表示復雜的關系。與樹不同,圖不要求有層次關系,也不一定是連通的。

1. 圖的基本概念


頂點 (Vertex):圖中的節點。
邊 (Edge):連接兩個頂點的線,表示它們之間的關系。
有向圖 (Directed Graph):邊有方向,即從一個頂點指向另一個頂點。

什么樣的關系可以由有向圖表示?


無向圖 (Undirected Graph):邊沒有方向,表示兩個頂點之間的關系是雙向的。

什么樣的關系可以由無向圖表示?


鄰接矩陣 (Adjacency Matrix):使用二維數組表示圖的結構,適用于稠密圖。
鄰接表 (Adjacency List):使用鏈表數組或動態數組表示圖的結構,適用于稀疏圖。

二、樹(Tree)

樹是一種特殊的圖!樹是無環的連通圖。
樹是一種分層結構的非線性數據結構,由節點和邊組成。每個樹由一個根節點和零個或多個子樹組成。

1. 樹的基本概念
節點(Node):樹中的每個元素。
根節點(Root):樹的最頂端節點,沒有父節點。
父節點(Parent):一個節點的直接前驅節點。
子節點(Child):一個節點的直接后繼節點。
葉節點(Leaf):沒有子節點的節點。
高度(Height):樹中節點的層次,根節點的高度為0。
深度(Depth):節點到根節點的距離。


2. 樹的類型
二叉樹 (Binary Tree):每個節點最多有兩個子節點,通常稱為左子節點和右子節點。

完全二叉樹:從根結點到倒數第二層滿足完美二叉樹,最后一層可以不完全填充,其葉子結點都靠左對齊。

建圖

建圖(樹),

我們接下來以這道題為例,從代碼的角度來實現一個圖的建立,樹的建立與圖完全一致

一:鄰接矩陣建圖

節點數量為n

首先創建一個n * n 的二維數組A,初始值默認為0

對每一條由u到v的邊,A[u][v] = A[v][u] = 1

二:鄰接表建圖

動態數組:

創建一個二維動態數組vector<vector<int>> B(n + 1)

對每一條由u到v的邊,B[u].push_back(v), B[v].push_back(u)

鏈表(較難):

這種方法較難,相對來講比較傳統,大家可以自行了解

下面是這道題目的通過代碼,希望大家可以先自行嘗試解決這道問題

#include <bits/stdc++.h>using namespace std;const int N = 1010, M = 1e5 + 10;// 鄰接矩陣
int A[N][N];// 鄰接表
vector<vector<int>> B(N);int main()
{int n, m;cin >> n >> m;for (int i = 1; i <= m; i ++ ){int a, b;cin >> a >> b;// 鄰接矩陣存儲邊A[a][b] = A[b][a] = 1;// 鄰接表存儲邊B[a].push_back(b);B[b].push_back(a);}for (int i = 1; i <= n; i ++ ){for (int j = 1; j <= n; j ++ ){cout << A[i][j] << " ";}cout << endl;}for (int i = 1; i <= n; i ++ ){// 一個點相關的邊的數量等于這個點的度數cout << B[i].size() << " ";// 題目中要求從小到大輸出sort(B[i].begin(), B[i].end());for (auto b : B[i]){cout << b << " ";}cout << endl;}return 0;
}

圖(樹)的深度優先搜索

大家已經學習過在網格圖中如何進行搜索,那么在圖中該怎么進行搜索呢?我們這里僅講述dfs,bfs與其類似,大家可以課后自行嘗試

在網格圖中,我們通常使用上下左右四個方向來進行移動,但是在圖和樹中,一個點能移動到的位置是所有與其相連的點

我們用鄰接表來講的話,其dfs大概是這樣的

// 鄰接表
vector<vector<int>> B(N);// u是當前訪問的節點,fa是上一個節點
void dfs(int u, int fa)
{// b 是相連的點for (auto b : B[u]){// 如果不是父節點,就移動過去,這避免了在兩個點之間反復橫跳if (b != fa){dfs(b, u);}}
}

二叉樹的前中后遍歷

在前文中,我們如果要去遍歷圖,遍歷的順序取決于給出邊的順序

舉個例子,如果給出12 13 14, 我們會先訪問2, 再訪問3,再訪問4

如果給出的是 13 12 14, 這個時候,順序就變為了3 2 4

但是在二叉樹中,我們知道一個點可以有左子節點和右子節點,如果我們按照某種順序去訪問其左子節點右子節點和其本身,那么就會得到相對來講比較特殊的遍歷順序

前序遍歷:根結點 ---> 左子樹 ---> 右子樹

中序遍歷:左子樹--->?根結點?---> 右子樹

后序遍歷:左子樹 ---> 右子樹?---> 根結點

如果課堂時間有剩余或者大家學有余力的話,我們不如一起來思考一下這些問題:

如何記錄二叉樹的左子節點和右子節點?

如果用鏈表去做的話怎么做鄰接表?

在博客開頭的情境里,能否根據已有信息排列出一個明確的年齡順序,什么情況下可以?什么情況下不行?

結語

關于樹與圖的知識還有很多,歡迎大家有不懂的知識來問學長學姐,希望大家能夠通過思考提高自己的思維能力,算法能力猛猛進步!

感謝閱讀!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72210.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72210.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72210.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HTML 日常開發常用標簽

文章目錄 HTML 日常開發常用標簽1、基本結構標簽2、內容標簽3、多媒體標簽4、表單標簽5、列表和定義標簽6、表格標簽7、鏈接和圖像8、元數據9、語義化標簽&#xff08;HTML5新增&#xff09;10、框架和內聯11、交互12、過時或不推薦使用的標簽 HTML 日常開發常用標簽 1、基本結…

7.1.1 計算機網絡的組成

文章目錄 物理組成功能組成工作方式完整導圖 物理組成 計算機網絡是將分布在不同地域的計算機組織成系統&#xff0c;便于相互之間資源共享、傳遞信息。 計算機網絡的物理組成包括硬件和軟件。硬件中包含主機、前端處理器、連接設備、通信線路。軟件中包含協議和應用軟件。 功…

【AI論文】MedVLM-R1:通過強化學習激勵視覺語言模型(VLMs)的醫療推理能力

摘要&#xff1a;推理是推進醫學影像分析的關鍵前沿領域&#xff0c;其中透明度和可信度對于贏得臨床醫生信任和獲得監管批準起著核心作用。盡管醫學視覺語言模型&#xff08;VLMs&#xff09;在放射學任務中展現出巨大潛力&#xff0c;但大多數現有VLM僅給出最終答案&#xff…

國產RISCV64 也能跑AI

Banana Pi BPI-F3 進控時空 K1開發板 AI人工智能AI 部署工具使用手冊_bianbu software-CSDN博客 文章置頂了 有興趣的可以一起留言探索&#xff0c;非常有意思&#xff1a; 我最近接觸到了進迭時空研發的 Spacengine?&#xff0c;這是一套能在進迭時空 RISC-V 系列芯片上部署…

APISIX Dashboard上的配置操作

文章目錄 登錄配置路由配置消費者創建后端服務項目配置上游再創建一個路由測試 登錄 http://192.168.10.101:9000/user/login?redirect%2Fdashboard 根據docker 容器里的指定端口&#xff1a; 配置路由 通過apisix 的API管理接口來創建&#xff08;此路由&#xff0c;直接…

【WPF】綁定報錯:雙向綁定需要 Path 或 XPath

背景 最開始使用的是 TextBlock: <ItemsControl ItemsSource"{Binding CameraList}"><ItemsControl.ItemsPanel><ItemsPanelTemplate><StackPanel Orientation"Horizontal"/></ItemsPanelTemplate></ItemsControl.Item…

Kotlin協變與逆變區別

在Kotlin中&#xff0c;協變和逆變是泛型編程中的兩個重要概念&#xff0c;它們允許我們在類型系統中更加靈活地處理類型關系。 1.協變&#xff1a;協變允許我們使用比原始類型更具體的類型。在kotlin中&#xff0c;通過在類型參數上加out關鍵字來表示協變,生產者&#xff0c;例…

如何調試Linux內核?

通過創建一個最小的根文件系統&#xff0c;并使用QEMU和GDB進行調試。 1.準備工作環境 確保系統上安裝了所有必要的工具和依賴項。 sudo apt-get update //更新一下軟件包 sudo apt-get install build-essential git libncurses-dev bison flex libssl-dev qemu-system-x…

Java 調試模式下 Redisson 看門狗失效

一、場景分析 前幾天在做分布式鎖測試&#xff1a; 在調試模式下&#xff0c;lock.lock() 之后打上斷點&#xff0c;想測試一下在當前線程放棄鎖之前&#xff0c;別的線程能否獲取得到鎖。 發現調試模式下&#xff0c;看門狗機制失效了&#xff0c;Redis 上 30 秒后&#xff0…

GPT-4.5震撼登場,AI世界再掀波瀾!(3)

GPT-4.5震撼登場&#xff0c;AI世界再掀波瀾! GPT-4.5震撼登場&#xff0c;AI世界再掀波瀾!(2) &#xff08;一&#xff09;倫理困境&#xff1a;如何抉擇 GPT-4.5 的強大功能在為我們帶來諸多便利的同時&#xff0c;也引發了一系列深刻的倫理問題&#xff0c;這些問題猶如高…

【數據挖掘】Pandas

Pandas 是 Python 進行 數據挖掘 和 數據分析 的核心庫之一&#xff0c;提供了強大的 數據清洗、預處理、轉換、分析 和 可視化 功能。它通常與 NumPy、Matplotlib、Seaborn、Scikit-Learn 等庫結合使用&#xff0c;幫助構建高效的數據挖掘流程。 &#x1f4cc; 1. 讀取數據 P…

七、JOIN 語法詳解與實戰示例

一、JOIN 的作用與分類 JOIN 操作用于合并兩個或多個表的行&#xff0c;基于表之間的關聯字段。以下是常見的 JOIN 類型&#xff1a; JOIN 類型描述INNER JOIN返回兩個表匹配的記錄LEFT JOIN返回左表所有記錄 右表匹配記錄&#xff08;右表無匹配則為NULL&#xff09;RIGHT …

2019年01月全國POI數據分享(同源歷史POI分享系列)

2019年01月全國范圍POI數據 2019年01月份全國范圍歷史POI數據&#xff0c;全國范圍所有類別共59336781個POI 2019年01月全國范圍POI數據按大類統計 大類代碼大類名稱2019年01月該類POI數量010000汽車服務1151164020000汽車銷售213647030000汽車維修517367040000摩托車服務1800…

Spring Boot + MyBatis 實現 RESTful API 的完整流程

后端開發&#xff1a;Spring Boot 快速開發實戰 引言 在現代后端開發中&#xff0c;Spring Boot 因其輕量級、快速開發的特性而備受開發者青睞。本文將帶你從零開始&#xff0c;使用 Spring Boot MyBatis 實現一個完整的 RESTful API&#xff0c;并深入探討如何優雅地處理異…

使用Python開發以太坊智能合約:輕松入門與深度探索

使用Python開發以太坊智能合約&#xff1a;輕松入門與深度探索 隨著區塊鏈技術的快速發展&#xff0c;以太坊作為最為成熟和廣泛使用的智能合約平臺&#xff0c;成為了開發去中心化應用&#xff08;DApp&#xff09;的核心工具。智能合約不僅是區塊鏈技術的基礎&#xff0c;更…

ES scroll=1m:表示快照的有效時間為1分鐘。怎么理解

在Elasticsearch中&#xff0c;scroll1m 表示你創建的 scroll 上下文 的有效時間為 1分鐘。這個參數控制了你可以在多長時間內繼續使用這個 scroll_id 來獲取更多的數據。 什么是 Scroll 上下文&#xff1f; 當你使用 scroll API 時&#xff0c;Elasticsearch 會為你的查詢創…

Linux與UDP應用1:翻譯軟件

UDP應用1&#xff1a;翻譯軟件 本篇介紹 本篇基于UDP編程接口基本使用中封裝的服務器和客戶端進行改寫&#xff0c;基本功能如下&#xff1a; 從配置文件dict.txt讀取到所有的單詞和意思客戶端向服務端發送英文服務端向客戶端發送英文對應的中文意思 配置文件內容 下面的內…

Jeecg-Boot 開放接口開發實戰:在 Jeecg-Boot 的jeecg-system-biz中添加一個controller 實現免鑒權數據接口

Jeecg-Boot 開放接口開發實戰&#xff1a;在 Jeecg-Boot 的jeecg-system-biz中添加一個controller 實現免鑒權數據接口 一、場景需求分析 在微服務架構中&#xff0c;常需要快速實現以下兩類接口&#xff1a; 開放接口&#xff1a;無需登錄即可訪問&#xff08;如數據查詢、…

C++ ++++++++++

初始C 注釋 變量 常量 關鍵字 標識符命名規則 數據類型 C規定在創建一個變量或者常量時&#xff0c;必須要指定出相應的數據類型&#xff0c;否則無法給變量分配內存 整型 sizeof關鍵字 浮點型&#xff08;實型&#xff09; 有效位數保留七位&#xff0c;帶小數點。 這個是保…

構建安全的Docker基礎鏡像:從最佳實踐到自動化加固

引言 容器化技術的普及使得Docker鏡像成為軟件交付的核心載體,但鏡像中的安全漏洞、敏感信息泄露和權限配置不當等問題可能引發嚴重風險。本文結合OWASP容器安全指南與一線運維經驗,系統化講解如何構建安全的Docker基礎鏡像,覆蓋鏡像構建、依賴管理、運行時防護全鏈路,并提…