C語言實現數據結構:堆排序和二叉樹_鏈式

在這里插入圖片描述


一.堆的應用

1.堆排序

void test01()
{int arr[] = { 17,20,10,13,19,15 };int n = sizeof(arr) / sizeof(arr[0]);HP p;HPInit(&p);for (int i = 0; i < n; i++){HPPush(&p, arr[i]);}int i = 0;while (!HPEmpty(&p)){arr[i++] = HPTop(&p);HPPop(&p);}for (int i = 0; i < n; i++){printf("%d ", arr[i]);}HPDesTroy(&p);
}

但是真正的堆排序不是我們上面這種寫法,堆排序是借助堆的算法思想,而不能夠直接使用堆的數據結構來輔助實現,這個時候我們來看一看怎么來實現堆的排序。

首先先將這三個我之前寫的算法放到我們頭文件里,可以用來直接使用。

void Swap(int* x, int* y);
void AdjustUp(HPDataType* arr, int child);
void AdjustDown(HPDataType* arr, int parent, int n);

(1)向下調整算法建堆的堆排序

我們建的是小堆

void HeapSort(int* arr, int n)
{//向下調整算法建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, i, n);}int end = n - 1;while (end){Swap(&arr[0], &arr[end]);AdjustDown(arr, 0, end);end--;}
}

測試

在這里插入圖片描述

建的是小堆,排的是降序的數組。所以排升序建大堆,排降序建小堆。

向下調整算法的最差的時間復雜度為O(logn)。
所以向下調整算法建堆的時間復雜度為:O(n×log n)。
總的來說,向下調整堆排序的時間復雜度就為:O(nlogn)。

(2)向上調整算法建堆的堆排序

我們這次來建一個大堆

	//向上調整算法建堆for (int i = 0; i < n; i++){AdjustUp(arr, i);}int end = n - 1;while (end){Swap(&arr[0], &arr[end]);AdjustDown(arr, 0, end);end--;}

測試

在這里插入圖片描述

向上調整算法最差的時間復雜度為:O(log n)。
向上調整算法建堆的時間復雜度:O(nlogn)
向上調整堆排序的時間復雜度:O(nlogn)。

我們通過總結得:向下調整算法建堆的時間復雜度比較好,越向下,結點個數逐漸增多,向下調整次數逐漸減少。向上調整算法建堆剛好相反。


二.實現鏈式結構二叉樹

用鏈表來表示一棵二叉樹,即用鏈來指示元素的邏輯關系。 通常的方法是鏈表中每個結點由三個域組成,數據域和左右指針域,左右指針分別用來給出該結點左孩子和右孩子所在的鏈結點的存儲地址,其二叉樹結點結構的定義如下:

1.二叉樹結點結構的定義

typedef int BTDataType;typedef struct BinaryTreeNode
{BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right;
}BTNode;

代碼實現

構造一棵二叉樹,將數據類型轉化成char。

2.獲取一個新結點

BTNode* buyNode(BTDataType x)
{BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));if (newnode == NULL){perror("molloc fail!");exit(1);}newnode->data = x;newnode->left = newnode->right = NULL;return newnode;
}

3.手動構造一棵二叉樹


BTNode* CreateTree()
{BTNode* nodeA = buyNode('A');BTNode* nodeB = buyNode('B');BTNode* nodeC = buyNode('C');BTNode* nodeD = buyNode('D');BTNode* nodeE = buyNode('E');BTNode* nodeF = buyNode('F');nodeA->left = nodeB;nodeA->right = nodeC;nodeB->left = nodeD;nodeC->left = nodeE;nodeC->right = nodeF;return nodeA;}

4.前序遍歷

void PreOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}printf("%c ", root->data);PreOrder(root->left);PreOrder(root->right);}

測試

在這里插入圖片描述

5.中序遍歷

void InOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}InOrder(root->left);printf("%c ", root->data);InOrder(root->right);}

測試

在這里插入圖片描述

6.后序遍歷

void PostOrder(BTNode* root)
{if (root == NULL){printf("NULL ");return;}PostOrder(root->left);PostOrder(root->right);printf("%c ", root->data);
}

測試

在這里插入圖片描述

7.二叉樹結點個數

int BinaryTreeSize(BTNode* root)
{if (root == NULL){return 0;}return BinaryTreeSize(root->left) + BinaryTreeSize(root->right) + 1;
}

8.二叉樹葉子結點個數

int BinaryTreeLeafSize(BTNode* root)
{if (root == NULL){return 0;}if (root->left == NULL && root->right == NULL){return 1;}return BinaryTreeLeaft(root->left) + BinaryTreeLeaft(root->right);
}

9.二叉樹第k層結點個數

