《Data Structures and Algorithm Analysis in C》(数据结构与算法分析 C语言描述)
构造表达式树
typedef char element_type;
struct TreeNode
{
element_type element;
TreeNode *left;
TreeNode *right;
TreeNode(element_type e, TreeNode * l, TreeNode * r){
element = e;
left = l;
right = r;
}
};
typedef TreeNode *BTree;
void post_trav(BTree node, int depth)
{
if(node != NULL)
{
post_trav(node->left, depth+1);
post_trav(node->right, depth+1);
for (size_t i = 0; i < depth; i++)
cout << "\t" ;
cout << node->element << endl;
}
}
void pre_trav(BTree node, int depth)
{
if(node != NULL)
{
for (size_t i = 0; i < depth; i++)
cout << "\t" ;
cout << node->element << endl;
pre_trav(node->left, depth+1);
pre_trav(node->right, depth+1);
}
}
bool is_operator(char c)
{
return c == '+' ||
c == '-' ||
c == '*' ||
c == '/' ;
}
BTree exptrsson_tree(string psot_exp)
{
stack<BTree> sta;
for (char c : psot_exp)
{
if(is_operator(c))
{
BTree right = sta.top();
sta.pop();
BTree left = sta.top();
sta.pop();
BTree t = new TreeNode(c, left, right);
sta.push(t);
}else
{
BTree t = new TreeNode(c, NULL, NULL);
sta.push(t);
}
}
BTree root = sta.top();
return root;
}
string infix_to_postfix(string)
{
//
return "";
}
int main(int argc, const char** argv) {
string expression = "ab+cde+**"; // postfix, 中缀可转后缀
post_trav(exptrsson_tree(expression), 0);
return 0;
}
二叉查找树
左子树 < 根 < 右子树,中序遍历即为由小到大排序。
typedef int element_type;
struct TreeNode
{
element_type element;
TreeNode *left;
TreeNode *right;
TreeNode(element_type e, TreeNode * l, TreeNode * r){
element = e;
left = l;
right = r;
}
};
typedef TreeNode *BTree;
typedef TreeNode *Position;
void in_trav(BTree node) // 排序
{
if(node != NULL)
{
in_trav(node->left);
cout << node->element << " ";
in_trav(node->right);
}
}
Position find_x(element_type x, BTree T)
{
if(T == NULL)
return NULL;
if(x < T->element)
return find_x(x, T->left);
else if (x > T->element)
return find_x(x, T->right);
else
return T;
}
Position find_min(BTree T)
{
if(T == NULL)
return NULL;
if(T->left == NULL)
return T;
return find_min(T->left);
}
Position find_max(BTree T)
{
if(T == NULL)
return NULL;
// BTree t = T; T本就是参数
while(T->right != NULL)
T = T->right;
return T;
}
// void insert_(element_type x, BTree &T) // 传引用无需返回值
BTree insert_(element_type x, BTree T)
{
if(!T)
T = new TreeNode(x, NULL, NULL);
else if(x < T->element)
T->left = insert_(x, T->left);
else if(x > T->element)
T->right = insert_(x, T->right);
return T;
}
BTree delete_min(element_type x, BTree T)
{
if(T->left == NULL)
{
BTree temp = T;
T = T->right;
free(temp);
}
else
T->left = delete_min(x, T->left);
return T;
}
BTree delete_(element_type x, BTree T)
{
if(T == NULL)
{
printf("Not found.\n");
return T;
}
else if (x < T->element)
T->left = delete_(x, T->left);
else if (x > T->element)
T->right = delete_(x, T->right);
else
{
if (T->left == NULL && T->right == NULL) // case1: 0 child
{
// delete T;
free(T); // 释放堆中对象内存,此时T是一个悬空指针,仍有其地址
T = NULL;
}else if (T->left == NULL) // case2: 1 child(right)
{
BTree temp = T;
T = T->right;
free(temp);
}else if (T->right == NULL) // case2: 1 child(left)
{
BTree temp = T;
T = T->left;
free(temp);
}else // case3: 2 children
{
BTree right_min = find_min(T->right); // 找待删节点右子树最小值
T->element = right_min->element; // 替换待删节点
T->right = delete_min(T->element, T->right); // 删除此最小值(最小值必无左孩子 --> case2)
// T->right = delete_(T->element, T->right); // 效率不高
// 找待删节点左子树最大值同理
}
}
return T;
}
void test()
{
BTree root = NULL;
root = insert_(5, root);
root = insert_(6, root);
root = insert_(2, root);
root = insert_(3, root);
root = insert_(1, root);
pre_trav(root, 0);
BTree x=NULL, mi=NULL, ma=NULL;
if(x = find_x(3, root))
cout << "find x " << x->element << endl;
if(mi = find_min(root))
cout << "find min e " << mi->element << endl;
if(ma = find_max(root))
cout << "find max e " << ma->element << endl;
delete_(2, root);
cout << "Sort: " << endl;
in_trav(root);
}
int main(int argc, const char** argv) {
test();
return 0;
}
平衡查找数:AVL树
在BST基础上,AVL树要求左右子树高度差小于等于1,以使N节点树高度的界约为lgN。
同BST插入(删除),然后调整位置保持平衡,类似链表的插入等操作。
旋转(wiki图):
struct TreeNode
{
element_type element;
TreeNode *left;
TreeNode *right;
int height;
int bf; // balance factor (方便)
TreeNode(element_type e, TreeNode * l, TreeNode * r){
element = e;
left = l;
right = r;
height = bf = 0;
}
};
typedef TreeNode *AVLTree;
typedef TreeNode *Position;
// update tree height and balance factor
void update_(AVLTree &T_ref)
{
int left_h = T_ref->left == NULL ? -1 : T_ref->left->height; // 空树height = -1
int right_h = T_ref->right == NULL ? -1 : T_ref->right->height;
T_ref->height = max(left_h, right_h) + 1;
T_ref->bf = left_h - right_h;
}
AVLTree right_rotation(AVLTree root)
{
AVLTree new_parent = root->left; // pivote为新的父节点
root->left = new_parent->right; // B成为root的左孩子
new_parent->right = root; // root成为新父节点的右孩子
update_(root);
update_(new_parent);
return new_parent;
}
AVLTree left_rotation(AVLTree root)
{ // 与右旋相反(左右互调)
AVLTree new_parent = root->right; // pivote为新的父节点
root->right = new_parent->left; // B成为root的右孩子
new_parent->left = root; // root成为新父节点的左孩子
update_(root);
update_(new_parent);
return new_parent;
}
AVLTree left_left_case(AVLTree T)
{
return right_rotation(T);
}
AVLTree left_right_case(AVLTree T)
{
T->left = left_rotation(T->left);
return left_left_case(T);
}
AVLTree right_right_case(AVLTree T)
{
return left_rotation(T);
}
AVLTree right_left_case(AVLTree T)
{
T->right = right_rotation(T->right);
return right_right_case(T);
}
AVLTree balance(AVLTree T)
{
if(T->bf == 2) // left heavy
{
if(T->left->bf >= 0)
return left_left_case(T);
else
return left_right_case(T);
}
else if(T->bf == -2) // right heavy
{
if(T->right->bf <= 0)
return right_right_case(T);
else
return right_left_case(T);
}
return T;
}
AVLTree insert_(element_type x, AVLTree T)
{
if(!T)
return new TreeNode(x, NULL, NULL);
if(x < T->element)
T->left = insert_(x, T->left);
else if(x > T->element)
T->right = insert_(x, T->right);
else // 处理重复
return T;
update_(T);
return balance(T);
}
AVLTree delete_max(element_type x, AVLTree T)
{
if(T->right == NULL)
{
AVLTree temp = T;
T = T->left;
free(temp);
}
else
T->right = delete_max(x, T->right);
return T;
}
AVLTree delete_(element_type x, AVLTree T)
{
if(T == NULL)
{
printf("Not found.\n");
return T;
}
else if (x < T->element)
T->left = delete_(x, T->left);
else if (x > T->element)
T->right = delete_(x, T->right);
else
{
if (T->left == NULL && T->right == NULL) // case1: 0 child
{
free(T);
// T = NULL;
return NULL; // 空指针不能到下面update / balance
}else if (T->left == NULL) // case2: 1 child(right)
{
AVLTree temp = T;
T = T->right;
free(temp);
}else if (T->right == NULL) // case2: 1 child(left)
{
AVLTree temp = T;
T = T->left;
free(temp);
}else // case3: 2 children
{
// 改进: x子树更高则在x子树替换、删除,以维持更平衡状态
if(T->left->height < T->right->height)
{
AVLTree right_min = find_min(T->right);
T->element = right_min->element;
T->right = delete_min(T->element, T->right);
}
else
{
AVLTree left_max = find_max(T->left);
T->element = left_max->element;
T->left = delete_max(T->element, T->left);
}
}
}
update_(T);
return balance(T);
}
void test()
{
srand((int)time(NULL));
AVLTree root = NULL;
int a[20];
for (int i = 0; i < 20; i++)
{
a[i] = rand() % 100;
root = insert_(a[i], root);
}
pre_trav(root, 0);
for (int i = 0; i < 5; i++)
{
printf("Delete %d\n", a[i]);
delete_(a[i], root);
pre_trav(root, 0);
}
}
int main(int argc, const char** argv) {
test();
return 0;
}