《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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值