int BinaryTreeLevelKSize(BTNode* root, int k)
{if (root == NULL){return 0;}if (k == 1){return 1;}return BinaryTreeLevelKSize(root->left,k-1) + BinaryTreeLevelKSize(root->right,k-1);
}

10.二叉樹的深度/高度

int BinaryTreeDepth(BTNode* root)
{if (root == NULL){return 0;}int leftDep = BinaryTreeDepth(root->left);int rihgtDep = BinaryTreeDepth(root->right);return 1 + (leftDep > rihgtDep ? leftDep : rihgtDep) ;
}

11.二叉樹查找值為x的結點

BTNode* BinaryTreeFind(BTNode* root, BTDataType x)
{if (root == NULL){return NULL;}if (root->data == x){return root;}BTNode* leftFind = BinaryTreeFind(root->left,x);if (leftFind){return leftFind;}BTNode* rightFind = BinaryTreeFind(root->right,x);if (rightFind){return rightFind;}return NULL;
}

12.二叉樹銷毀

void BinaryTreeDestroy(BTNode** root)
{if (*root == NULL){return;}BinaryTreeDestroy(&((*root)->left));BinaryTreeDestroy(&((*root)->right));free(*root);*root = NULL;
}

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

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

相關文章

C和指針——預處理

預處理是編譯前的過程&#xff0c;主要對define&#xff0c;include以及一些編譯器定義的內容進行替換 #define的本質就是替換 1、例子 #define FOREVER for(;;) 2、例子 #define TEMPD "1231231231\ 123123123" \\如果太長了&#xff0c;可以用\換行 3、例子——可…

C++ set和map

目錄 一、關聯式容器 1.1 鍵值對 1.1.1 概念 1.1.2 pair 1.2 樹形結構的關聯式容器 二、set 2.1 set 的介紹 2.2 set 的使用 2.2.1 set 的構造 2.2.2 set 的迭代器 2.2.3 set 的容量操作 2.2.4 set 的修改操作 2.2.5 set 的查找操作 三、multiset 3.1 multiset …

「Mac暢玩AIGC與多模態07」開發篇03 - 開發第一個 Agent 插件調用應用

一、概述 本篇介紹如何在 macOS 環境下,基于 Dify 平臺自帶的網頁爬蟲插件工具,開發一個可以提取網頁內容并作答的 Agent 應用。通過使用內置插件,無需自定義開發,即可實現基本的網頁信息提取與智能體回答整合。 二、環境準備 1. 確認本地部署環境 確保以下環境已搭建并…

cline或業務系統集成n8n的工作流(MCP Server Trigger、Call n8n Workflow Tool node)

1.成果展示 1.1n8n的主工作流 1.2n8n的子工作流 1.3cline集成效果 2.實操過程 2.1Call n8n Workflow Tool node節點 Call n8n Workflow Tool節點是一個工具&#xff0c;它允許代理運行另一個n8n工作流并獲取其輸出數據。 在此頁面上&#xff0c;您將找到“調用n8n工作流工具…

深入了解Linux系統—— 環境變量

命令行參數 我們知道&#xff0c;我們使用的指令它本質上也是一個程序&#xff0c;我們要執行這個指令&#xff0c;輸入指令名然后回車即可執行&#xff1b;但是對于指令帶選項&#xff0c;又是如何實現的呢&#xff1f; 問題&#xff1a;main函數有沒有參數&#xff1f; 在我…

pip安裝包時網絡不暢,替換國內PyPI鏡像源

1、PyPI 鏡像源 1.1、定義 PyPI 鏡像源是對 Python Package Index&#xff08;PyPI&#xff09;官方倉庫的復制。 PyPI 是 Python 社區中最大的軟件包倉庫&#xff0c;存儲著大量的 Python 包&#xff0c;供開發者們下載和使用。 然而&#xff0c;由于 PyPI 服務器位于國外&a…

貪心算法解決會議安排問題

文章目錄 前言 一、什么是貪心算法&#xff1f; 貪心算法的基本概念&#xff1a;貪心算法并不從整體最優上加以考慮&#xff0c;所做的選擇只是在某種意義上的局部最優選擇。 二、會議安排題目 1.題目理解 2.思路剖析 總結 前言 本文將主要介紹貪心算法需要注意的地方以…

從入門到登峰-嵌入式Tracker定位算法全景之旅 Part 4 |IMU 死算與校正:慣性導航在資源受限環境的落地

Part 4 |IMU 死算與校正:慣性導航在資源受限環境的落地 本章聚焦 ESP32-S3 平臺上如何利用 LSM6DS3 IMU 實現 死算(Dead Reckoning),并結合 零速更新(ZUPT) 或 磁力計輔助 進行 漂移校正,最終通過 EKF/UKF 融合提升定位精度。 一、傳感器簡介與校準 LSM6DS3 主要參數 加速…

力扣1128題解

