您的位置:首页 > 理论基础 > 数据结构算法

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

2016-03-21 10:52 134 查看
二叉排序树






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






二分查找的过程






新的想法






二叉排序树





















代码






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("\n");

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("\n");
}
}

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\n", BSTree_Height(tree));
printf("Degree: %d\n", BSTree_Degree(tree));
printf("Count: %d\n", BSTree_Count(tree));
printf("Search Key 5: %c\n", ((struct Node*)BSTree_Get(tree, (BSKey*)5, compare_key))->v);
printf("Full Tree: \n");

BSTree_Display(tree, printf_data, 4, '-');

BSTree_Delete(tree, (BSKey*)4, compare_key);

printf("After Delete Key 4: \n");
printf("Height: %d\n", BSTree_Height(tree));
printf("Degree: %d\n", BSTree_Degree(tree));
printf("Count: %d\n", BSTree_Count(tree));
printf("Full Tree: \n");

BSTree_Display(tree, printf_data, 4, '-');

BSTree_Clear(tree);

printf("After Clear: \n");
printf("Height: %d\n", BSTree_Height(tree));
printf("Degree: %d\n", BSTree_Degree(tree));
printf("Count: %d\n", 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\n", ps->id);
printf("Name: %s\n", ps->name);
printf("Age: %d\n", ps->age);

Hash_Destroy(hash);

return 0;
}</span></strong>


小结






整个数据结构总结






扩展学习






更多品种的树






算法设计






下一步的学习




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: