• 数据结构笔记-----二叉排序树和哈希表


    二叉排序树


    如何改进二分查找使其适应动态查找?


    二分查找的过程


    新的想法


    二叉排序树






    代码



    BSTree.c

    <strong><span style="font-size:18px;">#include <stdio.h>
    #include <malloc.h>
    #include "BSTree.h"
    
    typedef struct _tag_BSTree TBSTree;
    struct _tag_BSTree
    {
        int count;
        BSTreeNode* root;
    };
    
    static void recursive_display(BSTreeNode* node, BSTree_Printf* pFunc, int format, int gap, char div) // O(n)
    {
        int i = 0;
        
        if( (node != NULL) && (pFunc != NULL) )
        {
            for(i=0; i<format; i++)
            {
                printf("%c", div);
            }
            
            pFunc(node);
            
            printf("
    ");
            
            if( (node->left != NULL) || (node->right != NULL) )
            {
                recursive_display(node->left, pFunc, format + gap, gap, div);
                recursive_display(node->right, pFunc, format + gap, gap, div);
            }
        }
        else
        {
            for(i=0; i<format; i++)
            {
                printf("%c", div);
            }
            printf("
    ");
        }
    }
    
    static int recursive_count(BSTreeNode* root) // O(n)
    {
        int ret = 0;
        
        if( root != NULL )
        {
            ret = recursive_count(root->left) + 1 + recursive_count(root->right);
        }
        
        return ret;
    }
    
    static int recursive_height(BSTreeNode* root) // O(n)
    {
        int ret = 0;
        
        if( root != NULL )
        {
            int lh = recursive_height(root->left);
            int rh = recursive_height(root->right);
            
            ret = ((lh > rh) ? lh : rh) + 1;
        }
        
        return ret;
    }
    
    static int recursive_degree(BSTreeNode* root) // O(n)
    {
        int ret = 0;
        
        if( root != NULL )
        {
            if( root->left != NULL )
            {
                ret++;
            }
            
            if( root->right != NULL )
            {
                ret++;
            }
            
            if( ret == 1 )
            {
                int ld = recursive_degree(root->left);
                int rd = recursive_degree(root->right);
                
                if( ret < ld )
                {
                    ret = ld;
                }
                
                if( ret < rd )
                {
                    ret = rd;
                }
            }
        }
        
        return ret;
    }
    
    static int recursive_insert(BSTreeNode* root, BSTreeNode* node, BSTree_Compare* compare)
    {
        int ret = 1;
        int r = compare(node->key, root->key);
        
        if( r == 0 )
        {
            ret = 0;
        }
        else if( r < 0 )
        {
            if( root->left != NULL )
            {
                ret = recursive_insert(root->left, node, compare);
            }
            else
            {
                root->left = node;
            }
        }
        else if( r > 0 )
        {
            if( root->right != NULL )
            {
                ret = recursive_insert(root->right, node, compare);
            }
            else
            {
                root->right = node;
            }
        }
    }
    
    static BSTreeNode* recursive_get(BSTreeNode* root, BSKey* key, BSTree_Compare* compare)
    {
        BSTreeNode* ret = NULL;
        
        if( root != NULL )
        {
            int r = compare(key, root->key);
            
            if( r == 0 )
            {
                ret = root;
            }
            else if( r < 0 )
            {
                ret = recursive_get(root->left, key, compare);
            }
            else if( r > 0 )
            {
                ret = recursive_get(root->right, key, compare);
            }
        }
        
        return ret;
    }
    
    static BSTreeNode* delete_node(BSTreeNode** pRoot)
    {
        BSTreeNode* ret = *pRoot;
        
        if( (*pRoot)->right == NULL )
        {
            *pRoot = (*pRoot)->left;
        }
        else if( (*pRoot)->left == NULL )
        {
            *pRoot = (*pRoot)->right;
        }
        else
        {
            BSTreeNode* g = *pRoot;
            BSTreeNode* c = (*pRoot)->left;
            
            while( c->right != NULL )
            {
                g = c;
                c = c->right;
            }
            
            if( g != *pRoot )
            {
                g->right = c->left;
            }
            else
            {
                g->left = c->left;
            }
    
            c->left = (*pRoot)->left;
            c->right = (*pRoot)->right;
            
            *pRoot = c;
        }
        
        return ret;
    }
    
    static BSTreeNode* recursive_delete(BSTreeNode** pRoot, BSKey* key, BSTree_Compare* compare)
    {
        BSTreeNode* ret = NULL;
        
        if( (pRoot != NULL) && (*pRoot != NULL) )
        {
            int r = compare(key, (*pRoot)->key);
            
            if( r == 0 )
            {
                ret = delete_node(pRoot);
            }
            else if( r < 0 )
            {
                ret = recursive_delete(&((*pRoot)->left), key, compare);
            }
            else if( r > 0 )
            {
                ret = recursive_delete(&((*pRoot)->right), key, compare);
            }
        }
        
        return ret;
    }
    
    BSTree* BSTree_Create() // O(1)
    {
        TBSTree* ret = (TBSTree*)malloc(sizeof(TBSTree));
        
        if( ret != NULL )
        {
            ret->count = 0;
            ret->root = NULL;
        }
        
        return ret;
    }
    
    void BSTree_Destroy(BSTree* tree) // O(1)
    {
        free(tree);
    }
    
    void BSTree_Clear(BSTree* tree) // O(1)
    {
        TBSTree* btree = (TBSTree*)tree;
        
        if( btree != NULL )
        {
            btree->count = 0;
            btree->root = NULL;
        }
    }
    
    int BSTree_Insert(BSTree* tree, BSTreeNode* node, BSTree_Compare* compare) 
    {
        TBSTree* btree = (TBSTree*)tree;
        int ret = (btree != NULL) && (node != NULL) && (compare != NULL);
        
        if( ret )
        {
            node->left = NULL;
            node->right = NULL;
            
            if( btree->root == NULL )
            {
                btree->root = node;
            }
            else
            {
                ret = recursive_insert(btree->root, node, compare);
            }
            
            if( ret )
            {
                btree->count++;
            }
        }
        
        return ret;
    }
    
    BSTreeNode* BSTree_Delete(BSTree* tree, BSKey* key, BSTree_Compare* compare)
    {
        TBSTree* btree = (TBSTree*)tree;
        BSTreeNode* ret = NULL; 
        
        if( (btree != NULL) && (key != NULL) && (compare != NULL) )
        {
            ret = recursive_delete(&btree->root, key, compare);
            
            if( ret != NULL )
            {
                btree->count--;
            }
        }
        
        return ret;
    }
    
    BSTreeNode* BSTree_Get(BSTree* tree, BSKey* key, BSTree_Compare* compare)
    {
        TBSTree* btree = (TBSTree*)tree;
        BSTreeNode* ret = NULL; 
        
        if( (btree != NULL) && (key != NULL) && (compare != NULL) )
        {
            ret = recursive_get(btree->root, key, compare);
        }
        
        return ret;
    }
    
    BSTreeNode* BSTree_Root(BSTree* tree) // O(1)
    {
        TBSTree* btree = (TBSTree*)tree;
        BSTreeNode* ret = NULL;
        
        if( btree != NULL )
        {
            ret = btree->root;
        }
        
        return ret;
    }
    
    int BSTree_Height(BSTree* tree) // O(n)
    {
        TBSTree* btree = (TBSTree*)tree;
        int ret = 0;
        
        if( btree != NULL )
        {
            ret = recursive_height(btree->root);
        }
        
        return ret;
    }
    
    int BSTree_Count(BSTree* tree) // O(1)
    {
        TBSTree* btree = (TBSTree*)tree;
        int ret = 0;
        
        if( btree != NULL )
        {
            ret = btree->count;
        }
        
        return ret;
    }
    
    int BSTree_Degree(BSTree* tree) // O(n)
    {
        TBSTree* btree = (TBSTree*)tree;
        int ret = 0;
        
        if( btree != NULL )
        {
            ret = recursive_degree(btree->root);
        }
        
        return ret;
    }
    
    void BSTree_Display(BSTree* tree, BSTree_Printf* pFunc, int gap, char div) // O(n)
    {
        TBSTree* btree = (TBSTree*)tree;
        
        if( btree != NULL )
        {
            recursive_display(btree->root, pFunc, 0, gap, div);
        }
    }</span></strong>

    BSTree.h

    <strong><span style="font-size:18px;">#ifndef _BSTREE_H_
    #define _BSTREE_H_
    
    typedef void BSTree;
    typedef void BSKey;
    
    typedef struct _tag_BSTreeNode BSTreeNode;
    struct _tag_BSTreeNode
    {
        BSKey* key;
        BSTreeNode* left;
        BSTreeNode* right;
    };
    
    typedef void (BSTree_Printf)(BSTreeNode*);
    typedef int (BSTree_Compare)(BSKey*, BSKey*);
    
    BSTree* BSTree_Create();
    
    void BSTree_Destroy(BSTree* tree);
    
    void BSTree_Clear(BSTree* tree);
    
    int BSTree_Insert(BSTree* tree, BSTreeNode* node, BSTree_Compare* compare);
    
    BSTreeNode* BSTree_Delete(BSTree* tree, BSKey* key, BSTree_Compare* compare);
    
    BSTreeNode* BSTree_Get(BSTree* tree, BSKey* key, BSTree_Compare* compare);
    
    BSTreeNode* BSTree_Root(BSTree* tree);
    
    int BSTree_Height(BSTree* tree);
    
    int BSTree_Count(BSTree* tree);
    
    int BSTree_Degree(BSTree* tree);
    
    void BSTree_Display(BSTree* tree, BSTree_Printf* pFunc, int gap, char div);
    
    #endif
    </span></strong>

    main.c

    <strong><span style="font-size:18px;">#include <stdio.h>
    #include <stdlib.h>
    #include "BSTree.h"
    
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    
    struct Node
    {
        BSTreeNode header;
        char v;
    };
    
    void printf_data(BSTreeNode* node)
    {
        if( node != NULL )
        {
            printf("%c", ((struct Node*)node)->v);
        }
    }
    
    int compare_key(BSKey* k1, BSKey* k2)
    {
        return (int)k1 - (int)k2;
    }
    
    int main(int argc, char *argv[])
    {
        BSTree* tree = BSTree_Create();
        
        struct Node n1 = {{(BSKey*)1, NULL, NULL}, 'A'};
        struct Node n2 = {{(BSKey*)2, NULL, NULL}, 'B'};
        struct Node n3 = {{(BSKey*)3, NULL, NULL}, 'C'};
        struct Node n4 = {{(BSKey*)4, NULL, NULL}, 'D'};
        struct Node n5 = {{(BSKey*)5, NULL, NULL}, 'E'};
        struct Node n6 = {{(BSKey*)6, NULL, NULL}, 'F'};
        
        BSTree_Insert(tree, (BSTreeNode*)&n4, compare_key);
        BSTree_Insert(tree, (BSTreeNode*)&n1, compare_key);
        BSTree_Insert(tree, (BSTreeNode*)&n3, compare_key);
        BSTree_Insert(tree, (BSTreeNode*)&n6, compare_key);
        BSTree_Insert(tree, (BSTreeNode*)&n2, compare_key);
        BSTree_Insert(tree, (BSTreeNode*)&n5, compare_key);
        
        printf("Height: %d
    ", BSTree_Height(tree));
        printf("Degree: %d
    ", BSTree_Degree(tree));
        printf("Count: %d
    ", BSTree_Count(tree));
        printf("Search Key 5: %c
    ", ((struct Node*)BSTree_Get(tree, (BSKey*)5, compare_key))->v);
        printf("Full Tree: 
    ");
        
        BSTree_Display(tree, printf_data, 4, '-');
        
        BSTree_Delete(tree, (BSKey*)4, compare_key);
        
        printf("After Delete Key 4: 
    ");
        printf("Height: %d
    ", BSTree_Height(tree));
        printf("Degree: %d
    ", BSTree_Degree(tree));
        printf("Count: %d
    ", BSTree_Count(tree));
        printf("Full Tree: 
    ");
        
        BSTree_Display(tree, printf_data, 4, '-');
        
        BSTree_Clear(tree);
        
        printf("After Clear: 
    ");
        printf("Height: %d
    ", BSTree_Height(tree));
        printf("Degree: %d
    ", BSTree_Degree(tree));
        printf("Count: %d
    ", BSTree_Count(tree));
        
        BSTree_Display(tree, printf_data, 4, '-');
        
        BSTree_Destroy(tree);
        
    	return 0;
    }</span></strong>


    小结




    哈希表及其实现

    最常见的代码需求:


    再论数组


    一个常见的情形


    解决方案







    代码


    Hash.c

    <strong><span style="font-size:18px;">#include <stdio.h>
    #include <malloc.h>
    #include "Hash.h"
    #include "BSTree.h"
    
    typedef struct _tag_HashNode HashNode;
    struct _tag_HashNode
    {
        BSTreeNode header;
        HashValue* value;
    };
    
    void recursive_clear(BSTreeNode* node)
    {
        if( node != NULL )
        {
            recursive_clear(node->left);
            recursive_clear(node->right);
            
            free(node);
        }
    }
    
    Hash* Hash_Create()
    {
        return BSTree_Create();
    }
    
    void Hash_Destroy(Hash* hash)
    {
        Hash_Clear(hash);
        BSTree_Destroy(hash);
    }
    
    void Hash_Clear(Hash* hash)
    {
        recursive_clear(BSTree_Root(hash));
        BSTree_Clear(hash);
    }
    
    int Hash_Add(Hash* hash, HashKey* key, HashValue* value, Hash_Compare* compare)
    {
        int ret = 0;
        HashNode* node = (HashNode*)malloc(sizeof(HashNode));
        
        if( ret = (node != NULL) )
        {
            node->header.key = key;
            node->value = value;
            
            ret = BSTree_Insert(hash, (BSTreeNode*)node, compare);
            
            if( !ret )
            {
                free(node);
            }
        }
        
        return ret;
    }
    
    HashValue* Hash_Remove(Hash* hash, HashKey* key, Hash_Compare* compare)
    {
        HashValue* ret = NULL;
        HashNode* node = (HashNode*)BSTree_Delete(hash, key, compare);
        
        if( node != NULL )
        {
            ret = node->value;
            
            free(node);
        }
        
        return ret;
    }
    
    HashValue* Hash_Get(Hash* hash, HashKey* key, Hash_Compare* compare)
    {
        HashValue* ret = NULL;
        HashNode* node = (HashNode*)BSTree_Get(hash, key, compare);
        
        if( node != NULL )
        {
            ret = node->value;
        }
        
        return ret;
    }
    
    int Hash_Count(Hash* hash)
    {
        return BSTree_Count(hash);
    }</span></strong>

    Hash.h

    <strong><span style="font-size:18px;">#ifndef _HASH_H_
    #define _HASH_H_
    
    typedef void Hash;
    typedef void HashKey;
    typedef void HashValue;
    
    typedef int (Hash_Compare)(HashKey*, HashKey*);
    
    Hash* Hash_Create();
    void Hash_Destroy(Hash* hash);
    void Hash_Clear(Hash* hash);
    int Hash_Add(Hash* hash, HashKey* key, HashValue* value, Hash_Compare* compare);
    HashValue* Hash_Remove (Hash* hash, HashKey* key, Hash_Compare* compare);
    HashValue* Hash_Get(Hash* hash, HashKey* key, Hash_Compare* compare);
    int Hash_Count(Hash* hash);
    
    
    #endif</span></strong>

    main.c

    <strong><span style="font-size:18px;">#include <stdio.h>
    #include <stdlib.h>
    #include "Hash.h"
    
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    
    struct Student
    {
        char* id;
        char* name;
        int age;
    };
    
    int compare_id(HashKey* k1, HashKey* k2)
    {
        return strcmp((char*)k1, (char*)k2);
    }
    
    int main(int argc, char *argv[]) 
    {
        Hash* hash = Hash_Create();
        
        struct Student s1 = {"9001201", "Delphi", 30};
        struct Student s2 = {"0xABCDE", "Java", 20};
        struct Student s3 = {"koabc", "C++", 40};
        struct Student s4 = {"!@#$%^", "C#", 10};
        struct Student s5 = {"Python", "Python", 10};
        struct Student* ps = NULL;
        
        Hash_Add(hash, s1.id, &s1, compare_id);
        Hash_Add(hash, s2.id, &s2, compare_id);
        Hash_Add(hash, s3.id, &s3, compare_id);
        Hash_Add(hash, s4.id, &s4, compare_id);
        Hash_Add(hash, s5.id, &s5, compare_id);
        
        ps = Hash_Get(hash, "koabc", compare_id);
        
        printf("ID: %s
    ", ps->id);
        printf("Name: %s
    ", ps->name);
        printf("Age: %d
    ", ps->age);
        
        Hash_Destroy(hash);
        
    	return 0;
    }</span></strong>



    小结




    整个数据结构总结


    扩展学习


     更多品种的树


    算法设计


    下一步的学习


















  • 相关阅读:
    Oracle ——优化内存
    用 C# 实现 HTTP 协议多线程下载文件
    Oracle 为表某个字段进行字母数字组合编码
    Oracle 11g Release 1 (11.1)——自动存储管理(Automatic Storage Management,ASM)
    Oracle 11g Release 1 (11.1) Oracle Text 如何创建 CTXCAT 索引
    Oracle ——如何确定性能差的 SQL
    MySQL 5.5/5.6——概述 MySQL 客户端程序
    Oracle 数据库统计信息描述
    Oracle Database Instant Client
    HTTP 协议演示——HTTP 协议(45)
  • 原文地址:https://www.cnblogs.com/Zyf2016/p/6337832.html
Copyright © 2020-2023  润新知