記錄 2525.5.4 題目&#xff1a; 思路&#xff1a; 先將dominoes[i]的二元全部變為前大后小的形式&#xff0c;再遍歷該數組&#xff0c;用數組來記錄。 代碼&#xff1a; class Solution {public int numEquivDominoPairs(int[][] dominoes) {int [] [] cnt new int [10…

with的用法

Python SQLite 操作詳解 本文檔詳細解釋了使用 Python 操作 SQLite 數據庫時涉及的關鍵概念和代碼實踐&#xff0c;包括 with 語句、事務處理、批量插入以及相關的優化建議。 一、with 語句的作用&#xff08;自動關門的保險庫&#xff09; with sqlite3.connect(city_1301.d…

力扣解題匯總(困難)

文章目錄 技巧42_接雨水 技巧 42_接雨水 class Solution {public int trap(int[] height) {int LMax 0, RMax 0;int len height.length;int[] L2R new int[len];int[] R2L new int[len];//計數每一個格的左右邊最高柱for (int i 0; i < len; i) {LMax Math.max(LMa…

【Redis】Redis常用命令

4.Redis常見命令 4.1 Redis數據結構介紹 Redis是一個key-value的數據庫&#xff0c;key一般是String類型&#xff0c;不過value的類型多種多樣&#xff1a; 命令太多&#xff0c;不需要死記&#xff0c;學會查詢就好了~ Redis為了方便我們學習&#xff0c;將操作不同數據類型…

Ubuntu 系統上廣受好評的瀏覽器推薦

日常使用與開發者首選 Firefox 特點&#xff1a;開源、隱私保護強大&#xff0c;支持豐富擴展&#xff08;如開發者工具、廣告攔截&#xff09;&#xff0c;默認預裝且跨平臺兼容368。 適用場景&#xff1a;日常瀏覽、開發者調試&#xff08;支持實時 CSS/JS 編輯&#xff09;、…

Rust Trait 學習

概述 特征&#xff08;trait&#xff09;是rust中的概念&#xff0c;類似于其他語言中的接口&#xff08;interface&#xff09;。特征定義了一個可以被共享的行為&#xff0c;只要實現了特征&#xff0c;你就能使用該行為。 如果不同的類型具有相同的行為&#xff0c;那么我們…

JavaScript性能優化實戰(9):圖像與媒體資源優化

引言 在當今視覺驅動的網絡環境中,圖像和媒體資源往往占據了網頁總下載量的60%-80%,因此對圖像和媒體資源進行有效優化已成為前端性能提升的關鍵領域。盡管網絡帶寬持續提升,但用戶對加載速度的期望也在不斷提高,特別是在移動設備和網絡條件不穩定的場景下。 本文作為Jav…

NHANES指標推薦:LC9

文章題目&#xff1a;Association between lifes crucial 9 and kidney stones: a population-based study DOI&#xff1a;10.3389/fmed.2025.1558628 中文標題&#xff1a;生命的關鍵 9 與腎結石之間的關聯&#xff1a;一項基于人群的研究 發表雜志&#xff1a;Front Med 影響…

谷歌 NotebookLM 支持生成中文播客

谷歌 NotebookLM 支持生成中文播客。 2025 年 4 月 29 日&#xff0c;NotebookLM 宣布其 “音頻概覽”&#xff08;Audio Overviews&#xff09;功能新增 76 種語言支持&#xff0c;其中包括中文。用戶只需將文檔、筆記、研究材料等上傳至 NotebookLM&#xff0c;然后在設置中選…

ElasticSearch深入解析(十):字段膨脹(Mapping 爆炸)問題的解決思路

文章目錄 一、核心原理&#xff1a;動態映射的雙刃劍1. 動態映射的工作機制2. 映射爆炸的觸發條件3. 底層性能損耗 二、典型場景與案例分析1. 日志系統&#xff1a;動態標簽引發的災難2. 物聯網數據&#xff1a;設備屬性的無序擴展 三、系統性解決方案1. 架構層優化2. 配置層控…

交互式智能體面臨長周期決策和隨機環境反饋交互等挑戰 以及解決辦法

交互式智能體面臨長周期決策和隨機環境反饋交互等挑戰 以及解決辦法 目錄 交互式智能體面臨長周期決策和隨機環境反饋交互等挑戰 以及解決辦法隨機初始化參數,lora但是訓練需要更加細粒度的評價指數(對思考過程評價,對得出結果的證明評價,對結果評價)用戶進看到結果《RAGE…

4:機器人目標識別無序抓取程序二次開發

判斷文件是否存在 //判斷文件在不在 int HandEyeCalib::AnsysFileExists(QString FileAddr) {QFile File1(FileAddr);if(!File1.exists()){QMessageBox::warning(this,QString::fromLocal8Bit("提示"),FileAddrQString::fromLocal8Bit("文件不存在"));retu…