【算法/c++】利用中序遍歷和后序遍歷建二叉樹

目錄

  • 題目:樹的遍歷
    • 前言
    • 題目來源
    • 樹的數組存儲
      • 基本思想
      • 存儲規則
      • 示例
    • 建樹算法
      • 關鍵思路
      • 代碼
      • 總代碼
    • 鏈表法

題目:樹的遍歷

前言

如果不是完全二叉樹,使用數組模擬樹,會很浪費空間。

題目來源

本題來自 PTA 天梯賽。
題目鏈接: 樹的遍歷

題目描述
給定一棵二叉樹的后序遍歷和中序遍歷序列,輸出其層序遍歷的序列。假設樹中節點的鍵值均為互不相同的正整數。

輸入格式

  • 第一行:一個正整數 N(≤30),表示二叉樹的節點個數。
  • 第二行:后序遍歷序列,數字間以空格分隔。
  • 第三行:中序遍歷序列,數字間以空格分隔。

輸出格式

  • 輸出層序遍歷序列,數字間以 1 個空格分隔,行首尾不得有多余空格。

輸入樣例

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

輸出樣例

4 1 6 3 5 7 2

樹的數組存儲

基本思想

通過數組的索引關系表示樹的父子結構,無需顯式存儲指針。

存儲規則

  1. 根節點存儲在索引 1(注意不是 0)。
  2. 對于任意節點 i
    • 左子節點索引2 * i
    • 右子節點索引2 * i + 1
    • 父節點索引i / 2(整數除法)

示例

假設有一棵二叉樹:
在這里插入圖片描述
我們可以通過一個數組去存儲
在這里插入圖片描述
樹的索引對應數組的索引,樹節點的值存在數組里。

建樹算法

關鍵思路

  • 后序遍歷:最后一個元素是根節點
  • 中序遍歷:根節點左邊是左子樹,右邊是右子樹
  • 遞歸構建:分別處理左右子樹

后序遍歷:
結構: 左子樹 — 右子樹 — 根

中序遍歷:
結構: 左子樹,根,右子樹

我們通過中序遍歷找到根,就能知道左子樹的個數,那么我們就能找到后序遍歷左子樹的范圍,從而得知左子樹的根。右子樹同理。

算法過程:

1.確定根節點:

  • 從后序遍歷序列中取出最后一個元素,這就是當前子樹的根節點
  • 將這個根節點存入我們構建的樹結構中

2.在中序序列中定位根節點:

  • 在中序遍歷序列中查找這個根節點的位置
  • 這個位置將中序序列分為左子樹和右子樹兩部分

3.遞歸構建左右子樹

代碼

參數說明

  • root 后序序列中當前子樹的根節點索引
  • start 中序序列中當前子樹的起始索引
  • ed 中序序列中當前子樹的結束索引
  • idx 當前節點在tree數組中的存儲位置

變量說明

  • post 為后序遍歷數組
  • in 為中序遍歷數組
  • tree為存儲樹的數組
//根據中序遍歷和后續遍歷構造樹
void build(int root,int start,int ed,int idx)
{if(start>ed) return;//后序知道樹根,直接構造數組樹tree[idx] = post[root];//在中序遍歷中找根位置,用來區分后序遍歷左右子樹位置int i = start;while(i<ed && in[i] != post[root]) i++;//構造左子樹build(root - ed+i-1,start,i-1,idx*2);//構造右子樹build(root - 1,i+1,ed,idx*2+1);
}

總代碼

#include <iostream>
using namespace std;
#include <vector>const int N = 1e5+10;
int n;
int post[N],in[N];
vector<int> tree(N,-1);//根據中序遍歷和后續遍歷構造樹
void build(int root,int start,int ed,int idx)
{if(start>ed) return;//后序知道樹根,直接構造數組樹tree[idx] = post[root];//在中序遍歷中找根位置,用來區分后序遍歷左右子樹位置int i = start;while(i<ed && in[i] != post[root]) i++;//構造左子樹build(root - ed+i-1,start,i-1,idx*2);//構造右子樹build(root - 1,i+1,ed,idx*2+1);
}int main()
{cin  >> n;for(int i = 1;i<=n;i++)cin >>  post[i];for(int i = 1;i<=n;i++)cin >> in[i];build(n,1,n,1);vector<int> ans;for(int i = 1;i<tree.size();i++)if(tree[i] !=-1) ans.push_back(tree[i]);for(int i = 0;i<ans.size();i++)if(i != ans.size()-1)cout << ans[i]  <<  ' ';else cout << ans[i];return 0;
}

鏈表法

思路是差不多的

