# 哈希查找

顺序查找和折半查找是顺序表存储；二叉排序树是二叉树存储；哈希查抄是类图（和图的邻接表存储相似）；

# ifndef _SORT_

typedef int KeyType;

typedef struct
{
KeyType key;
}DataType;

# endif

# ifndef _SEQLIST_
# define _SEQLIST_

# include <iostream>
# include "Search.h"//引用这里的DataType；
using namespace std;

# define MAXSIZE 64

typedef struct
{
DataType data[MAXSIZE];
int length;
}SeqList, * PSeqList;

typedef struct Node
{
DataType elem;
struct Node * lchild;
struct Node * rchild;
}BSTree, * PBSTree;

//线性表查找基本准备；
PSeqList Init_SeqList(void);
bool Full_SeqList(PSeqList p);
int Push_SeqList(PSeqList p, KeyType keyValue);
void Traversal_SeqList(PSeqList p);
ostream & operator<<(ostream & os, DataType dataValue);

//基于线性表的查找方法；

//顺序查找；
int SeqSearch(PSeqList p, KeyType key);

//折半查找；
int BinSearch(PSeqList p, KeyType key);

//二叉排序树插入；
void BSTreeInsert(PBSTree * ppt, KeyType key);

//二叉排序树查找；
PBSTree BSTreeSearch(PBSTree pt, KeyType key);

//二叉排序树中序遍历；
void InOrder(PBSTree pt);

//二叉树删除；
int BSTreeDelete(PBSTree * ppt, KeyType key);

//哈希基表长度；
# define SIZE 13

