二叉搜索树插入:
可以首先要判断树是不是为空(针对链表结构是必须的,因为要分配动态内存),然后插入。有2种选择,递归和循环,因为递归是尾部递归,牺牲了空间复杂度获得了可读性,可以转换为循环。
删除结点:
分为3种情况:
1、删除没有孩子的结点,直接删除
2、删除只有一个孩子的结点,删除原有结点,指向孩子结点。
3、删除有2个孩子的结点,删除左子树的最大结点,把值放在当前结点。
代码实现:
tree.h
#ifndef TREE_H
#define TREE_H
static const int ARRAY_SIZE = 100;
static int tree[ARRAY_SIZE];
int left_child(int i);
int right_child(int i);
int find(int i);
void insert(int i);
void Delete(int i);
#endif
tree.cpp
#include "tree.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int left_child(int i){
return 2*i+1;
}
int right_child(int i){
return i*2+2;
}
int find(int i){
int a = 0;
while(tree[a] != 0)
{
if(tree[a] > i)
a = left_child(a);
if(tree[a] == i)
return a;
if(tree[a] < i)
a = right_child(a);
assert(a<ARRAY_SIZE);
}
return a;
}
void insert(int i){
assert(i!=0);
int current = 0;
while(tree[current] != 0){
if(tree[current] > i)
current = left_child(current);
else
current = right_child(current);
assert(current < ARRAY_SIZE);
}
tree[current] = i;
}
void Delete(int i){
int index = find(i);
assert(index < ARRAY_SIZE);
register int left = left_child(index);
register int right = right_child(index);
if(tree[left] == 0 && tree[right] == 0)
tree[index] = 0;
else if(tree[left] == 0)
{
tree[index] = tree[right];//这时候如果right后还有结点有问题!考虑一下
tree[right] = 0;
}
else if(tree[right] == 0){
tree[index] = tree[left];
tree[left] = 0;
}
else
{
int pre;
right = left_child(right);
while (tree[right] != 0)
{
assert(right < ARRAY_SIZE);
pre = right;
right = right_child(right);
}
tree[index] = tree[pre];
tree[pre] = 0;
}
}
test.cpp
#include "tree.h"
#include <stdio.h>
#include <stdlib.h>
int main(){
insert(20);
insert(12);
insert(25);
insert(5);
insert(16);
Delete(12);
Delete(16);
Delete(25);
return EXIT_SUCCESS;
}