哈希查找

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qinjiawei_156558/article/details/98995595

接下来的几篇博客都是关于查找的;主要有顺序查找;折半查找(应用于有序表);二叉排序树查找;哈希查找;

排序直接的数据结构介绍;

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

 

头文件(Search.h);

# ifndef _SORT_

typedef int KeyType;

typedef struct
{
	KeyType key;
}DataType;

# endif

头文件(SeqList.h);

# 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

//哈希链表节点;
typedef struct HashLinkListNode
{
	DataType data;
	struct HashLinkListNode * next;
}HashLinkListNode, * PHashLiskListNode;

//哈希基表节点;
typedef struct HashBaseListNode
{
	DataType data;
	int len;
	HashLinkListNode * firstnode;
}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









实现文件(SeqList.cpp);

# 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
	{
		HashLinkListNode * t = (HashLinkListNode *)malloc(sizeof(HashLinkListNode));
		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
		{
			;
		}
	}
}









主函数(Main.cpp);

# 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;
}
展开阅读全文

没有更多推荐了,返回首页