2叉树实现及其原理
相信原理在網上很多地方有很詳細的講解,個人轉載這篇文章這個鏈接作為參考,如下所示:
2叉樹原理詳解及其數據遍歷
源碼提供:這里面包含了前中后序的遞歸實現,也包含了前中序的棧/數組實現。其中網絡上很多源碼都是有一些小小的瑕疵,運行之后會出現各種各樣的問題,這份代碼是自己手寫的源碼,經過測試無誤!!!
/** BinTree.c** Created on: 2020年7月3日* Author: Leonard*/#include <stdio.h> #include <stdlib.h> #include <string.h>#include <assert.h>#define ARRAY_LENGTH 21typedef int KEY_VALUE;/*這段代碼還是很神奇的,可以做到結構題與業務分離的作用,可以用到實際的項目里去 :)*/ #define BSTREE_ENTRY(name,type) \struct name { \struct type *left; \struct type *right; \}typedef struct bst_treenode {KEY_VALUE data;BSTREE_ENTRY(, bst_treenode) bst;}TBST_TREE,*PBST_TREE;struct bstree {TBST_TREE *root; //根節點 };//創建節點 PBST_TREE CreateNewNode(KEY_VALUE value) {PBST_TREE node = NULL;node = (PBST_TREE)malloc(sizeof(TBST_TREE));if (node == NULL) {assert(0);}node->bst.left = node->bst.right = NULL;node->data = value;return node; }//插入 int bstInsert(struct bstree* T,KEY_VALUE value) {assert(T != NULL);PBST_TREE p = T->root;PBST_TREE node = T->root;if(T->root == NULL){T->root = CreateNewNode(value);return 1;}while(node != NULL) //先找某個最終插入的節點{p = node;if(node->data > value)node = node->bst.left;elsenode = node->bst.right;}if(p->data > value)p->bst.left = CreateNewNode(value);else if(p->data < value)p->bst.right = CreateNewNode(value);elsereturn 2; //同樣的節點不選擇插入進去return 0; }//刪除節點 int bstDelete(struct bstree* T,KEY_VALUE key) {assert(T != NULL);PBST_TREE tmp = T->root;PBST_TREE p = T->root;PBST_TREE pre = T->root;if(T->root == NULL)return -1;//找到節點while(p != NULL){tmp = p;if(key == p->data)break;else if(key > p->data)p = p->bst.right;elsep = p->bst.left;pre = tmp;}//沒找到if(p == NULL) return -2;//刪除根節點之后 這里選擇之前的右子樹的最左端插入,如果P沒有右子樹,直接將T->root = p的左子樹節點if(p == T->root){tmp = p->bst.right;while(tmp->bst.left != NULL && tmp)tmp = tmp->bst.left;if(tmp != NULL)T->root = p->bst.right;elseT->root = p->bst.left;}else{//step 1: 找到p的右子樹的最左節點tmp = p->bst.right;while(tmp->bst.left != NULL && tmp){tmp = tmp->bst.left;}tmp->bst.left = p->bst.left;//將p的左子樹插入到P的右子樹的最左節點的 左節點if(pre->bst.left->data == key){if(tmp != NULL)pre->bst.left = p->bst.right;elsepre->bst.left = p->bst.left;}else{if(tmp != NULL)pre->bst.right = p->bst.right;elsepre->bst.right = p->bst.left;}}free(p);p = NULL;return 0; }//先序 根 左 右 int bstPreSortPrint(PBST_TREE node) {if(node == NULL) return 0;printf("%4d",node->data);bstPreSortPrint(node->bst.left);bstPreSortPrint(node->bst.right); }//中序 左 根 右 int bstMidSortPrint(PBST_TREE node) {if(node == NULL) return 0;bstMidSortPrint(node->bst.left);printf("%4d",node->data);bstMidSortPrint(node->bst.right); }//后序 左右根 int bstBehSortPrint(PBST_TREE node) {if(node == NULL) return 0;bstBehSortPrint(node->bst.left);bstBehSortPrint(node->bst.right);printf("%4d",node->data); }// stack 先/中 序遍歷 0-preSort 1-midSort int OrderTraverseByStack(struct bstree *T,int mode) {assert(T);int top = 0;TBST_TREE* Stack[128] = {0}; //形象一點可以用棧實現,我這里用數組代替棧了PBST_TREE pRoot = T->root; //初始化if(T->root == NULL) return -1;while(pRoot || top > 0) //top>=0 會造成根節點的右子樹重復打印,故必須top>0來作為判斷條件{if(pRoot != NULL){Stack[top++] = pRoot;if(mode == 0)printf("%4d",pRoot->data);pRoot = pRoot->bst.left;}else{if(mode == 1)printf("%4d",Stack[top-1]->data);pRoot=Stack[--top]->bst.right;}}return 0; }/*這里的后序遍歷棧實現,可以使用兩個數組進行模擬棧實現,* 也可以用兩個棧來實現后序遍歷* 網上教程代碼也很多,可以參考著實現,這里就不再做過多的贅述 */int main(int argc,const char *argv[]) {int keyArray[ARRAY_LENGTH] = {24,25,13,35,23, 26,67,47,38,98, 20,17,49,12, 21,9,11,18,14,15,10};struct bstree T = {0};int i = 0;for (i = 0;i < ARRAY_LENGTH;i ++) {bstInsert(&T, keyArray[i]);}printf("first sort:\n");bstPreSortPrint(T.root);printf("\n");printf("stack first sort:\n");OrderTraverseByStack(&T,0);printf("\n");printf("Middle sort:\n");bstMidSortPrint(T.root);printf("\n");printf("stack middle sort:\n");OrderTraverseByStack(&T,1);printf("\n");printf("Behind sort:\n");bstBehSortPrint(T.root);printf("\n");//delete onebstDelete(&T,20);printf("first sort:\n");bstPreSortPrint(T.root);printf("\n");return 0; }?
總結
- 上一篇: 变配电所SF6气体泄漏及环境安全在线监测
- 下一篇: 111cccc