資料結構實驗四---二叉樹
阿新 • • 發佈:2022-04-18
#include<bits/stdc++.h> using namespace std ; //二叉連結串列資料結構定義 typedef struct TNode { int data; struct TNode *lchild; struct TNode *rchild; } *BinTree, BinNode; int BuildTree(BinTree &bt) { cout << "輸入頭節點元素:(空頭節點輸入-1)"; int e;cin >> e ; if(e!=-1){ bt->data = e ; bt->lchild = NULL ; bt->rchild = NULL ; }else{ bt = NULL ; } } //求雙親結點(父結點) BinNode *Parent(BinTree tree, char x) { if (tree == NULL) return NULL; else if ((tree->lchild != NULL && tree->lchild->data == x) || (tree->rchild != NULL && tree->rchild->data == x)) return tree; else{ BinNode *node1 = Parent(tree->lchild, x); BinNode *node2 = Parent(tree->rchild, x); return node1 != NULL ? node1 : node2; } } //先序遍歷 void PreOrder(BinTree tree) { if (tree) { cout << tree->data << " " ; PreOrder(tree->lchild); PreOrder(tree->rchild); } } //中序 void InOrder(BinTree tree) { if (tree) { InOrder(tree->lchild); printf("%c ", tree->data); InOrder(tree->rchild); } } //後序 void PostOrder(BinTree tree) { if (tree) { PostOrder(tree->lchild); PostOrder(tree->rchild); printf("%c ", tree->data); } } //銷燬結點 遞迴free所有節點 void DestroyTree(BinTree *tree) { if (*tree != NULL) { printf("free %c \n", (*tree)->data); if ((*tree)->lchild) { DestroyTree(&((*tree)->lchild)); } if ((*tree)->rchild) { DestroyTree(&((*tree)->rchild)); } free(*tree); *tree = NULL; } } // 查詢元素為X的結點 使用的是層次遍歷 BinNode *FindNode(BinTree tree, char x) { if (tree == NULL) { return NULL; } //佇列 BinNode *nodes[1000] = {}; //佇列頭尾位置 int front = 0, real = 0; //將根節點插入到佇列尾 nodes[real] = tree; real += 1; //若佇列不為空則繼續 while (front != real) { //取出佇列頭結點輸出資料 BinNode *current = nodes[front]; if (current->data == x) { return current; } front++; //若當前節點還有子(左/右)節點則將結點加入佇列 if (current->lchild != NULL) { nodes[real] = current->lchild; real++; } if(current->rchild != NULL) { nodes[real] = current->rchild; real++; } } return NULL; } //層次遍歷 // 查詢元素為X的結點 使用的是層次遍歷 void LevelOrder(BinTree tree) { if (tree == NULL) { return; } //佇列 BinNode *nodes[1000] = {}; //佇列頭尾位置 int front = 0, real = 0; //將根節點插入到佇列尾 nodes[real] = tree; real += 1; //若佇列不為空則繼續 while (front != real) { //取出佇列頭結點輸出資料 BinNode *current = nodes[front]; printf("%2c", current->data); front++; //若當前節點還有子(左/右)節點則將結點加入佇列 if (current->lchild != NULL) { nodes[real] = current->lchild; real++; } if (current->rchild != NULL) { nodes[real] = current->rchild; real++; } } } //查詢x的左孩子 BinNode *Lchild(BinTree tree, char x) { BinTree node = FindNode(tree, x); if (node != NULL) { return node->lchild; } return NULL; } //查詢x的右孩子 BinNode *Rchild(BinTree tree, char x) { BinTree node = FindNode(tree, x); if (node != NULL) { return node->rchild; } return NULL; } //求葉子結點數量 int leafCount(BinTree *tree) { if (*tree == NULL) return 0; //若左右子樹都為空則該節點為葉子,且後續不用接續遞迴了 else if (!(*tree)->lchild && !(*tree)->rchild) return 1; else //若當前結點存在子樹,則遞迴左右子樹, 結果相加 return leafCount(&((*tree)->lchild)) + leafCount(&((*tree)->rchild)); } //求非葉子結點數量 int NotLeafCount(BinTree *tree) { if (*tree == NULL) return 0; //若該結點左右子樹均為空,則是葉子,且不用繼續遞迴 else if (!(*tree)->lchild && !(*tree)->rchild) return 0; else //若當前結點存在左右子樹,則是非葉子結點(數量+1),在遞迴獲取左右子樹中的非葉子結點,結果相加 return NotLeafCount(&((*tree)->lchild)) + NotLeafCount(&((*tree)->rchild)) + 1; } //求樹的高度(深度) int DepthCount(BinTree *tree) { if (*tree == NULL) return 0; else{ //當前節點不為空則深度+1 在加上子樹的高度, int lc = DepthCount(&((*tree)->lchild)) + 1; int rc = DepthCount(&((*tree)->rchild)) + 1; return lc > rc?lc:rc;// 取兩子樹深度的 最大值 } } //刪除左子樹 void RemoveLeft(BinNode *node){ if (!node) return; if (node->lchild) DestroyTree(&(node->lchild)); node->lchild = NULL; } //刪除右子樹 void RemoveRight(BinNode *node){ if (!node) return; if (node->rchild) DestroyTree(&(node->rchild)); node->rchild = NULL; } int main() { return 0; }