#include <iostream>
#include <queue>using namespace std;
const int N  =50;
int n;
int post[N],in[N];struct node
{int val;node* left;node* right;
};node* build(int root,int start,int ed)
{if(start>ed) return nullptr;//創建結點node * p = (node *) malloc(sizeof(node));p->val = post[root];//在中序遍歷中找根位置,用來區分后序遍歷左右子樹位置int i = start;while(i<ed && in[i] != post[root]) i++;p->left = build(root - ed+i-1,start,i-1);p->right = build(root - 1,i+1,ed);return p;
}void dfs(node *p)
{queue<node> q;q.push(*p);while(q.size()){node temp = q.front();q.pop();if(temp.val != p->val)cout << " ";cout << temp.val;if(temp.left != nullptr)  q.push(*temp.left);if(temp.right != nullptr) q.push(*temp.right);} 
}int main()
{cin >> n;for(int i = 1;i<=n;i++)cin >>  post[i];for(int i = 1;i<=n;i++)cin >> in[i];node* head = build(n,1,n);dfs(head);return 0;
}

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

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

相關文章

李臻20242817_安全文件傳輸系統項目報告_第6周

安全文件傳輸系統項目報告&#xff08;第 1 周&#xff09; 1. 代碼鏈接 Gitee 倉庫地址&#xff1a;https://gitee.com/li-zhen1215/homework/tree/master/Secure-file 代碼結構說明&#xff1a; project-root/├── src/ # 源代碼目錄│ ├── main.c # 主程序入口│ ├…

嵌入式rodata段

在嵌入式軟件開發中&#xff0c;將數據放入只讀數據段&#xff08;.rodata&#xff09;具有以下好處及典型應用示例&#xff1a; 好處 數據保護 .rodata段的內容在程序運行時不可修改&#xff0c;防止意外或惡意篡改&#xff0c;提升系統穩定性。 節省RAM資源 只讀數據可直接…

InfoSec Prep: OSCP靶場滲透

InfoSec Prep: OSCP InfoSec Prep: OSCP ~ VulnHubInfoSec Prep: OSCP, made by FalconSpy. Download & walkthrough links are available.https://www.vulnhub.com/entry/infosec-prep-oscp,508/ 1&#xff0c;將兩臺虛擬機網絡連接都改為NAT模式 2&#xff0c;攻擊機上做…

【JavaWeb-Spring boot】學習筆記

目錄 <<回到導覽Spring boot1. http協議1.1.請求協議1.2.響應協議 2.Tomcat2.1.請求2.1.1.apifox2.1.2.簡單參數2.1.3.實體參數2.1.4.數組集合參數2.1.5.日期參數2.1.6.(重點)JSON參數2.1.7.路徑參數 2.2.響應2.3.綜合練習 3.三層架構3.1.三層拆分3.2.分層解耦3.3.補充 &…

C++的多態-上

目錄 多態的概念 多態的定義及實現 1.虛函數 2. 多態的實現 2.1.多態構成條件 2.2.虛函數重寫的兩個例外 (1)協變(基類與派生類虛函數返回值類型不同) (2)析構函數的重寫(基類與派生類析構函數的名字不同) 2.3.多態的實現 2.4.多態在析構函數中的應用 2.5.多態構成條…

網絡安全的重要性與防護措施

隨著信息技術的飛速發展&#xff0c;互聯網已經成為我們日常生活、工作和學習的必需品。無論是通過社交媒體與朋友互動&#xff0c;還是在網上進行銀行交易&#xff0c;網絡已經滲透到我們生活的方方面面。然而&#xff0c;隨之而來的是各種網絡安全問題&#xff0c;包括數據泄…

CMake學習--Window下VSCode 中 CMake C++ 代碼調試操作方法

目錄 一、背景知識二、使用方法&#xff08;一&#xff09;安裝擴展&#xff08;二&#xff09;創建 CMake 項目&#xff08;三&#xff09;編寫代碼&#xff08;四&#xff09;配置 CMakeLists.txt&#xff08;五&#xff09;生成構建文件&#xff08;六&#xff09;開始調試 …

訪問數組元素(四十四)

1. 數組下標與類型 數組的索引從 0 開始。例如&#xff0c;一個包含 10 個元素的數組&#xff0c;其合法下標范圍為 0 到 9&#xff0c;而不是 1 到 10。為了表示下標&#xff0c;通常使用 size_t 類型&#xff0c;它是一種與機器相關的無符號整型&#xff0c;足夠大以存放內存…

計算機網絡 3-1 數據鏈路層(功能+組幀+差錯控制)

