SearchTree每个节点被指定一个Key,这里假设Key是不同的(这一假设是合理的,在实际应用中,按照Key来存储不同的软件信息,若有相同Key可以增加一个引用计数字段)。
SearchTree具有结构性和堆序性:
结构性:二叉树
堆序性:所有节点的左子树上所有节点的Key值比自身小,右子树上所有节点Key值比自身大
头文件searchtree.h
#ifndef _SEARCHTREE_H_ #define _SEARCHTREE_H_ struct TreeNode; typedef struct TreeNode * Position; typedef struct TreeNode * SearchTree; SearchTree MakeEmpty(SearchTree); Position Find(element_t, SearchTree); Position FindMin(SearchTree); Position FindMax(SearchTree); SearchTree Insert(element_t, SearchTree); SearchTree Delete(element_t, SearchTree); #endif
C文件searchtree.c
#ifdef _cplusplus extern "C" { #endif typedef unsigned int element_t; #include <stdlib.h> #include <assert.h> #include "searchtree.h" struct TreeNode { element_t element; SearchTree Left; //ptr to left child SearchTree Right; //ptr to right child }; /* destroy a searchtree, return nullptr */ SearchTree MakeEmpty(T) SearchTree T; { if (T) { MakeEmpty(T->Left); MakeEmpty(T->Right); free(T); } return (SearchTree)0; } /* O(logN)时间,N是节点数 */ Position Find(element, T) element_t element; SearchTree T; { if (!T) { return (Position)0; } if (element < T->element) { return Find(element, T->Left); } else if (element > T->element) { return Find(element, T->Right); } return T; } /* recursive implementation */ Position FindMin(T) SearchTree T; { if (!T) { return (Position)0; } /* 若没有左儿子,这个节点就是最小的 */ else if (!T->Left) { return T; } return FindMin(T->Left); } /* 非递归 */ Position FindMax(T) SearchTree T; { if (T) { while (T->Right) { T = T->Right; } } return T; } /* O(logN)时间 */ SearchTree Insert(element, T) element_t element; SearchTree T; { if (!T) { T = malloc(sizeof(struct TreeNode)); assert(T != NULL); T->Left = T->Right = (SearchTree)0; T->element = element; } else if (element < T->element) { T->Left = Insert(element, T->Left); } else if (element > T->element) { T->Right = Insert(element, T->Right); } else { //todo } return T; } /* O(logN)时间 */ SearchTree Delete(element, T) element_t element; SearchTree T; { Position Tmp; if (!T) { //todo } /* 寻找这个节点,不能用find,因为递归过程要挂接内存 */ else if (element < T->element) { T->Left = Delete(element, T->Left); } else if (element > T->element) { T->Right = Delete(element, T->Right); } /* 若要删除的节点有两个儿子,用左子树最大的节点代替本节点,并删除左子树上的这个节点 */ else if (T->Left && T->Right) { Tmp = FindMax(T->Left); T->element = Tmp->element; T->Left = Delete(Tmp->element, T->Left); } else { /* 若该节点是树叶或者只有一个儿子,很好处理 */ Tmp = T; if (!T->Left) { T = T->Right; } else { T = T->Left; } free(Tmp); } return T; } #ifdef _cplusplus } #endif