[ Problem description ]
The creation, insertion, deletion and query operations of the balanced binary sorting tree are realized , and the average search length ASL of the constructed balanced binary sorting tree is obtained.
[ Basic Requirements ]
( 1) The binary linked list is used as the storage structure of the balanced binary tree;
( 2) Input a keyword sequence to establish the corresponding balanced binary tree;
( 3) Insert a node (keyword) into the balanced binary tree;
( 4) Delete a node (keyword) from the balanced binary tree;
( 5) Calculate the average search length of the balanced binary tree;
( 6) Destroy the balanced binary tree.
Calculate the average search length of a balanced binary tree (n is the number of nodes):
ALS=((n+1)/n)*(log10(n+1)/log10(2))-1;
#include<stdio.h> #include<stdlib.h> #include<math.h> #define LH 1 //left height #define EH 0 // same height #define RH -1 //right height #define TRUE 1 #define FALSE 0 typedef int Status ; typedef bool Boolean ; typedef struct BSTNode { int data; int bf; //balance factor of the node struct BSTNode * lchild,* rchild; //Left and right child pointers }BSTNode,*BStree; //Right-rotate the binary sort with *p as the root void R_Rotate(BSTree &p) { BSTree lc=p->lchild ; //lc points to the root node of the left subtree of *p p->lchild =lc->rchild ; //The right subtree of lc is attached to the left subtree of *p lc->rchild =p; //p points to the new root node p=lc; }//R_Rotate //The binary sort with *p as the root is left-handed void L_Rotate(BSTree &p) { BSTree rc=p->rchild ; //rc points to the root node of the right subtree of *p p->rchild =rc->lchild ; //The left subtree of rc is attached to the right subtree of *p rc->lchild =p; //p points to the new root node p = rc; }//L_Rotate // Left-balance processing of binary tree T (LL type and LR type) void LeftBalance(BSTree &T) { BSTree lc = T->lchild; switch (lc->bf) { //The LL type only needs to be rotated right case LH: //After the right rotation, both the root and the left subtree are balanced T->bf=lc->bf = EH; R_Rotate(T); //Right rotation operation break; //LR type needs to be left-handed, then right-handed HR cases: BSTree rd = lc->rchild; switch (rd->bf) { //Modify the balance factor of *T and its left child case LH:T->bf = RH; lc->bf = EH;break; case EH:T->bf = EH; lc->bf = EH;break; case RH:T->bf = EH; lc->bf = LH;break; } //switch (rd->bf) rd->bf = EH; L_Rotate(T->lchild); R_Rotate(T); break; } //switch (lc->bf) } //LeftBalance void RightBalance(BSTree & T) { BSTree rc = T->rchild; switch (rc->bf) { //RR type only needs to do the left rotation operation HR cases: T->bf = EH; rc->bf = EH; L_Rotate(T); //Left rotation operation break; //RL type needs to do right rotation operation first, and then do left rotation operation case LH: BSTree ld = rc->lchild; switch (ld->bf) { case LH:T->bf = EH; rc->bf = RH;break; case EH:T->bf = EH; rc->bf = EH;break; case RH:T->bf = LH; rc->bf = EH;break; } //switch (ld->bf) ld->bf = EH; R_Rotate(T->rchild); L_Rotate(T); break; }//switch (rc->bf) } //RightBalance //Insert element e into balanced binary tree T Status InsertAVL(BSTree &T, int e, Boolean & taller) { if (!T) { T = (BSTree)malloc(sizeof(BSTNode)); T->rchild = NULL; T->lchild = NULL; T->data = e; T->bf = EH; taller = TRUE; } else { //The element already exists in the balanced binary tree if (e == T->data) { taller = FALSE; return FALSE; } //insert left subtree else if (e < T->data) { if (!InsertAVL(T->lchild, e, taller)) return FALSE; //Not inserted if (taller) //The insertion was successful and the tree became taller { switch (T->bf) { case LH: LeftBalance(T); taller = FALSE; break; //After the balanced binary tree is left balanced //The tree height has not changed, so taller = false case EH: T->bf = LH; taller = TRUE; break; //It turned out to be balanced, so after inserting an element //The tree height must become higher HR cases: T->bf = EH;taller = FALSE; break; //It turns out that the right subtree is higher than the left subtree, but when the left subtree is //When inserting an element, the tree becomes balanced, so taller = false } //switch (T->bf) } //if (taller) } //insert right subtree else { if (!InsertAVL(T->rchild, e, taller)) return 0; //not inserted if (taller) { switch (T->bf) { case LH: T->bf = EH; taller = FALSE; break; case EH: T->bf = RH; taller = TRUE; break; HR cases: RightBalance(T); taller = FALSE; break; } // switch (T->bf) } //if (taller) } //else } //else return TRUE; }//InsertAVL // delete a node (keyword) from a balanced binary tree Status DeleteAVL(BSTree &T, int key, Boolean &shorter) { if (!T) {//No keyword shorter = FALSE; printf("There is no such keyword in this balanced binary tree!\n"); return 0; } else { if (key==T->data) //Found the node that needs to be deleted { //If the node's lchild and //rchild at least one is NULL //Then you're done, otherwise please refer to //explain below BSTree q = T; if (!T->lchild)//If the node's lchild is NULL { q = T; T = T->rchild; free(q); shorter = TRUE; return TRUE; } else if (!T->rchild){//If the rchild of the node is NULL q = T; T = T->lchild;//This sentence is meaningless if it is not for the power of & (quote) free(q); shorter = TRUE; return TRUE; } else { // delete a node whose left and right children are not empty //Make the data of the immediate predecessor p of the node replace the data of the node //Then change key=p.data BSTree s = T->lchild; while (s->rchild) s = s->rchild; T->data = s->data; key = s->data; } } if (key<T->data) { if (!DeleteAVL(T->lchild, key, shorter)) return 0; if (shorter) { switch(T->bf) { case LH:T->bf = EH; shorter = TRUE;break; case EH:T->bf = RH; shorter = FALSE;break; case RH:RightBalance(T); if (T->rchild->bf == EH) shorter = FALSE; else shorter = TRUE;break; }//switch(T->bf) } } else{ if (!DeleteAVL(T->rchild, key, shorter)) return 0; if (shorter) { switch(T->bf) { case LH:LeftBalance(T); if (T->lchild->bf == EH) shorter = FALSE; else shorter = TRUE;break; case EH:T->bf = LH; shorter = FALSE;break; case RH:T->bf = EH; shorter = TRUE;break; } } } } return 1; }//DeleteAVL //Calculate the average search length of a balanced binary tree (search for keyword e) Status SearchBST(BSTree & T, int e) { if (T ==NULL) { printf("There is no such keyword in this balanced binary tree!\n"); return NULL; } if (T->data == e) { return T->data; } else if (e< T->data) { return SearchBST(T->lchild, e); } else { return SearchBST(T->rchild, e); } } //destroy balanced binary tree void DestroyBST(BSTree & T) { if (NULL == T) return; DestroyBST(T->lchild); DestroyBST(T->rchild); free(T); } //Output all elements in the balanced binary tree (small -> large, in-order traversal) void PrintBST(BSTree & T) { if (NULL == T) return; PrintBST(T->lchild); printf("%d ",T->data); PrintBST(T->rchild); } //7- The number of leaf nodes of the statistical tree Status CountLeafs(BSTree T) { int i,j; if (T) { i=CountLeafs(T->lchild); j=CountLeafs(T->rchild); return i+j+1; } else return 0; } // average search length float ASL(BSTree T) { float n; float ALS; n=CountLeafs(T); ALS=((n+1)/n)*(log10(n+1)/log10(2))-1; return ALS; }
Main function:
void main() { BSTree T=NULL; bool taller = false,shorter; int n,a;float c; printf("Please enter data, enter 0 to end:\n"); while(scanf("%d",&n)) { if(n==0) break; else InsertAVL(T,n,taller); } printf("Balanced binary tree created successfully!\n"); printf("Please enter the inserted node:"); scanf("%d",&n); InsertAVL(T,n,taller); printf("Insert successfully!\n"); printf("Please enter the node to delete:"); scanf("%d",&n); DeleteAVL(T,n,shorter); c=ASL(T); printf("The average search length is:\n"); printf("ASL=%5.2f\n",c); printf("The result is:\n"); PrintBST(T); printf("\n"); DestroyBST(T); }