//哈希链表节点；
{
DataType data;

//哈希基表节点；
typedef struct HashBaseListNode
{
DataType data;
int len;
}HashBaseListNode, * PHashBaseListNode;

//哈希表；
typedef struct
{
HashBaseListNode elem[SIZE];
int length;
}HashTable, * PHashTable;

//哈希函数 ；
int HashFunction(KeyType key);
//哈希表创建；
PHashTable CreateHashTable(void);
//哈希表插入；
bool HashTableInsert(PHashTable p, KeyType key);
//遍历哈希表；
void HashTableTraversal(PHashTable p);

#endif



# include "SeqList.h"

PSeqList Init_SeqList(void)
{
PSeqList p = (PSeqList)malloc(sizeof(SeqList));

if (NULL != p)
{
p->length = 0;
return p;
}
else
{
cout << "Memory allocate is error! " << endl;
system("pause");
exit(0);
}
}

bool Full_SeqList(PSeqList p)
{
if (p->length >= MAXSIZE)
{
return true;
}
else
{
return false;
}
}

int Push_SeqList(PSeqList p, KeyType keyValue)
{
if (Full_SeqList(p))
{
cout << "SeqList is full! " << endl;

return -1;
}

p->data[p->length].key = keyValue;
p->length++;

return 0;
}

void Traversal_SeqList(PSeqList p)
{
for (int i = 0; i < p->length; i++)
{
cout << p->data[i] << " ";
}
cout << endl;

return;
}

ostream & operator<<(ostream & os, DataType dataValue)
{
cout << dataValue.key;

return os;
}

//基于线性表的查找方法；；

//顺序查找；
int SeqSearch(PSeqList p, KeyType key)
{
int i = 0;
p->data[p->length].key = key;
while (p->data[i].key != key)//使用这种带前哨站的算法必须是非满表；不然出错；
{
i++;
}

if (i == p->length)
{
return -1;
}
else
{
return i;
}

//for (int i = 0; i < p->length; i++)
//{
//	if (p->data[i].key == key)
//	{
//		return i;
//	}
//}

return -1;
}

//折半查找；
int BinSearch(PSeqList p, KeyType key)
{
int low = 0;
int mid = 0;
int high = p->length - 1;

while (low <= high)
{
mid = (low + high) / 2;

if (key == p->data[mid].key)
{
return mid;
}
else if (key > p->data[mid].key)
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}

return -1;
}

//折半查找；
int BinSearch(PSeqList p, KeyType key)
{
int low = 0;
int mid = 0;
int high = p->length - 1;

while (low <= high)
{
mid = (low + high) / 2;

if (key == p->data[mid].key)
{
return mid;
}
else if (key > p->data[mid].key)
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}

return -1;
}

//二叉排序树插入；
void BSTreeInsert(PBSTree * ppt, KeyType key)
{
PBSTree t = NULL;

if (*ppt == NULL)
{
t = (PBSTree)malloc(sizeof(BSTree));
t->elem.key = key;
t->lchild = NULL;
t->rchild = NULL;

*ppt = t;
}
else
{
if (key < ((*ppt)->elem).key)
{
BSTreeInsert(&((*ppt)->lchild), key);
}
else
{
BSTreeInsert(&((*ppt)->rchild), key);
}
}

return;
}

//二叉排序树查找；
PBSTree BSTreeSearch(PBSTree pt, KeyType key)
{
if (NULL == pt)
{
return NULL;
}

if (key == pt->elem.key)
{
return pt;
}
else if (key < pt->elem.key)
{
BSTreeSearch(pt->lchild, key);
}
else
{
BSTreeSearch(pt->rchild, key);
}
}

//二叉排序树中序遍历；
void InOrder(PBSTree pt)
{
if (NULL != pt)
{
InOrder(pt->lchild);
cout << pt->elem.key << " ";
InOrder(pt->rchild);
}
}

//二叉树删除；
int BSTreeDelete(PBSTree * ppt, KeyType key)
{
PBSTree pre = NULL;
PBSTree p = *ppt;
PBSTree q = NULL;
PBSTree s = NULL;

//查找要插入的节点和前驱节点；
while ((NULL != p) && (p->elem.key != key))
{
pre = p;

if (key < p->elem.key)
{
p = p->lchild;
}
else
{
p = p->rchild;
}
}

//检测是否没有查找到；
if (NULL == p)
{
return 0;
}

if (NULL == p->lchild)//没有左孩子；这里需要用到前驱节点；
{
if (NULL == pre)//待删除的节点是根节点；
{
*ppt = p->rchild;
}
else if (pre->lchild == p)//待删除的节点是其前驱的左节点；
{
pre->lchild = p->rchild;
}
else//待删除节点是其前驱的右节点；
{
pre->rchild = p->rchild;
}

free(p);

return 1;
}
else//没有右孩子；
{
q = p;
s = p->lchild;

while (s->rchild)
{
q = s;
s = s->rchild;
}

if (p == q)
{
p->lchild = s->lchild;
}
else
{
q->rchild = s->lchild;
}
p->elem = s->elem;

free(s);

return 1;
}
}

//哈希函数；
int HashFunction(KeyType key)
{
return (key % 13);
}

//创建哈希表；
PHashTable CreateHashTable(void)
{
PHashTable p = (PHashTable)malloc(sizeof(HashTable));

if (NULL != p)
{
for (int i = 0; i < SIZE; i++)
{
p->elem[i].firstnode = NULL;
p->elem[i].len = 0;
p->elem[i].data = { 0 };
}
p->length = 0;

return p;
}
else
{
cout << "Memory allocate is error! " << endl;
system("pause");
exit(0);
}
}

//哈希表插入；
bool HashTableInsert(PHashTable p, KeyType key)
{
int sub = HashFunction(key);
if (0 == p->elem[sub].len)
{
p->elem[sub].data.key = key;
p->elem[sub].len++;
p->length++;
}
else
{
if (NULL == t)
{
return false;
}
t->data.key = key;
t->next = p->elem[sub].firstnode;
p->elem[sub].firstnode = t;
p->elem[sub].len++;
p->length++;
}

return true;
}

//遍历哈希表；
void HashTableTraversal(PHashTable p)
{
for (int i = 0; i < SIZE; i++)
{
if (p->elem[i].len == 1)
{
cout << p->elem[i].data.key << endl;
}
else if (p->elem[i].len > 1)
{
cout << p->elem[i].data.key << endl;
PHashLiskListNode q = p->elem[i].firstnode;
while (NULL != q)
{
cout << q->data.key << endl;
q = q->next;
}
}
else
{
;
}
}
}



# include "SeqList.h"

int main(int argc, char ** argv)
{
PSeqList p = Init_SeqList();

for (int i = 0; i < 10; i++)
{
Push_SeqList(p, i + 1);
}

cout << "------------------------SeqList Search------------------------" << endl;
Traversal_SeqList(p);

//这里是测试区；可以测试各种基于线性表的存储结构；
//后面的就不一一改了；都是一样的； 改一个函数名就可以了；
cout << "Your search position is : " << SeqSearch(p, 0) << endl;
cout << "Your search position is : " << SeqSearch(p, 1) << endl;
cout << "Your search position is : " << SeqSearch(p, 5) << endl;
cout << "Your search position is : " << SeqSearch(p, 10) << endl;
cout << "Your search position is : " << SeqSearch(p, 11) << endl << endl;

cout << "------------------------TreeList Search------------------------" << endl;

//这里是测试区；可以测试各种基于二叉树的存储结构；
PBSTree pt = NULL;
PBSTree pp = NULL;
BSTreeInsert(&pt, 34);
BSTreeInsert(&pt, 18);
BSTreeInsert(&pt, 76);
BSTreeInsert(&pt, 13);
BSTreeInsert(&pt, 25);
BSTreeInsert(&pt, 52);
BSTreeInsert(&pt, 82);
BSTreeInsert(&pt, 20);
BSTreeInsert(&pt, 67);
BSTreeInsert(&pt, 91);
BSTreeInsert(&pt, 58);
BSTreeInsert(&pt, 73);

InOrder(pt);
cout << endl;

if (NULL != (pp = BSTreeSearch(pt, 13)))
{
cout << pp->elem.key << endl;
}

BSTreeDelete(&pt, 34);

InOrder(pt);
cout << endl;

cout << "------------------------Hash Search------------------------" << endl;

//这里是测试区；可以测试哈希表的存储结构；
PHashTable pht = CreateHashTable();
HashTableInsert(pht, 26);
HashTableInsert(pht, 38);
HashTableInsert(pht, 73);
HashTableInsert(pht, 21);
HashTableInsert(pht, 54);
HashTableInsert(pht, 35);
HashTableInsert(pht, 167);
HashTableInsert(pht, 32);
HashTableInsert(pht, 7);
HashTableInsert(pht, 223);
HashTableInsert(pht, 62);

HashTableTraversal(pht);

system("pause");
return 0;
}