C語言實現(xiàn)二叉樹的搜索及相關(guān)算法示例
本文實例講述了C語言實現(xiàn)二叉樹的搜索及相關(guān)算法。分享給大家供大家參考,具體如下:
二叉樹(二叉查找樹)是這樣一類的樹,父節(jié)點的左邊孩子的key都小于它,右邊孩子的key都大于它。
二叉樹在查找和存儲中通常能保持logn的查找、插入、刪除,以及前驅(qū)、后繼,最大值,最小值復(fù)雜度,并且不占用額外的空間。
這里演示二叉樹的搜索及相關(guān)算法:
#include<stack>
#include<queue>
using namespace std;
class tree_node{
public:
int key;
tree_node *left;
tree_node *right;
int tag;
tree_node(){
key = 0;
left = right = NULL;
tag = 0;
}
~tree_node(){}
};
void visit(int value){
printf("%d\n", value);
}
// 插入
tree_node * insert_tree(tree_node *root, tree_node* node){
if (!node){
return root;
}
if (!root){
root = node;
return root;
}
tree_node * p = root;
while (p){
if (node->key < p->key){
if (p->left){
p = p->left;
}
else{
p->left = node;
break;
}
}
else{
if (p->right){
p = p->right;
}
else{
p->right = node;
break;
}
}
}
return root;
}
// 查詢key所在node
tree_node* search_tree(tree_node* root, int key){
tree_node * p = root;
while (p){
if (key < p->key){
p = p->left;
}
else if (key > p->key){
p = p->right;
}
else{
return p;
}
}
return NULL;
}
// 創(chuàng)建樹
tree_node* create_tree(tree_node *t, int n){
tree_node * root = t;
for (int i = 1; i<n; i++){
insert_tree(root, t + i);
}
return root;
}
// 節(jié)點前驅(qū)
tree_node* tree_pre(tree_node* root){
if (!root->left){ return NULL; }
tree_node* p = root->left;
while (p->right){
p = p->right;
}
return p;
}
// 節(jié)點后繼
tree_node* tree_suc(tree_node* root){
if (!root->right){ return NULL; }
tree_node* p = root->right;
while (p->left){
p = p->left;
}
return p;
}
// 中序遍歷
void tree_walk_mid(tree_node *root){
if (!root){ return; }
tree_walk_mid(root->left);
visit(root->key);
tree_walk_mid(root->right);
}
// 中序遍歷非遞歸
void tree_walk_mid_norecursive(tree_node *root){
if (!root){ return; }
tree_node* p = root;
stack<tree_node*> s;
while (!s.empty() || p){
while (p){
s.push(p);
p = p->left;
}
if (!s.empty()){
p = s.top();
s.pop();
visit(p->key);
p = p->right;
}
}
}
// 前序遍歷
void tree_walk_pre(tree_node *root){
if (!root){ return; }
visit(root->key);
tree_walk_pre(root->left);
tree_walk_pre(root->right);
}
// 前序遍歷非遞歸
void tree_walk_pre_norecursive(tree_node *root){
if (!root){ return; }
stack<tree_node*> s;
tree_node* p = root;
s.push(p);
while (!s.empty()){
tree_node *node = s.top();
s.pop();
visit(node->key);
if (node->right){
s.push(node->right);
}
if (node->left){
s.push(node->left);
}
}
}
// 后序遍歷
void tree_walk_post(tree_node *root){
if (!root){ return; }
tree_walk_post(root->left);
tree_walk_post(root->right);
visit(root->key);
}
// 后序遍歷非遞歸
void tree_walk_post_norecursive(tree_node *root){
if (!root){ return; }
stack<tree_node*> s;
s.push(root);
while (!s.empty()){
tree_node * node = s.top();
if (node->tag != 1){
node->tag = 1;
if (node->right){
s.push(node->right);
}
if (node->left){
s.push(node->left);
}
}
else{
visit(node->key);
s.pop();
}
}
}
// 層級遍歷非遞歸
void tree_walk_level_norecursive(tree_node *root){
if (!root){ return; }
queue<tree_node*> q;
tree_node* p = root;
q.push(p);
while (!q.empty()){
tree_node *node = q.front();
q.pop();
visit(node->key);
if (node->left){
q.push(node->left);
}
if (node->right){
q.push(node->right);
}
}
}
// 拷貝樹
tree_node * tree_copy(tree_node *root){
if (!root){ return NULL; }
tree_node* newroot = new tree_node();
newroot->key = root->key;
newroot->left = tree_copy(root->left);
newroot->right = tree_copy(root->right);
return newroot;
}
// 拷貝樹
tree_node * tree_copy_norecursive(tree_node *root){
if (!root){ return NULL; }
tree_node* newroot = new tree_node();
newroot->key = root->key;
stack<tree_node*> s1, s2;
tree_node *p1 = root;
tree_node *p2 = newroot;
s1.push(root);
s2.push(newroot);
while (!s1.empty()){
tree_node* node1 = s1.top();
s1.pop();
tree_node* node2 = s2.top();
s2.pop();
if (node1->right){
s1.push(node1->right);
tree_node* newnode = new tree_node();
newnode->key = node1->right->key;
node2->right = newnode;
s2.push(newnode);
}
if (node1->left){
s1.push(node1->left);
tree_node* newnode = new tree_node();
newnode->key = node1->left->key;
node2->left = newnode;
s2.push(newnode);
}
}
return newroot;
}
int main(){
tree_node T[6];
for (int i = 0; i < 6; i++){
T[i].key = i*2;
}
T[0].key = 5;
tree_node* root = create_tree(T, 6);
//tree_walk_mid(root);
//tree_walk_mid_norecursive(root);
//tree_walk_pre(root);
//tree_walk_pre_norecursive(root);
//tree_walk_post(root);
//tree_walk_post_norecursive(root);
//tree_walk_level_norecursive(root);
visit(search_tree(root, 6)->key);
visit(tree_pre(root)->key);
visit(tree_suc(root)->key);
//tree_node* newroot = tree_copy_norecursive(root);
//tree_walk_mid(newroot);
return 0;
}
希望本文所述對大家C語言程序設(shè)計有所幫助。
相關(guān)文章
C++ 中l(wèi)ambda表達(dá)式的編譯器實現(xiàn)原理
C++ 11加入了一個非常重要的特性——Lambda表達(dá)式。這篇文章主要介紹了C++ 中l(wèi)ambda表達(dá)式的編譯器實現(xiàn)原理,需要的朋友可以參考下2017-02-02
C++?JSON庫?nlohmann::basic_json::accept的用法解析
nlohmann::basic_json::accept 是 Nlohmann JSON 庫中的一個方法,它用于檢查一個字符串是否可以解析為有效的 JSON,這篇文章主要介紹了C++?JSON庫nlohmann::basic_json::accept的用法,需要的朋友可以參考下2023-06-06
詳解C++ 多態(tài)的兩種形式(靜態(tài)、動態(tài))
這篇文章主要介紹了C++ 多態(tài)的兩種形式,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下2020-08-08
C語言三種函數(shù)調(diào)用約定_cdecl與_stdcall及_fastcall詳細(xì)講解
本篇文章使用的工具是vs2010,內(nèi)容可能涉及到匯編的知識,建議有一些匯編基礎(chǔ)的再來看,不過沒有匯編基礎(chǔ)也沒有關(guān)系,了解一下這三種調(diào)用約定即可2022-10-10
c語言中十進制轉(zhuǎn)二進制顯示小工具的實現(xiàn)代碼
本篇文章是對c語言中十進制轉(zhuǎn)二進制顯示小工具的實現(xiàn)代碼進行了詳細(xì)的分析的介紹,需要的朋友參考下2013-05-05
Unity3D實現(xiàn)經(jīng)典小游戲Pacman
這篇文章主要介紹了基于Unity3D制作一做個經(jīng)典小游戲Pacman,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Unity3D有一定的幫助,感興趣的小伙伴可以了解一下2021-12-12

