二叉樹(多路平衡搜索樹)-(代碼、分析、匯編)

目錄:

    • 代碼:
    • 分析:
    • 匯編:

代碼:

BTree.h

#ifndef _BTREE_H_
#define _BTREE_H_#define BT_LEFT 0 //定義左子節點標識
#define BT_RIGHT 1 //定義右子節點標識typedef void BTree;//定義樹類型
typedef unsigned long long BTPos;//定義樹位置類型typedef struct _tag_BTreeNode BTreeNode;//定義樹節點類型
struct _tag_BTreeNode
{BTreeNode* left;BTreeNode* right;
};typedef void (BTree_Printf)(BTreeNode*);//定義樹節點類型指針參數無返回值的函數類型BTree* BTree_Create();//聲明創建樹函數void BTree_Destroy(BTree* tree);//聲明銷毀樹函數void BTree_Clear(BTree* tree);//聲明清空樹函數int BTree_Insert(BTree* tree, BTreeNode* node, BTPos pos, int count, int flag);//聲明插入節點函數BTreeNode* BTree_Delete(BTree* tree, BTPos pos, int count);//聲明刪除節點函數BTreeNode* BTree_Get(BTree* tree, BTPos pos, int count);//聲明獲取節點函數BTreeNode* BTree_Root(BTree* tree);//聲明獲取根節點函數int BTree_Height(BTree* tree);//聲明獲取樹高度函數int BTree_Count(BTree* tree);//聲明獲取樹節點數量函數int BTree_Degree(BTree* tree);//聲明獲取樹度數函數void BTree_Display(BTree* tree, BTree_Printf* pFunc, int gap, char div);//聲明用函數處理每個節點的函數#endif

BTree.c

