二叉排序樹的建立(結點的插入,刪除等操作)
阿新 • • 發佈:2019-01-10
二叉排序樹的理論看課本
程式碼如下:
BSTree.h
struct BSTreeNode; typedef struct BSTreeNode *ptrtreenode; void MakeEmpty(ptrtreenode T); ptrtreenode InsertBSTree(int x,ptrtreenode T); //二叉樹的插入操作 ptrtreenode FindMin(ptrtreenode T);//查詢以T為頭結點的子樹中最小的關鍵字的結點,並返回--------------------遞迴方式實現 ptrtreenode FindMin1(ptrtreenode T);//查詢以T為頭結點的子樹中最小的關鍵字的結點,並返回--------------------非遞迴方式實現 ptrtreenode DeleteBSTree(int x,ptrtreenode T); //刪除關鍵字為x的結點(遞迴策略) void PrintBSTree_Pre(ptrtreenode T);//先序遍歷 void PrintBSTree_Post(ptrtreenode T);//後序遍歷 void PrintBSTree_In(ptrtreenode T);//中序遍歷
BSTree.c
//name :jae chia //purpose:建立二叉查詢樹,並進行二叉查詢樹的結點的刪除,搜尋帶有某個關鍵字的結點等 #include<stdio.h> #include<stdlib.h> #include"BSTree.h" struct BSTreeNode { int element; ptrtreenode left; ptrtreenode right; }; /*ptrtreenode CreateBSTree() //利用這個函式建立的是帶有啞元結點的二叉查詢樹,並不合適 { ptrtreenode T=(ptrtreenode)malloc(sizeof(struct BSTree)); T->left=NULL; T->right=NULL; return T; }*/ void MakeEmpty(ptrtreenode T) { if(T) { MakeEmpty(T->left); MakeEmpty(T->right); free(T); } } ptrtreenode InsertBSTree(int x,ptrtreenode T) //二叉樹的插入操作 { //ptrtreenode newtreenode=(ptrtreenode)malloc(sizeof(struct BSTreeNode)); //newtreenode->element=x; if(NULL==T) { //ptrtreenode T=(ptrtreenode)malloc(sizeof(struct BSTreeNode)); T = (ptrtreenode)malloc(sizeof(struct BSTreeNode));//這裡誤寫為ptrtreenode T=(ptrtreenode)malloc(sizeof(struct BSTreeNode));相當於在if語句塊內用定義了一個T,語句塊結束,該區域性變數就銷燬 //因此在建立一個二叉樹的根節點時,該函式返回的T仍是NULL if(T==NULL) { printf("Insufficient memory!\n"); exit(0); } T->element=x; T->left=NULL; T->right=NULL; } else { if(x < T->element) T->left=InsertBSTree(x,T->left); else if(x > T->element) T->right=InsertBSTree(x,T->right); } return T; } ptrtreenode FindMin(ptrtreenode T)//查詢以T為頭結點的子樹中最小的關鍵字的結點,並返回--------------------遞迴方式實現 { if(T->left==NULL) { return T; //return FindMin(T->left); } else { return FindMin(T->left); } } ptrtreenode FindMin1(ptrtreenode T)//查詢以T為頭結點的子樹中最小的關鍵字的結點,並返回--------------------非遞迴方式實現 { while(T->left) { T=T->left; } return T; } ptrtreenode DeleteBSTree(int x,ptrtreenode T) //這裡也是採用的遞迴策略 { ptrtreenode tmpcell; if(T==NULL) { printf(" element can't find\n"); exit(0); } else if(x < T->element) //在左分支上查詢關鍵字x,如此遞迴 { T->left=DeleteBSTree(x,T->left); } else if(x > T->element) //在右分支上查詢關鍵字x,如此遞迴 { T->right=DeleteBSTree(x,T->right); } else //找到該關鍵字 { if (T->left && T->right)//所刪除關鍵字的結點的左右子樹都存在的情況下 { tmpcell=FindMin(T->right); T->element=tmpcell->element;//找到所要刪結點的右子樹上關鍵字最小的結點,並將其關鍵字值賦給所要刪除的那個結點 T->right=DeleteBSTree(T->element,T->right);//這時候刪除上面右子樹上關鍵字最小的那個結點(因為這時候所刪的這個結點肯定沒有左孩子,否 //則就不會是最小,因此這就相當於對僅有一個孩子的結點進行刪除操作) } else //所刪除的關鍵字的結點的左右子樹僅存在一個 { tmpcell=T; if(T->left==NULL) { T=T->right; } else if(T->right==NULL) { T=T->left; } free(tmpcell); } } return T; } //先序遞迴遍歷 void PrintBSTree_Pre(ptrtreenode T) { if(T) { printf("%d ",T->element); PrintBSTree_Pre(T->left); PrintBSTree_Pre(T->right); } } //後序遞迴遍歷 void PrintBSTree_Post(ptrtreenode T) { if(T) { PrintBSTree_Post(T->left); PrintBSTree_Post(T->right); printf("%d ",T->element); } } //中序遞迴遍歷 void PrintBSTree_In(ptrtreenode T) { if(T) {; PrintBSTree_In(T->left); printf("%d ",T->element); PrintBSTree_In(T->right); } } int main(void) { ptrtreenode T=NULL; T=InsertBSTree(6,T); T=InsertBSTree(2,T); T=InsertBSTree(1,T); T=InsertBSTree(4,T); T=InsertBSTree(8,T); T=InsertBSTree(3,T); printf("先序遍歷:"); PrintBSTree_Pre(T); printf("\n"); printf("後序遍歷:"); PrintBSTree_Post(T); printf("\n"); printf("中序遍歷:"); PrintBSTree_In(T); printf("\n"); printf("刪除關鍵字為4的結點後的遍歷狀態:\n");//刪除僅有左子樹或僅有右子樹的結點(關鍵字為4) T=DeleteBSTree(4,T); printf("先序遍歷"); PrintBSTree_Pre(T); printf("\n"); printf("後序遍歷:"); PrintBSTree_Post(T); printf("\n"); printf("中序遍歷:"); PrintBSTree_In(T); printf("\n"); printf("刪除關鍵字為2的結點後的遍歷狀態:\n");//刪除左子樹和右子樹都非空的結點(關鍵字為2) T=DeleteBSTree(2,T); printf("先序遍歷"); PrintBSTree_Pre(T); printf("\n"); printf("後序遍歷:"); PrintBSTree_Post(T); printf("\n"); printf("中序遍歷:"); PrintBSTree_In(T); printf("\n"); //PrintBSTreeZ(T); //PrintBSTreeH(T); return 0; }
執行結果: