你可以看完代码再看难点,或许会有更深的理解
难点:
这些操作看起来挺简单,但实现起来确实不好操作:
- 各种函数要考虑为空树的情况,例如:FindMax与FindMin
- 在删除函数中,要用递归的找个删除的元素并删除,不能简单地用Find函数找到就把他删除:因为用Find函数找到这些元素后指针指向这些要删除的元素,当这些元素直接被删除时这些元素的子元素没有办法再与父节点拼接。这就会造成断链
而当调用递归时 :每次调用结束都会返回新的子根节点(删除元素有两个子结点) 或者 子根结点的子结点(删除元素没有两个子结点)
进行前置工作
typedef int ElementType;
typedef struct TNode* Position;
typedef Position BinTree;
struct TNode {
ElementType Data;
BinTree Left;
BinTree Right;
};
要完成的操作
void PreorderTraversal(BinTree BT);
void InorderTraversal(BinTree BT);
BinTree Insert(BinTree BST, ElementType X);
BinTree Delete(BinTree BST, ElementType X);
Position Find(BinTree BST, ElementType X);
Position FindMin(BinTree BST);
Position FindMax(BinTree BST);
操作实现
BinTree Insert(BinTree BST, ElementType X) {
if (!BST) {
BST = (BinTree)malloc(sizeof(struct TNode));
BST->Data = X; BST->Left = NULL; BST->Right = NULL;
}
else {
if (X > BST->Data) {
BST->Right = Insert(BST->Right, X);
}
else {
BST->Left = Insert(BST->Left, X);
}
}
return BST;
}
Position FindMin(BinTree BST) {
if (!BST)
return NULL;
if (BST->Left) {
FindMin(BST->Left);
}
else { //这个BST没有左结点,意味着最小
return BST;
}
}
Position FindMax(BinTree BST) {
if (!BST)
return NULL;
if (BST->Right) {
FindMax(BST->Right);
}
else {
return BST;
}
}
Position Find(BinTree BST, ElementType X) {
Position T = NULL;
if (BST == NULL ) {
T = NULL;
}
else{
if (X == BST->Data) {
T = BST;
}
else if (X < BST->Data) {
T = Find(BST->Left, X);
}
else if (X > BST->Data) {
T = Find(BST->Right, X);
}
}
return T;
}
BinTree Delete(BinTree BST, ElementType X) {
if (!BST) { //BST是空
printf("Not Found\n");
}
else if (X < BST->Data) {
BST->Left = Delete(BST->Left, X);
}
else if (X > BST->Data) {
BST->Right = Delete(BST->Right, X);
}
else {
if (BST->Left && BST->Right) {
BinTree M = FindMax(BST->Left);
BST->Data = M->Data;
BST->Left = Delete(BST->Left, M->Data);
}
else {
if (BST->Left) {
BinTree M = BST;
BST = BST->Left;
free(M);
}
else {
BinTree M = BST;
BST = BST->Right;
free(M);
}
}
}
return BST;
}
void PreorderTraversal(BinTree BT) {
if (BT) {
printf("%d ", BT->Data);
PreorderTraversal(BT->Left);
PreorderTraversal(BT->Right);
}
}
void InorderTraversal(BinTree BT) {
if (BT) {
InorderTraversal(BT->Left);
printf("%d ", BT->Data);
InorderTraversal(BT->Right);
}
}