#include <stdio.h>
#include <malloc.h>
#include "BTree.h"typedef struct _tag_BTree TBTree;//定義實際使用樹類型
struct _tag_BTree
{int count;//節點數量BTreeNode* root;//根節點
};static void recursive_display(BTreeNode* node, BTree_Printf* pFunc, int format, int gap, char div) // 定義遞歸處理節點函數
{int i = 0;if( (node != NULL) && (pFunc != NULL) )//如果節點與函數指針不為空{for(i=0; i<format; i++)//輸出占位符{printf("%c", div);}pFunc(node);//對節點進行函數處理printf("\n");if( (node->left != NULL) || (node->right != NULL) )//如果左子節點或右子節點不為空{recursive_display(node->left, pFunc, format + gap, gap, div);//處理左子節點,占位符數量以gap遞增recursive_display(node->right, pFunc, format + gap, gap, div);//處理右子節點,占位符數量以gap遞增}}else//如果節點或函數指針為空 只輸出占位符{for(i=0; i<format; i++)//輸出占位符{printf("%c", div);}printf("\n");}
}static int recursive_count(BTreeNode* root) // 遞歸調用計算以一個節點開始下面所有子節點數量(包括第一次的節點本身)函數
{int ret = 0;if( root != NULL ){//遞歸調用每次調用只要不是空節點都會加1 數量ret = recursive_count(root->left) + 1 + recursive_count(root->right);}return ret;
}static int recursive_height(BTreeNode* root) // 定義遞歸計算樹高度的函數
{int ret = 0;if( root != NULL ){int lh = recursive_height(root->left);int rh = recursive_height(root->right);ret = ((lh > rh) ? lh : rh) + 1;//取左右兩邊節點較多的再加上本身節點}return ret;//返回高度
}static int recursive_degree(BTreeNode* root) //定義遞歸計算度數函數
{  //最大度數只會是2int ret = 0;if( root != NULL ){if( root->left != NULL ){ret++;}if( root->right != NULL ){ret++;}//如果是根節點是1,表示還不是最大度數,繼續往子節點尋找有沒有最大度數存在if( ret == 1 ){int ld = recursive_degree(root->left);int rd = recursive_degree(root->right);if( ret < ld )//如果該節點的左子節點中有度數比該節點大{ret = ld;//取左子節點返回的度數}if( ret < rd )//如果右子節點中有度數比現在度數{ret = rd;//取右子節點返回的度數}}}return ret;//返回最終度數 
}BTree* BTree_Create()//定義創建樹函數
{TBTree* ret = (TBTree*)malloc(sizeof(TBTree));//申請使用的樹空間if( ret != NULL )//申請成功{ret->count = 0;//數量為0ret->root = NULL;//根節點為空}return ret;//返回創建樹
}void BTree_Destroy(BTree* tree) // 定義銷毀樹函數
{free(tree);
}void BTree_Clear(BTree* tree) // 定義清空樹函數
{TBTree* btree = (TBTree*)tree;if( btree != NULL ){btree->count = 0;btree->root = NULL;}
}
/* count 表示插入節點的上面有多少層節點flag 表示原來該位置的節點位于插入節點的方向
*/
int BTree_Insert(BTree* tree, BTreeNode* node, BTPos pos, int count, int flag) // 定義插入節點函數
{TBTree* btree = (TBTree*)tree;//轉換成使用樹類型//判斷樹與插入節點不為空,和flag標識是左邊或右邊int ret = (btree != NULL) && (node != NULL) && ((flag == BT_LEFT) || (flag == BT_RIGHT));int bit = 0;if( ret ){BTreeNode* parent = NULL;BTreeNode* current = btree->root;node->left = NULL;//將插入節點的左子節點設空node->right = NULL;//將插入節點的右子節點設空while( (count > 0) && (current != NULL) )//找到插入的位置{bit = pos & 1;//判斷pos是奇數還是偶數 (奇數往右偶數往左)pos = pos >> 1;parent = current;//父節點賦值if( bit == BT_LEFT )//如果是左邊{current = current->left;//取得節點左子節點指向}else if( bit == BT_RIGHT )//如果是右邊{current = current->right;//取得節點右子節點指向}count--;}if( flag == BT_LEFT )//如插入位置是左子節點{node->left = current;//將本來在該位置的節點設為新插入節點的左子節點}else if( flag == BT_RIGHT )//如果插入位置是右子節點{node->right = current;//將本來在該位置的節點設為新插入節點的右子節點}if( parent != NULL )//如果父節點不為空{if( bit == BT_LEFT ){parent->left = node;//父節點的左子節點指向新插入節點 }else if( bit == BT_RIGHT ){parent->right = node;//父節點的右子節點指向新插入節點}}else//父節點為表示是{btree->root = node;//將新插入節點當作根節點}btree->count++;//樹節點數量增加}return ret;
}BTreeNode* BTree_Delete(BTree* tree, BTPos pos, int count) // 定義刪除節點函數
{/*注意:刪除節點后面,刪除的節點與其子節點都不在樹中,而且刪除的節點和其子節點的left和right 沒置空,還保持著對應關系 */TBTree* btree = (TBTree*)tree;//取得樹BTreeNode* ret = NULL; int bit = 0;if( btree != NULL )//樹不為空{BTreeNode* parent = NULL;BTreeNode* current = btree->root;//取得根節點while( (count > 0) && (current != NULL) )//取得刪除節點{bit = pos & 1;pos = pos >> 1;parent = current;if( bit == BT_LEFT ){current = current->left;}else if( bit == BT_RIGHT ){current = current->right;}count--;}if( parent != NULL )//如果父節點不為空{if( bit == BT_LEFT )//如果刪除節點是父節點的左邊{parent->left = NULL;//將父節點的左子節點置空不指向刪除節點了}else if( bit == BT_RIGHT )//如果刪除節點是父節點的右邊{parent->right = NULL;//將父節點的右子節點置空不指向刪除節點了}}else//如果父節點為空{btree->root = NULL;//直接將根節點置空}ret = current;//取得刪除節點//調用遞歸計算以刪除節點開始和其子節點數量,再總數減少得刪除該節點后樹的節點數btree->count = btree->count - recursive_count(ret);}return ret;//返回刪除節點
}BTreeNode* BTree_Get(BTree* tree, BTPos pos, int count) // 定義獲取節點函數
{TBTree* btree = (TBTree*)tree;//取得樹BTreeNode* ret = NULL; int bit = 0;if( btree != NULL )//樹不為空{BTreeNode* current = btree->root;//取得根節點while( (count > 0) && (current != NULL) )//找到要獲取的節點{bit = pos & 1;pos = pos >> 1;if( bit == BT_LEFT ){current = current->left;}else if( bit == BT_RIGHT ){current = current->right;}count--;}ret = current;//取得獲取節點}return ret;//返回獲取節點
}BTreeNode* BTree_Root(BTree* tree) // 定義獲取根節點函數
{TBTree* btree = (TBTree*)tree;//取得樹BTreeNode* ret = NULL;if( btree != NULL )//如果樹不為空{ret = btree->root;//取得根節點}return ret;//獲取根節點
}int BTree_Height(BTree* tree) // 定義獲取樹高度函數
{TBTree* btree = (TBTree*)tree;int ret = 0;if( btree != NULL )//如果查{ret = recursive_height(btree->root);//用根節點調用遞歸計算高度函數計算高度}return ret;//返回高度
}int BTree_Count(BTree* tree) // 定義獲取節點數量函數
{TBTree* btree = (TBTree*)tree;//取得樹int ret = 0;if( btree != NULL ){ret = btree->count;//取得樹節點數量}return ret;//返回數量
}int BTree_Degree(BTree* tree) // 定義獲取樹度數函數
{TBTree* btree = (TBTree*)tree;//取得樹int ret = 0;if( btree != NULL ){ret = recursive_degree(btree->root);//用根節點調用遞歸計算度數函數}return ret;//返回度數 
}void BTree_Display(BTree* tree, BTree_Printf* pFunc, int gap, char div) //定義使用函數統一處理節點信息函數
{TBTree* btree = (TBTree*)tree;//取得樹if( btree != NULL ){recursive_display(btree->root, pFunc, 0, gap, div);//調用遞歸處理函數}
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include "BTree.h"struct Node
{BTreeNode header;char v;
};void printf_data(BTreeNode* node)
{if( node != NULL ){printf("%c", ((struct Node*)node)->v);}
}int main(int argc, char *argv[])
{BTree* tree = BTree_Create();struct Node n1 = {{NULL, NULL}, 'A'};struct Node n2 = {{NULL, NULL}, 'B'};struct Node n3 = {{NULL, NULL}, 'C'};struct Node n4 = {{NULL, NULL}, 'D'};struct Node n5 = {{NULL, NULL}, 'E'};struct Node n6 = {{NULL, NULL}, 'F'};BTree_Insert(tree, (BTreeNode*)&n1, 0, 0, 0);BTree_Insert(tree, (BTreeNode*)&n2, 0x00, 1, 0);BTree_Insert(tree, (BTreeNode*)&n3, 0x01, 1, 0);BTree_Insert(tree, (BTreeNode*)&n4, 0x00, 2, 0);BTree_Insert(tree, (BTreeNode*)&n5, 0x02, 2, 0);BTree_Insert(tree, (BTreeNode*)&n6, 0x02, 3, 0);printf("Height: %d\n", BTree_Height(tree));printf("Degree: %d\n", BTree_Degree(tree));printf("Count: %d\n", BTree_Count(tree));printf("Position At (0x02, 2): %c\n", ((struct Node*)BTree_Get(tree, 0x02, 2))->v);printf("Full Tree: \n");BTree_Display(tree, printf_data, 4, '-');BTree_Delete(tree, 0x00, 1);printf("After Delete B: \n");printf("Height: %d\n", BTree_Height(tree));printf("Degree: %d\n", BTree_Degree(tree));printf("Count: %d\n", BTree_Count(tree));printf("Full Tree: \n");BTree_Display(tree, printf_data, 4, '-');BTree_Clear(tree);printf("After Clear: \n");printf("Height: %d\n", BTree_Height(tree));printf("Degree: %d\n", BTree_Degree(tree));printf("Count: %d\n", BTree_Count(tree));BTree_Display(tree, printf_data, 4, '-');BTree_Destroy(tree);getchar();return 0;
}

分析:

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

匯編:

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

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

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

相關文章

window service服務安裝錯誤

今天按照園子里面的文章&#xff0c;弄了一個系統服務&#xff0c;可是一直裝不上去&#xff0c; 正在運行事務處理安裝。 正在開始安裝的“安裝”階段。查看日志文件的內容以獲得 D:\TecCreateSvc\TecJsCreateService.exe 程序集的進度。該文件位于 D:\TecCreateSvc\TecJsCre…

DM9000調試記錄

最近在調試DM9000&#xff0c;遇到了很多問題&#xff0c;在網上幾乎也能找到同樣的問題&#xff0c;但是答案千變萬化&#xff0c;弄的我這樣不行&#xff0c;那樣也不行。 1、遇到的第一個問題&#xff0c;網卡不識別&#xff0c;出現的調試信息就是&#xff1a; dm9000 dm90…

Python---二分法查找

輸入n個數&#xff0c;通過二分法查找該數的下標 def binarySearch(arr,value):m 0#開始n len(arr#最后)while m<n:mid(mn)//2#計算中間位置if valuearr[mid]:#查找成功&#xff0c;返回元素對應的位置return midelif value>arr[mid]:#在后面一半元素中繼續查找mmid1e…

Python datetime isocalendar()方法與示例

Python datetime.isocalendar()方法 (Python datetime.isocalendar() Method) datetime.isocalendar() method is used to manipulate objects of datetime class of module datetime. datetime.isocalendar()方法用于操作模塊datetime的datetime類的對象。 It uses a dateti…

ASP.NET 技術(附翻譯)

1.構建 ASP.NET 頁面ASP.NET 和ASP.NET結構ASP.NET 是微軟.NET framework整體的一部分, 它包含一組大量的編程用的類&#xff0c;滿足各種編程需要。 在下列的二個部分中, 你如何學會 ASP.NET 很適合的放在.NET framework, 和學會能在你的 ASP.NET 頁面中使用語言。.NET類庫假想…

SQL捕獲異常

原文地址 http://technet.microsoft.com/zh-cn/office/ms179296%28vsql.100%29在 Transact-SQL 中使用 TRY...CATCHTransact-SQL 代碼中的錯誤可使用 TRY…CATCH 構造處理&#xff0c;此功能類似于 Microsoft Visual C 和 Microsoft Visual C# 語言的異常處理功能。TRY…CATCH …

二叉樹遍歷(代碼,分析,匯編)

目錄&#xff1a;代碼&#xff1a;分析&#xff1a;匯編&#xff1a;代碼&#xff1a; BTree.h BTree.c 二叉樹&#xff08;多路平衡搜索樹&#xff09; LinkQueue.h #ifndef _LINKQUEUE_H_ #define _LINKQUEUE_H_typedef void LinkQueue;//定義隊列類型LinkQueue* LinkQueu…

Java Vector insertElementAt()方法與示例

矢量類insertElementAt()方法 (Vector Class insertElementAt() method) insertElementAt() method is available in java.util package. insertElementAt()方法在java.util包中可用。 insertElementAt() method is used to set the given element (ele) at the given (indices…

Python---查找序列的最長遞增子序列

查找序列的最長遞增子序列 什么是序列的最長遞增子序列&#xff1f; 答&#xff1a;在一個數值序列中&#xff0c;找到一個子序列&#xff0c;使得這個子序列元素的數值依次遞增&#xff0c;并且這個子序列的長度盡可能地大。這就是所謂的最長遞增子序列 from itertools impo…

SendMessage和PostMessage

SendMessage 和 PostMessage 的區別 &#xff11;、首先是返回值意義的區別&#xff0c;我們先看一下 MSDN 里的聲明&#xff1a; LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);BOOL PostMessage( HWND hWnd…

ffmpeg-從mp4、flv、ts文件中提取264視頻流數據

ffmpeg-從mp4、flv、ts文件中提取264視頻流數據 main.c #include <stdio.h> #include <libavutil/log.h> #include <libavformat/avio.h> #include <libavformat/avformat.h>void proc(int need_to_annexb, char* in_file, char* out_file) {AVForma…

java timezone_Java TimeZone getDSTSavings()方法與示例

java timezoneTimeZone類的getDSTSavings()方法 (TimeZone Class getDSTSavings() method) getDSTSavings() method is available in java.util package. getDSTSavings()方法在java.util包中可用。 getDSTSavings() method is used to get the number of time differences in …

Photoshop 保存PNG格式交錯和不交錯有差別

1.PNG格式是由Netscape公司開發出來的格式&#xff0c;可以用于網絡圖像&#xff0c;但它不同于GIF格式圖像只能保存256色&#xff0c;PNG格式可以保存24位的真彩色圖像&#xff0c;并且支持透明背景和消除鋸齒邊緣的功能&#xff0c;可以在不失真的情況下壓縮保存圖像。但由于…

線索化二叉樹(代碼 、分析 、匯編)

目錄&#xff1a;代碼&#xff1a;分析&#xff1a;匯編&#xff1a;代碼&#xff1a; BTree.h BTree.c 二叉樹&#xff08;多路平衡搜索樹&#xff09; SeqList.h SeqList.c 順序表 main.c #include <stdio.h> #include <stdlib.h> #include "BTree.h&qu…

Python---尋找給定序列中相差最小的兩個數字

編寫函數&#xff0c;尋找給定序列中相差最小的兩個數字 def getTwoClosestElements(arr):#先進行排序&#xff0c;使得相鄰元素最接近#相差最小的元素必然相鄰seq sorted(arr)#先進行排序dif float(inf)#無窮大#遍歷所有元素&#xff0c;兩兩比較&#xff0c;比較相鄰元素的…

ubuntu 無線 共享 上網

配置DHCP服務器 使連接到此AP的電腦 自動獲取IP 1. 安裝軟件包&#xff1a;sudo apt-get install dhcp3-server2. 修改/etc/default/dhcp3-server配置文件INTERFACES"eth1" //eth1為無線網卡的名字3. 修改/etc/dhcp3/dhcpd.conf配置文件option domain-name-servers …

Java StringBuilder getChars()方法與示例

StringBuilder類的getChars()方法 (StringBuilder Class getChars() method) getChars() method is available in java.lang package. getChars()方法在java.lang包中可用。 getChars() method is used to copy all the characters from the given arguments (int src_st, int …

Python---利用蒙特.卡羅方法計算圓周率近似值

利用蒙特.卡羅方法計算圓周率近似值 什么是蒙特.卡羅方法&#xff1f; 答&#xff1a;蒙特卡羅方法是一種計算方法。原理是通過大量隨機樣本&#xff0c;去了解一個系統&#xff0c;進而得到所要計算的值。 正方形內部有一個相切的圓&#xff0c;它們的面積之比是π/4。 這里假…

不具有繼承關系的Delegate如何進行類型轉換?

- 引自:Artech 我們知道對于兩個不具有繼承關系的兩個類型&#xff0c;如果沒有為它們定義轉換器&#xff0c;兩這之間的類型轉換是不允許的&#xff0c;Delegate也是如此。但是有時候我們卻希望“兼容”的兩種Delegate類型能夠進行轉換&#xff0c;比較典型的就是表示事件的De…

Java屬性loadFromXML()方法與示例

屬性類loadFromXML()方法 (Properties Class loadFromXML() method) loadFromXML() method is available in java.util package. loadFromXML()方法在java.util包中可用。 loadFromXML() method is used to load all the properties denoted by the XML file on the given inpu…