二叉搜索树学习

来源:互联网 发布:oracle数据库的decode 编辑:程序博客网 时间:2024/06/04 18:57

二叉搜索树是指具有以下性质的二叉树:

1. 其父节点的左孩子一定大于父节点,右孩子一定小于父节点

2. 具有普通二叉树的性质

      二叉搜索树执行各种操作的时间复杂度与树的高度成正比,而线性链表的操作则与链表长度成正比。因此,对于有相同结点数的二叉搜索树和链表,树的操作花费代价小于链表,但实现略复杂于链表。

      下面是二叉树的一些基本操作,其中,插入、遍历、最大最小等比较简单,删除某个结点稍微有点复杂:

#include <stdio.h>#include <malloc.h>#include <stdlib.h>typedef char type_value;typedef struct BTSNode{type_value data;BTSNode *lchild, *rchild;}BTSNode;//递归实现插入void  BTSNodeInsert(BTSNode **p, char cValue){if(*p == NULL) {*p = (BTSNode*) malloc ( sizeof(BTSNode) );(*p)->data = cValue;(*p)->lchild = NULL;(*p)->rchild = NULL;} else if( cValue < (*p)->data){BTSNodeInsert(&((*p)->lchild), cValue);} else{BTSNodeInsert(&((*p)->rchild), cValue);}}//非递归插入void  BTSNodeInsert2(BTSNode **root, type_value value){BTSNode *p = *root;BTSNode *newNode = new BTSNode;newNode->lchild = newNode->rchild = NULL;newNode->data = value;BTSNode *parent = NULL;while(p != NULL) {parent = p;if(value < p->data){p = p->lchild;} else p = p->rchild;}if(parent == NULL){*root = newNode;printf("newNode %c root\n",newNode->data);} else if (parent->data > value){parent->lchild = newNode;printf("newNode %c is in the left of %c\n",newNode->data,parent->data);} else {parent->rchild = newNode;printf("newNode %c is in the right of %c\n",newNode->data,parent->data);}}void preOrder(BTSNode *root) {BTSNode *p = root;if(p != NULL) {printf("%c  ",p->data);preOrder(p->lchild);preOrder(p->rchild);}}void InOrder(BTSNode *root){BTSNode *p = root;if(p != NULL) {InOrder(p->lchild);printf("%c  ",p->data);InOrder(p->rchild);}}bool searchNode(BTSNode *root, type_value value)//递归{if(root == NULL) {printf("找不到\n");return false;} else if (value == root->data){printf("已找到\n");return true;}else if(value < root->data) {return searchNode(root->lchild,value);} else if(value > root->data){return searchNode(root->rchild,value);}}bool searchNode2(BTSNode *root, type_value value)//非递归{BTSNode *p = root;while(p != NULL) {if(value == p->data) {printf("已找到\n");return true;} else if (value < p->data){p = p->lchild;} else if(value > p->data) {p = p->rchild;}}printf("找不到\n");return false;}bool deleteNode(BTSNode *root, type_value v){if(root == NULL) {printf("空树\n");return false;}BTSNode *ptemp = root;BTSNode *parent = NULL;while(ptemp != NULL) {if(ptemp->data == v) {break;} else if(ptemp->data < v){parent = ptemp;ptemp = ptemp->rchild;} else if(ptemp->data > v){parent = ptemp;ptemp = ptemp->lchild;}}if(ptemp == NULL) {printf("找不到要删除的点\n");return false;}//如果被删结点是叶子,直接释放即可if(ptemp->lchild == NULL && ptemp->rchild == NULL){if(ptemp == root) {root = NULL;} else if(parent->lchild == ptemp){parent->lchild = NULL;} else {parent->rchild = NULL;}free(ptemp);}//被删结点为单支子树的根,让其父节点与其子树相连,释放被删节点else if(ptemp->lchild == NULL || ptemp->rchild == NULL) {if(ptemp == root) {//它为根节点if(ptemp->lchild != NULL) {root = ptemp->lchild;} else if(ptemp->rchild != NULL) {root = ptemp->rchild;}}else{if(parent->lchild == ptemp && ptemp->lchild){parent->lchild = ptemp->lchild;} else if(parent->lchild == ptemp && ptemp->rchild) {parent->lchild = ptemp->rchild;} else if(parent->rchild == ptemp && ptemp->lchild){parent->rchild = ptemp->lchild;} else if(parent->rchild == ptemp && ptemp->rchild) {parent->rchild = ptemp->rchild;}free(ptemp);}}//被删结点左右子树均不为空else {BTSNode *p = ptemp; BTSNode *q = p->lchild;while(q->rchild != NULL) //找到被删节点的前驱q{p = q;q = q->rchild;}ptemp->data = q->data; //直接把前驱节点的值赋给被删节点if(p == ptemp) {ptemp->lchild = q->lchild;} else{ptemp->rchild = q->lchild;}free(q); //删除前驱(相当于删除被删节点)}return true;}int main() {type_value a[8] = {'f','h','e','b','a','d','g','c'};BTSNode *root = NULL;for(int i=0; i<8; i++){BTSNodeInsert(&root,a[i]);//printf("%p\n",root);}preOrder(root);printf("\n");InOrder(root);searchNode2(root,'c');searchNode2(root,'m');deleteNode(root, 'c');InOrder(root);BTSNodeInsert(&root,'c');InOrder(root);deleteNode(root,'m');}



0 0