【考綱內容】 &#xff08;一&#xff09;數據鏈路層的功能 &#xff08;二&#xff09;組幀 &#xff08;三&#xff09;差錯控制 檢錯編碼&#xff1b;糾錯編碼 &#xff08;四&#xff09;流量控制與可靠傳輸機制 流量控制、可靠傳輸與滑動窗口機制&#xff1b;停止-等…

Django中使用不同種類緩存的完整案例

Django中使用不同種類緩存的完整案例 推薦超級課程: 本地離線DeepSeek AI方案部署實戰教程【完全版】Docker快速入門到精通Kubernetes入門到大師通關課AWS云服務快速入門實戰目錄 Django中使用不同種類緩存的完整案例步驟1:設置Django項目步驟2:設置URL路由步驟3:視圖級別…

Spring Boot 集成Redis 的Lua腳本詳解

1. 對比Lua腳本方案與Redis自身事務 對比表格 對比維度Redis事務&#xff08;MULTI/EXEC&#xff09;Lua腳本方案原子性事務命令序列化執行&#xff0c;但中間可被其他命令打斷&#xff0c;不保證原子性Lua腳本在Redis單線程中原子執行&#xff0c;不可中斷計算能力僅支持Red…

【大模型】DeepSeek + 藍耕MaaS平臺 + 海螺AI生成高質量視頻操作詳解

目錄 一、前言 二、藍耘智能云MaaS平臺介紹 2.1 藍耘智算平臺是什么 2.2 平臺優勢 2.3 平臺核心能力 三、海螺AI視頻介紹 3.1 海螺AI視頻是什么 3.2 海螺AI視頻主要功能 3.3 海螺AI視頻應用場景 3.4 海螺AI視頻核心優勢 3.5 項目git地址 四、藍耘MaaS平臺DeepSeek海…

12-產品經理-維護模塊

需求模塊是幫助產品經理進行需求的分類和維護。 1. 維護模塊 在具體產品的“研發需求”頁面左側&#xff0c;點擊“維護模塊”。也可以在具體產品的“設置”-“模塊”下進行維護。 點擊保存后&#xff0c;返回模塊頁面。還可以點擊“子模塊”對已有模塊進行子模塊的維護。 點擊…

考研單詞筆記 2025.04.06

area n領域&#xff0c;范圍&#xff0c;方面&#xff0c;地區&#xff0c;地方&#xff0c;場地&#xff0c;面積 aspect n方面&#xff0c;層面&#xff0c;外表&#xff0c;外觀 boundary n限度&#xff0c;界限&#xff0c;分界線&#xff0c;邊界 cap n最高限額&#x…

護網藍初面試題

《網安面試指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token1860256701&langzh_CN 5000篇網安資料庫https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247486065&idx2&snb30ade8200e842743339d428f414475e&chksmc0e4732df793fa3bf39…

玄機-apache日志分析

靶場任務 1、提交當天訪問次數最多的IP&#xff0c;即黑客IP&#xff1a; 查看apache日志 apache訪問日志的位置是&#xff1a;/var/log/apache2/access.log.1 匹配正則算法 首先先cat看看 發現地址都在第一行&#xff0c;直接匹配計算輸出 cat access.log.1 |grep -Eo &…

C++ I/O 流通俗指南

1. std::ostream 是什么&#xff1f; 定義&#xff1a;std::ostream 是 C 標準庫中的輸出流類&#xff0c;負責將數據輸出到各種目標&#xff08;如屏幕、文件、網絡等&#xff09;。你可以把 std::ostream 想象成一根“數據水管”&#xff1a; 數據從 C 代碼流進 std::ostrea…

Systemd 使用教程(二):Unit 的概念

目錄 【二】 Systemd 單元&#xff08;Unit&#xff09;的概念 本教程將由淺入深的介紹 linux 中 Systemd 的知識和相關使用&#xff08;同時也方便自己后續查閱&#xff09; 【二】 Systemd 單元&#xff08;Unit&#xff09;的概念 雖然我想介紹的比較偏實際操作&#xff0…

樹莓派PICO 設備燒錄成cmsis dap

文章目錄 1. 實際操作2. IO連接 1. 實際操作 2. IO連接

IntelliJ IDEA中Spring Boot 3.4.x+集成Redis 7.x:最新配置與實戰指南

?前言 Spring Boot 3.4.x作為當前?最新穩定版本?&#xff0c;全面支持Java 17與Jakarta EE 10規范。本文以?Spring Boot 3.4.1?和?Redis 7.x?為例&#xff0c;詳解如何在IDEA中快速接入Redis&#xff0c;涵蓋?最新依賴配置?、?數據序列化優化?、?緩存注解?及?高…