【使用層次序列構建二叉樹(數據結構C)】

使用層次序列構建二叉樹(C語言實現)

在這里插入圖片描述

在數據結構學習過程中,二叉樹的構建方式通常有遞歸建樹(前序/中序)層次建樹(廣度優先)兩種。本文將介紹一種基于輔助隊列實現的層次建樹方法,并結合前序、中序、后序遍歷結果來驗證構建的正確性。


🌳 示例結構

輸入層次序列:a b c d e f g

預期構建出的二叉樹結構如下:

        a/   \b     c/ \   / \d   e f   g

🧠 思路解析

層次建樹的關鍵是 廣度優先遍歷的順序插入節點。為了實現這一目標,我們需要:

  • 使用一個結構體指針隊列,保存待填左右孩子的節點。
  • 每讀入一個字符,就創建一個新樹節點,并嘗試插入到當前隊首節點的左或右孩子位置。
  • 如果左右孩子都已填滿,就將當前隊首出隊,指向下一個節點。

🛠? 關鍵數據結構

// 樹節點結構體
typedef struct BiTNode {char data;struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;// 輔助隊列節點(保存 BiTree 指針)
typedef struct tag {BiTNode *p;struct tag *pnext;
} tag_t, *ptag_t;

🧩 核心建樹邏輯

BiTree tree = NULL; // 根節點
ptag_t phead = NULL, ptail = NULL, listpnew = NULL, pre = NULL;
char c;while(scanf("%c", &c)) {if(c == '\n') break;BiTree pnew = (BiTree)calloc(1, sizeof(BiTNode));pnew->data = c;listpnew = (ptag_t)calloc(1, sizeof(tag_t));listpnew->p = pnew;if(tree == NULL) {tree = pnew;phead = ptail = listpnew;pre = listpnew;} else {ptail->pnext = listpnew;ptail = listpnew;if(pre->p->lchild == NULL) {pre->p->lchild = pnew;} else if(pre->p->rchild == NULL) {pre->p->rchild = pnew;pre = pre->pnext; // 移動到下一個節點}}
}

🔁 遍歷驗證

前序遍歷(PreOrder):

void PreOrder(BiTree p) {if(p != NULL) {printf("%c", p->data);PreOrder(p->lchild);PreOrder(p->rchild);}
}

中序遍歷(InOrder):

在這里插入圖片描述

void InOrder(BiTree p) {if(p != NULL) {InOrder(p->lchild);printf("%c", p->data);InOrder(p->rchild);}
}

后序遍歷(PostOrder):

void PostOrder(BiTree p) {if(p != NULL) {PostOrder(p->lchild);PostOrder(p->rchild);printf("%c", p->data);}
}

完整代碼

//層次建樹   借助一個輔助隊列
//          a
//        b   c
//    d   e   f   g#include <iostream>
#include<stdio.h>
#include<stdlib.h>//借助輔助隊列來進行建樹
typedef struct LinkNode{char datac; //數據結點}LinkNode; //建立一個結點//這里沒有使用標準的鏈隊列來實現 相應的層次建樹
typedef struct {LinkNode *front, *rear;
}LinkQueue;   //建立隊列#建立數的結點  使用的是鏈式的存儲typedef struct BiTNode{char data;struct BiTNode *lchild,*rchild;
}BiTNode , * BiTree;//而是建立一個輔助隊列 tag
typedef struct tag{
//    BiTree p;  //樹的某一結點的地址值BiTNode *p;struct tag *pnext;}tag_t , *ptag_t;//前序遍歷
void PreOrder(BiTree p){if(p!=NULL){printf("%c",p->data);PreOrder(p->lchild);PreOrder(p->rchild);}}//中序遍歷
void InOrder(BiTree p){if(p!=NULL){InOrder(p->lchild);printf("%c",p->data);InOrder(p->rchild);}}//后序遍歷
void PostOrder(BiTree p){if(p!=NULL){PostOrder(p->lchild);PostOrder(p->rchild);printf("%c",p->data);}
}int main() {BiTree pnew; //用來指向新申請的數結點BiTree tree =NULL; //tree 是指向樹根的,代表樹ptag_t phead= NULL,ptail =NULL, listpnew =NULL, pre =NULL; //初始化隊列 定義一個pre 指向執行的當前元素char c;//abcdefwhile(scanf("%c",&c)){if(c=='\n'){break;}//calloc申請空間  大小是兩個參數相乘,并對空間進行初始化  賦值為0;//malloc 申請以后還需要對其進行賦值 malloc 返回的是 void * 類型的 也需要進行強制轉換樹申請結點pnew =(BiTree) calloc(1,sizeof(BiTNode));pnew->data = c;//隊列結點申請空間listpnew = (ptag_t) calloc(1,sizeof(tag_t));  //申請一個結構體類型的結點 返回一個指針類型的listpnew->p =pnew;//如果是數的第一個結點if(tree==NULL){tree = pnew;  //tree 指向根的頭結點//第一個結點 即是隊列頭也是 隊列尾phead = ptail = listpnew;pre = listpnew; //  用來判斷當前結點 的左右孩子是否滿了}else {//元素直接入隊ptail ->pnext = listpnew;ptail =listpnew;//接下來把元素放入樹中if(pre->p->lchild ==NULL){pre ->p ->lchild =pnew;  // pre -> p 左孩子為空 就放入左孩子}else if(pre->p->rchild==NULL){pre->p->rchild =pnew;pre = pre->pnext;  // !!! 左右孩子都滿了,指向下一個節點}}}PreOrder(tree);printf("\n");InOrder(tree);printf("\n");PostOrder(tree);return 0;//這沒有對樹進行相應的輸出  ,使用調試發現建樹完成
}
//D:\TextOPT\C_CPP_code\For408\DateS\5\SqBinaryTree1\cmake-build-debug\SqBinaryTree1.exe
//123456789
//124895367
//849251637
//894526731

📌 完整輸出樣例

以輸入:abcdefg(按層次順序輸入,以回車結束)為例:

輸入:
abcdefg?輸出:
前序遍歷:abdecfg
中序遍歷:dbeafcg
后序遍歷:debgfca

輸出對應的樹結構:

        a/   \b     c/ \   / \d   e f   g

在這里插入圖片描述

? 總結

  • 使用輔助隊列可以按層次方式構建二叉樹,代碼邏輯清晰,效率也較高。
  • 在建樹過程中,記得及時更新隊列指針(例如 pre = pre->pnext;)以避免插入錯誤。
  • 可結合三種遍歷結果驗證建樹的正確性。

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

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

相關文章

設置Rocky Linux盒蓋不休眠的3個簡單步驟

在 Rocky linux&#xff08;和其他基于 RHEL 的發行版&#xff09;中&#xff0c;當你關閉筆記本電腦的蓋子時&#xff0c;默認行為通常是使系統休眠。如果你想更改這一行為&#xff0c;例如&#xff0c;使系統在關閉蓋子時只是鎖定&#xff0c;你可以按照以下步驟操作&#xf…

WPF的發展歷程

文章目錄 WPF的發展歷程引言起源與背景&#xff08;2001-2006&#xff09;從Avalon到WPF設計目標與創新理念 WPF核心技術特點與架構基礎架構與渲染模型關鍵技術特點MVVM架構模式 WPF在現代Windows開發中的地位與前景當前市場定位與其他微軟UI技術的關系未來發展前景 社區貢獻與…

【器件專題1——IGBT第1講】IGBT:電力電子領域的 “萬能開關”,如何撐起新能源時代?

一、IGBT 是什么&#xff1f;重新認識這個 “低調的電力心臟” 你可能沒聽過 IGBT&#xff0c;但一定用過它驅動的設備&#xff1a;家里的變頻空調、路上的電動汽車、屋頂的光伏逆變器&#xff0c;甚至高鐵和電網的核心部件里&#xff0c;都藏著這個 “電力電子開關的瑞士軍刀”…

新聞速遞丨Altair 與 Databricks 達成合作,加速數據驅動型創新

NEWS Altair 近日宣布與數據和人工智能公司 Databricks 達成戰略合作&#xff0c;通過新一代數據統一化、圖譜驅動智能和企業級人工智能&#xff08;AI&#xff09;技術賦能雙方客戶。 此次合作整合了兩大平臺的核心優勢&#xff0c;將 Altair RapidMiner 平臺的強大功能&…

c++11 :智能指針

目錄 一 為什么需要智能指針&#xff1f; 二 智能指針的使用及原理 1. RAII 2. auto_ptr 3. unique_ptr 4. shared_ptr 5. weak_ptr 三 內存泄漏 1.什么是內存泄漏&#xff0c;內存泄漏的危害 2. 如何避免內存泄漏&#xff1f; 一 為什么需要智能指針&#xff1f; …

大模型在直腸癌預測及治療方案制定中的應用研究

目錄 一、引言 1.1 研究背景與意義 1.2 研究目的 1.3 研究方法與創新點 二、大模型技術概述 2.1 大模型的基本原理 2.2 常見大模型類型及特點 2.3 在醫療領域的應用進展 三、直腸癌預測相關數據收集與處理 3.1 數據來源 3.2 數據清洗與預處理 3.3 特征工程 四、大…

VRRP與防火墻雙機熱備實驗

目錄 實驗一&#xff1a;VRRP負載均衡與故障切換 實驗拓撲?編輯一、實驗配置步驟 1. 基礎網絡配置 2. VRRP雙組配置 二、關鍵驗證命令 1. 查看VRRP狀態 2. 路由表驗證 三、流量分析 正常負載均衡場景&#xff1a; 故障切換驗證&#xff1a; 實驗二&#xff1a;防火…

OpenCV中的SIFT特征提取

文章目錄 引言一、SIFT算法概述二、OpenCV中的SIFT實現2.1 基本使用2.1.1 導入庫2.1.2 圖片預處理2.1.3 創建SIFT檢測器2.1.4 檢測關鍵點并計算描述符2.1.5 檢測關鍵點并計算描述符并對關鍵點可視化2.1.6 印關鍵點和描述符的形狀信息 2.2 參數調優 三、SIFT的優缺點分析3.1 優點…

【信息系統項目管理師】高分論文:論成本管理與采購管理(信用管理系統)

更多內容請見: 備考信息系統項目管理師-專欄介紹和目錄 文章目錄 論文1、規劃成本管理2、成本估算3、成本預算4、成本控制論文 2019年1月,我作為項目經理參與了 XX基金管理有限公司信用管理系統項目。該項目成 本1000萬,建設期為1年。通過該項目,XX基金管理有限公司在信用…

從邊緣到云端,如何通過時序數據庫 TDengine 實現數據的全局洞

在當今數字化轉型加速的背景下&#xff0c;海量的數據生成和實時處理需求已成為企業面臨的關鍵挑戰。無論是物聯網設備、工業自動化系統&#xff0c;還是智能城市的各類傳感器&#xff0c;數據的采集、傳輸與分析效率&#xff0c;直接影響企業的決策與運營。為此&#xff0c;TD…

Axure全局變量的含義與基礎應用

親愛的小伙伴,在您瀏覽之前,煩請關注一下,在此深表感謝! Axure產品經理精品視頻課已登錄CSDN可點擊學習https://edu.csdn.net/course/detail/40420 課程主題:全局變量 主要內容:全局變量含義、基礎應用 應用場景:元件賦值 案例展示: 案例視頻:

題目 3320: 藍橋杯2025年第十六屆省賽真題-產值調整

題目 3320: 藍橋杯2025年第十六屆省賽真題-產值調整 時間限制: 2s 內存限制: 192MB 提交: 549 解決: 122 題目描述 偏遠的小鎮上&#xff0c;三兄弟共同經營著一家小型礦業公司 “兄弟礦業”。公司旗下有三座礦山&#xff1a;金礦、銀礦和銅礦&#xff0c;它們的初始產值分別用…

常見緩存淘汰算法(LRU、LFU、FIFO)的區別與實現

一、前言 緩存淘汰算法主要用于在內存資源有限的情況下&#xff0c;優化緩存空間的使用效率。以確保緩存系統在容量不足時能夠智能地選擇需要移除的數據。 二、LRU&#xff08;Least Recently Used&#xff09; 核心思想&#xff1a;淘汰最久未被訪問的數據。實現方式&#x…

linux ptrace 圖文詳解(七) gdb、strace跟蹤系統調用

目錄 一、gdb/strace 跟蹤程序系統調用 二、實現原理 三、代碼實現 四、總結 &#xff08;代碼&#xff1a;linux 6.3.1&#xff0c;架構&#xff1a;arm64&#xff09; One look is worth a thousand words. —— Tess Flanders 相關鏈接&#xff1a; linux ptrace 圖…

Git基本使用(很詳細)

一&#xff1a;Git 概述 1.1 定義&#xff1a;分布式版本控制系統 1.2 版本控制 &#xff08;1&#xff09;定義&#xff1a; 版本控制時一種記錄文件內容變化&#xff0c;以便將來查閱特定版本修訂情況的系統 &#xff08;2&#xff09;舉例 多副本 優化&#xff1a; 不使用多…

23種設計模式-結構型模式之橋接模式(Java版本)

Java 橋接模式&#xff08;Bridge Pattern&#xff09;詳解 &#x1f309; 什么是橋接模式&#xff1f; 橋接模式用于將抽象部分與實現部分分離&#xff0c;使它們可以獨立變化。 通過在兩個獨立變化的維度之間建立“橋”&#xff0c;避免因多維度擴展導致的類爆炸。 &#x…

基于SIMMECHANICS的單自由度磁懸浮隔振器PID控制系統simulink建模與仿真

目錄 1.課題概述 2.系統仿真結果 3.核心程序與模型 4.系統原理簡介 4.1 單自由度磁懸浮減振器工作原理簡介 4.2 SIMMECHANICS工具箱 5.完整工程文件 1.課題概述 基于SIMMECHANICS的單自由度磁懸浮隔振器PID控制系統simulink建模與仿真。其中&#xff0c;SIMMECHANICS是M…

contenthash 持久化緩存

以下是關于持久化緩存(contenthash)的深度技術解析,涵蓋原理、配置策略及最佳實踐,幫助我們構建高性能前端應用的緩存體系: 一、緩存機制核心原理 1. 瀏覽器緩存決策矩陣 觸發條件緩存行為對應場景URL 未變化 + 強緩存有效直接讀取磁盤/內存緩存未修改的靜態資源URL 變化…

【前端記事】關于electron的入門使用

electron入門使用 背景how to start第一步 創建一個vite-vue3項目第二步 裝各種依賴第三步 配置vite.config.jspackage.jsonelectron入口 啟動重寫關閉、隱藏、最大化最小化 背景 最近對electron比較感興趣&#xff0c;折騰一段時間后有了點眉目&#xff0c;記錄一下 how to …

跨瀏覽器音頻錄制:實現兼容的音頻捕獲與WAV格式生成

在現代Web開發中&#xff0c;音頻錄制功能越來越受到開發者的關注。無論是在線會議、語音識別還是簡單的語音留言&#xff0c;音頻錄制都是一個重要的功能。然而&#xff0c;實現一個跨瀏覽器的音頻錄制功能并非易事&#xff0c;因為不同瀏覽器對音頻錄制API的支持存在差異。本…