詳細實現**參考:
資料結構定義:
//1 - 二叉鏈表示法
//節點型別為int
typedef struct bitnode
bitnode, *bitree;
//節點型別為char
typedef struct bitnodec
bitnodec, *bitreec;
實現:
void play01_2()
和二叉鏈表示法相比,多了乙個指向父節點的指標。
//2 - 三叉鏈表示法
typedef struct tritnode
tritnode, *tritree;
資料結構定義:
//3 - 雙親鍊錶表示法(子節點中儲存了雙親節點的位置)
#define max_tree_size 100
typedef struct bptnode
bptnode;
typedef struct bptree
bptree;
實現:
void play01_3()
}
# 法建立樹,讓樹的每乙個節點都變成度數為2的樹,其中沒有節點的補足#,如下所示:
此時,124###3##是可以確定一棵樹的,因為只有乙個節點後面跟了兩個#(##)就說明該節點為葉子節點。
bitreec createtree2(const char *s)
else
return node;
}const char *s = "abdh#k###e##cfi###g#j##"; //先序字串
bitreec p = nullptr;
p = createtree2(s);
基本思想:
中序和先序建立樹 演算法:
1、通過先序遍歷結果中找到根節點root,再通過root在中序遍歷結果中找出左子樹(左側)、右子樹(右側)
2、在root的左子樹中,找出左子樹的根節點(在先序結果中中找),轉步驟1;
3、在root的右子樹中,找出右子樹的根節點(在先序結果中中找),轉步驟1;
const string g_pre_str = "adebcf";
const string g_in_str = "deacfb";
string split_left(const string root_str, const char& root)
string in_str = root_str;
string left = in_str.substr(0, in_str.find(root));
return left;
}string split_right(const string root_str, const char& root)
string right = in_str.substr(in_str.find(root) + 1, in_str.length());
return right;
}char getroot(const string root_str)
return g_pre_str.at(pre_index);
}bitreec createtree_in_and_pre(const string root_str)
char root = getroot(root_str);
if ('\0' == root)
node = (bitreec)malloc(sizeof(bitnodec));
memset(node, 0, sizeof(bitnodec));
node->data = root;
string left_str = split_left(root_str, root);
string right_str = split_right(root_str, root);
node->lchild = createtree_in_and_pre(left_str);
node->rchild = createtree_in_and_pre(right_str);
return node;
}const char *pre = "adebcf";
const char *in = "deacfb";
bitreec p = nullptr;
p = createtree_in_and_pre(g_in_str);
先序建立樹則後續銷毀。
void freetree(bitreec t)
if (nullptr != t->rchild)
if(t)
return;
}
先序遍歷:中左右
//先序遍歷
void preorder(bitnode* root)
//列印根節點
cout << root->data << " ";
//然後 遍歷左子樹
preorder(root->lchild);
//最後 遍歷右子樹
preorder(root->rchild);
return;
}
中序遍歷:左中右
//中序遍歷
void inorder(bitnode* root)
//先 遍歷左子樹
inorder(root->lchild);
//然後 列印根節點的值
cout << root->data << " ";
//最後 遍歷右子樹
inorder(root->rchild);
return;
}
後序遍歷:左右中
//後序遍歷
void postorder(bitnode* root)
//先 遍歷左子樹
postorder(root->lchild);
//然後 遍歷右子樹
postorder(root->rchild);
//最後 列印根節點的值
cout << root->data << " ";
return;
}
樹的非遞迴遍歷(中序遍歷),演算法基本思想:
中序遍歷的幾種情況:
分析1:什麼時候訪問根?什麼時候訪問左子樹?什麼時候訪問右子樹?
當左子樹為空或者左子樹已經訪問完畢,再訪問根;
訪問根之後,再訪問右子樹;
分析2:為什麼是棧,而不是其他(比如 佇列)
先走到的後訪問,後走到的先訪問,顯示是站結構
分析3:節點所有路徑情況
步驟1: 找到中序遍歷的起點
如果節點 有 左子樹,該節點入棧,繼續找下乙個左子樹;
如果該節點 沒有 左子樹,訪問該節點;
步驟2:
如果節點 有 右子樹,走到右子樹的根節點,重複步驟1;
如果節點 沒有 右子樹(節點訪問完畢),根據棧頂指示訪問棧頂元素,並回退;
如果棧為空,表示遍歷結束;
注意:入棧的節點表示,本身沒有被訪問過,同時右子樹也沒有被訪問過。
using treestack = stack;
//步驟①:向左走,直到找到中序遍歷的起點
bitreec goleft(bitreec root, treestack &stack)
while (nullptr != root->lchild)
cout << root->data << " "; //節點沒有左子樹,直接訪問該節點
return root;
}//中序 非遞迴 遍歷
void inorder_stack(bitreec root)
treestack stack;
bitreec t = goleft(root, stack);
while (t)
else if(nullptr == t->rchild && !stack.empty())
else}}
int treedepth(bitnode* root)
//左子樹高度
leftdepth = treedepth(root->lchild);
//右子數高度
rightdepth = treedepth(root->rchild);
depth = 1 + (leftdepth>rightdepth?leftdepth:rightdepth);
return depth;
}
bitree treecopy(bitnode* root)
else
return nullptr;
if (root->rchild)
else
return nullptr;
*/ newnode = (bitree)malloc(sizeof(bitnode));
if (!newnode)
return nullptr;
newnode->lchild = newleft;
newnode->rchild = newright;
newnode->data = root->data;
return newnode;
}
資料結構 樹與二叉樹
一 性質 1 在二叉樹中,第i層的結點總數不超過2 i 1 2 深度為h的二叉樹最多有2 h 1個結點 h 1 最少有h個結點 3 對於任意一棵二叉樹,如果其葉結點數為n0,而度數為2的結點總數為n2,則n0 n2 1 4 具有n個結點的完全二叉樹的深度為int log2n 1 5 給定n個節點,能...
資料結構 樹與二叉樹
1 樹的定義 樹是一種 非線性的資料結構。樹是n n 0 個結點的有限集,在任意一棵非空樹中 1 有且僅有乙個特定的被稱為 根 root 的結點 2 當n 1時,其餘結點可分為m m 0 個互不相交的有限集,其中每個集合本身又是一棵樹,並且稱為根的 子樹 subtree 3 每棵子樹也是由唯一的根結...
資料結構 樹與二叉樹
樹是一類重要的非線性資料結構,是以分支關係定義的層次結構 定義 樹 tree 是n n 0 個結點的有限集t,其中 有且僅有乙個特定的結點,稱為樹的根 root 當n 1時,其餘結點可分為m m 0 個互不相交的有限集t1,t2,tm,其中每乙個集合本身又是一棵樹,稱為根的子樹 subtree 特點...