数据结构之查找算法

本文详细介绍了数据结构中的查找方法,包括线性表的顺序查找和折半查找,二叉排序树及其查找,以及分块查找和平衡二叉树的概念。文中通过示例代码展示了这些查找方法的实现,如二叉树的插入、删除、查找等操作,并讨论了各种查找方法的性能和适用场景。此外,还提到了散列表的查找方法,强调了哈希函数和冲突解决在散列表查找中的重要性。
摘要由CSDN通过智能技术生成

查找

一、线性表的查找

顺序查找

从表的一端开始,依次将记录的关键字和给定的值进行比较,时间复杂度为O(n)

算法简单,对表结构没有任何要求,既适用于顺序结构,也适用于链式结构

缺点:平均查找长度较大,查找效率较低

折半查找

折半查找要求线性表必须采取顺序结构,而且表中元素按照关键字有序排列时间复杂度为O(log2n)

`#include<iostream>`
`#include<map>`
`#define maxsize 100`
`using namespace std;`
`typedef struct {`
	`int key;`
	`string name;`
	`char sex;`
	`int age;`
`}ElemType;`
`typedef struct {`
	`ElemType* elem;`
	`int length;`
`}SSTable;`
`string name[11] = { "Zhang" ,"Wang","Zhou","Huang","Zheng","Li","Liu","Qian","Sun","Zhao","Chen"};`
`int key[11] = {56,19,80,5,21,64,88,13,37,75,92};`
`char  sex[11] = {'F','F','F','M','M','M','F','F','M','M','M'};`
`int age[11] = {19,20,19,20,20,19,18,19,20,20,20};`
`void CreateSSTable(SSTable& S, int n) {`
	`if (n > maxsize) {`
		`cout << "字符的长度过大";`
		`return;`
	`}`
	`S.elem = new ElemType[n];`
	`for (int i = 0; i < n; i++) {`
		`S.elem[i].age = age[i];`
		`S.elem[i].key = key[i];`
		`S.elem[i].name = name[i];`
		`S.elem[i].sex = sex[i];`
	`}`
	`S.length = n;`
`}`
`void TraversSSTable(SSTable S) {`
	`cout << "学号      姓名      年龄    性别" << endl;`
	`for (int i = 0; i < S.length; i++) {`
		`cout << S.elem[i].key << "  " << S.elem[i].name << "  " << S.elem[i].age << "  " << S.elem[i].sex << endl;`
	`}`
	`return;`
`}`
`int SearchSSTable_Seq(SSTable S, int key, int& c) {`
	`int i = 0;`
	`while (i <= S.length) {`
		`if (key == S.elem[i].key) {`
			`c++;`
			`cout << "查找成功";`
			`cout << S.elem[i].key << "  " << S.elem[i].name << "  " << S.elem[i].age << "  " << S.elem[i].sex << endl;`
			`cout << "下标为" << i << endl;`
			`cout << "比较次数:" << c << endl;`
			`return 1;`
		`}`
		`else {`
			`c++;`
			`i++;`
		`}`
	`}`
	`cout << "查找失败";`
	`return 0;`
`}`

`void SortSSTable(SSTable& S) {`
	`ElemType Temp;`
	`int j;`
	`for (int i = 0; i < S.length; i++) {`
		`Temp = S.elem[i];`
		`j = i - 1;`
		`while (j >= 0 && Temp.key < S.elem[j].key) {`
			`S.elem[j + 1] = S.elem[j];`
			`--j;`
		`}`
		`S.elem[j + 1] = Temp;`
	`}`
`}`
`int SearchSSTable(SSTable S, int key, int& c) {`
	`int center = S.length / 2;`
	`int head = 0;`
	`int tail = S.length;`
	`if (key<S.elem[0].key || key>S.elem[S.length - 1].key) {`
		`cout << "你输入的数据不在查找范围";`
		`return 0;`
	`}`
	`while (head <= tail) {`
		`if (S.elem[center].key < key) {`
			`head = center + 1;`
			`c++;`
		`}`
		`else if (S.elem[center].key == key) {`
			`cout << "查找到" << S.elem[center].key << "  " << S.elem[center].name << "  " << S.elem[center].age << "  " << S.elem[center].sex << endl;`
			`cout << "比较次数" << c << endl;`
			`c++;`
			`break;`

		}
		else {
			tail = center - 1;
			c++;
		}
		center = (head + tail) / 2;
	}
	if (head > tail) {
		cout << "没有找到该学员";
	}

`}`
`int main() {`
	`int key2[10] = { 111,198,157,164,187,124,35,852,987,333 };`
	`int key1;`
	`int c1 = 0;`
	`int c = 0;`
	`SSTable S;`
	`CreateSSTable(S, 10);`
	`TraversSSTable(S);`
	`cout << "请输入你要顺序查找对象的学号"<<endl;`
	`cin >> key1;`
	`SearchSSTable_Seq(S, key1, c1);`
	`SortSSTable(S);`
	`TraversSSTable(S);`

	cout << "请输入你要二分查找对象的学号输入-1结束循环" << endl;
	cin >> key1;
	while (key1 != -1) {
		c = 0;
		SearchSSTable(S, key1, c);
		cin >> key1;
	}
	
	for (int i = 0; i < 11; i++) {
		c = 0;
		SearchSSTable(S, key[i], c);
	}
	for (int i = 0; i < 10; i++) {
		c = 0;
		SearchSSTable(S, key2[i], c);
	}
	return 0;

`}`

分块查找(索引顺序查找)

可以将一个表分为多个子表,对每个子表建立一个索引项,其中包括两项内容:关键字项(此表内的最大关键字)和指针项(指示该子表的第一个记录在表中的位置)

分块有序:索引表按关键字有序,第二的子表中的所有记录关键字均大于第一个子表中的关键字,依次类推。

索引表有序排列,可以用二分查找或者顺序查找,块内查找用顺序查找

分块查找于哈希查找相似(索引表和哈希函数类似,可以说分块查找是哈希的特殊形式)

tip:个人认为分块查找的应用性不大,如果需要保证索引表的有序性,并且满足子表之间的大小关系排布,需要进行排序,但是排序以后,可以直接使用二分查找,效率更高;如果先确定索引表,那么再插入匀速的时候,很可能出现索引无效,可以直接用哈希表代替。

二、树表的查找

二叉排序树

1、若他的根节点不空,则左子树上的所有节点的值均小于他的根节点上的值

2、若他的右子树不空,则右子树上的所有节点的值均大于他的根节点上的值

3、他的左右子树也可以被看作二叉排序树

在二叉树上进行查找操作于折半查找类似,也是一个逐步缩小查找范围的过程

`#include<iostream>`
`#include<stack>`
`#include <windows.h>`
`#include<string>`
`using namespace std;`

`struct TreeNode {`
	`int  data;`
	`string name;`
	`string sex;`
	`int age;`
	`int time = 0;`
	`TreeNode* pParent;`
	`TreeNode* pLeft;`
	`TreeNode* pRight;`
`};`
`TreeNode* pRoot = NULL;`
`TreeNode* find(TreeNode* root, char const& findData,int &time) {`
	`if (root) {`
		`time++;`
		`if (root->data == findData) {`
			`return root;`
		`}`
		`else if (findData < root->data) {`
			`return find(root->pLeft, findData,time);`
		`}`
		`else {`
			`return find(root->pRight, findData, time);`
		`}`
	`}`
	`return nullptr;`
`}`


`void InOrderTraverse(TreeNode* pRoot) {//递归中序遍历`
	`if (pRoot == NULL) {`
		`return;`
	`}`
	`InOrderTraverse(pRoot->pLeft);`
	`if (pRoot->data != -1) {`
		`cout << pRoot->data << " " << pRoot->name << " " << pRoot->age << " " << pRoot->sex << endl;`
	`}`
	`InOrderTraverse(pRoot->pRight);`
`}`
`void insert(TreeNode* pRoot, int const& insertData, char const& findData, bool isLeft) {`
	`TreeNode* tempInsertNode = new TreeNode;`
	`tempInsertNode->data = insertData;`
	`tempInsertNode->pParent = nullptr;`
	`tempInsertNode->pLeft = nullptr;`
	`tempInsertNode->pRight = nullptr;`
	`int number = 0;`
	`if (pRoot) {`
		`TreeNode* findNode = find(pRoot, findData,number);`
		`if (findNode) {`
			`if (isLeft) {`
				`findNode->pLeft = tempInsertNode;`
				`tempInsertNode->pParent = findNode;`
			`}`
			`else {`
				`findNode->pRight = tempInsertNode;`
				`tempInsertNode->pParent;`
			`}`
		`}`
		`else {`
			`TreeNode* tempNode = pRoot;`
			`while (tempNode->pLeft) {`
				`tempNode = tempNode->pLeft;`
			`}`
			`tempNode->pLeft = tempInsertNode;`
			`tempInsertNode->pParent = tempNode;`
		`}`
	`}`
	`else {`
		`pRoot = tempInsertNode;`
	`}`
`}`
`int High(TreeNode* pRoot) {`
	`if (pRoot == NULL)`
		`return -1;`
	`else {`
		`return 1 + max(High(pRoot->pLeft), High(pRoot->pRight));`
	`}`
`}`


`void _clear(TreeNode* root) {`
	`if (root) {`
		`_clear(root->pLeft);`
		`_clear(root->pRight);`
		`delete root;`
		`root = nullptr;`
	`}`
`}`



`void CMyTree_List(TreeNode* pRoot) {`
	`pRoot->pLeft = nullptr;`
	`pRoot->pRight = nullptr;`
	`pRoot->pParent = nullptr;`

`}`

`TreeNode* BSTiinsert(TreeNode*& pRoot, int n, int age, string name, string sex) {
	if (pRoot == NULL) {
		TreeNode* temp = new TreeNode;`
		`temp->data = n;`
		`temp->age = age;`
		`temp->name = name;`
		`temp->sex = sex;`
		`temp->pLeft = NULL;`
		`temp->pRight = NULL;`
		`pRoot = temp;`
	`}`
	`else {`
		`if (n < pRoot->data) {`
			`pRoot->pLeft = BSTiinsert(pRoot->pLeft, n, age, name, sex);`
		`}`
		`else {`
			`pRoot->pRight = BSTiinsert(pRoot->pRight, n, age, name, sex);`
		`}`
	`}`
	`return pRoot;`
`}`
`void CreateBST(TreeNode*& pRoot, const int* arr, int* age, string* name, string* sex, int number) {`



	for (int i = 0; i < number; i++) {
		cout << arr[i] << endl;
		BSTiinsert(pRoot, arr[i], age[i], name[i], sex[i]);
	}

`}`
`void TNodes(TreeNode* pRoot, int& no, int& one, int& two) {`


	if (pRoot == NULL) {
		return;
	}
	if (pRoot->pLeft != nullptr && pRoot->pRight != nullptr) {
		two++;
	}
	if (pRoot->pLeft == nullptr && pRoot->pRight == nullptr) {
		no++;
	}
	if (((pRoot->pLeft == nullptr) && (pRoot->pRight != nullptr)) || ((pRoot->pLeft != nullptr) && (pRoot->pRight == nullptr))) {
		one++;
	}
	
	TNodes(pRoot->pLeft, no, one, two);
	TNodes(pRoot->pRight, no, one, two);

`}`
`void DeleteDSTable_BST(TreeNode*& pRoot, int finddata) {
	int number = 0;
	TreeNode* T1 = find(pRoot, finddata,number);`
	`if (T1) {`
		`T1->data = -1;`
	`}`
	`else {`
		`cout << "你输入的学生不存在,请重新输入";`
	`}`
`}`
`int main() {`
	`TreeNode* pRoot = NULL;`
	`int n;`
	`int data;`
	`int age1;`
	`string name1;`
	`string sex1;`
	`TreeNode* T1 = new TreeNode;`
	`TreeNode* T2 = NULL;`
	`int no = 0, one = 0, two = 0;`
	`int high;`
	`int arr[11] = { 56,19,80,5,21,64,88,13,37,75,92 };`
	`string name[11] = { "zhang","wang","zhou","huang","zheng","li","liu","qian","sun","zhao","chen" };`
	`string sex[11] = { "F","F","F","M","M","M","F","F","M","M","M" };`
	`int age[11] = { 19,20,19,20,20,19,18,19,20,20,20 };`

	CreateBST(pRoot, arr, age, name, sex, 11);
	InOrderTraverse(pRoot);
	cout << "请输入插入学生的信息:(学号,年龄,姓名,性别)输入-1时代表插入结束" << endl;
	cin >> n >> age1 >> name1 >> sex1;
	while (n != -1) {
		int time3 = 0;
		TreeNode* p = find(pRoot, n, time3);
		
		BSTiinsert(pRoot, n, age1, name1, sex1);
		InOrderTraverse(pRoot);
		cin >> n >> age1 >> name1 >> sex1;
	}
	cout << "请输入查找人的学号:" << endl;
	cin >> data;
	while (data != -1) {
		int time = 0;
		T2 = find(pRoot, data,time);
		if (T2) {
			cout << T2->data << " " << T2->name << "  " << T2->sex << "  " << T2->age<<"比较次数为" <<time<< endl;
		}
		else {
			cout << "您输入的学号不存在";
		}
		cin >> data;
	}
	double sum = 0;
	for (int i = 0; i < 11; i++) {
		int time1 = 0;
		T2 = find(pRoot, arr[i], time1);
		if (T2) {
			cout << T2->data << " " << T2->name << "  " << T2->sex << "  " << T2->age << "比较次数为" << time1 << endl;
			sum = sum + time1;
		}
		else {
			cout << "您输入的学号不存在";
		}
	}
	double ASL = sum/ 11;
	cout << "ASL  " << ASL;
	cout << "请输入你要删除人的学号:" << endl;
	cin >> n;
	while (n != -1) {
		DeleteDSTable_BST(pRoot, n);
		InOrderTraverse(pRoot);
		cin >> n;
	}

`}`

平衡二叉树

二叉查找算法的性能取决于二叉树的结构,而二叉排序树的形状则取决于其数据集

如果数据呈现有序排列,则二叉树是线性的,查找的时间复杂度是O(n);反之,如果二叉排序树的结构合理,则查找速度较快,查找的时间复杂度为log2n,平衡二叉树就是尽可能的减少二叉树的高度,来提高算法的效率。

平衡二叉树的特点:

左子树和右子树的深度之差的绝对值不超过1

左子树和右子树也是平衡二叉树

平衡因子:该节点左子树和右子树的深度之差,平衡二叉树所有节点的平衡因子只可能是-1,0,1#include<iostream>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vddr58fB-1622456745177)(C:\Users\Lenovo\Desktop\备份\平衡二叉树LL转换.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1X77e7Pn-1622456745186)(C:\Users\Lenovo\Desktop\备份\平衡二叉树LR转换.png)]

`#include<Cstdlib>`
`#include<cmath>`
`using namespace std;`
`template<class ElementType>`
`struct Node {`
	`ElementType data;`
	`struct Node* lChild;`
	`struct Node* rChild;`
	`int balanceFctor;`
`};`
`template <class ElementType>`
`class BalanceBiTree {`
`public:`
    `BalanceBiTree(Node<ElementType>*& T);                       //初始化
    static void menu();                                          //菜单
    void destory(Node<ElementType>*& T);                        //销毁二叉树`
    `void insert(Node<ElementType>*& T, Node<ElementType>* S);   //将指针S所指节点插入二叉排序中`
    `int BiTreeDepth(Node <ElementType>* T);                     //求树的高度`
    `int getNodeFactor(Node<ElementType>* T);                     //求树中节点的平衡因子`
    `void factorForTree(Node<ElementType>*& T);                   //求树中的每个节点的平衡因子
    void nodeFctorIsTwo(Node<ElementType>*& T, Node<ElementType>*& p);        //获得平衡因子为2或-2的节点
    void nodeFctorIsTwoFather(Node<ElementType>*& T, Node<ElementType>*& f);  //获得平衡因子为2或-2的节点的父节点
    void LLAdjust(Node<ElementType>*& T, Node<ElementType>*& p, Node<ElementType>*& f);                        //LL调整`
    `void LRAdjust(Node<ElementType>*& T, Node<ElementType>*& p, Node<ElementType>*& f);                        //LR调整
    void RLAdjust(Node<ElementType>*& T, Node<ElementType>*& p, Node<ElementType>*& f);                        //RL调整`
    `void RRAdjust(Node<ElementType>*& T, Node<ElementType>*& p, Node<ElementType>*& f);                        //RR调整
    void AllAdjust(Node<ElementType>*& T);                       //集成四种调整,并实时更新平衡因子`
    `void preOrderTraverse(Node<ElementType>* T, int level);       //先序遍历输出`
    `void inOrderTraverse(Node <ElementType>* T, int level);       //中序遍历输出`
    `void BiTreeToArray(Node <ElementType>* T, ElementType A[], int i, int& count); //二叉树转数组`
    `void LevelTraverse(Node <ElementType>* T, ElementType B[], int num);          //对二叉链表表示的二叉树,按从上到下,从左到右打印结点值,即按层次打印`
    `void createSubBalanceBiTree(Node<ElementType>*& T);          //交互创建二叉平衡树
    void createBalanceBiTreeFromArray(Node<ElementType>*& T, ElementType A[], int n);//从数组中创建平衡二叉树`
    `void search(Node <ElementType>*& T, Node <ElementType>*& p, ElementType x);          //查找元素x`
    `Node <ElementType>* getElementFatherPointer(Node <ElementType>*& T, Node <ElementType>*& f, ElementType x); //获取某个元素的父亲指针,不存在返回NULL`
    `void getPriorElement(Node <ElementType>*& T, ElementType& min, ElementType& max);                 //获取前驱元素
    Node <ElementType>* getElementPriorPointer(Node <ElementType>*& T);  //获取某个元素的前驱指针
    void getNextElement(Node <ElementType>*& T, ElementType& min, ElementType& max);                  //获取后继元素`
    `Node <ElementType>* getElementNextPointer(Node <ElementType>*& T);   //获取某个元素的后继指针
    void deleteLeafNode(Node <ElementType>*& T, Node <ElementType>*& p, Node <ElementType>*& f);        //删除叶子节点`
    `void deleteOneBranchNode(Node <ElementType>*& T, Node <ElementType>*& p, Node <ElementType>*& f);   //删除仅有左子树或只有右子树的节点
    void deleteTwoBranchNode(Node <ElementType>*& T, Node <ElementType>*& p);   //删除既有左子树又有右子树的节点
    void deleteOperate(Node <ElementType>*& T, ElementType x);         //集成删除的三种情况的操作`
`private:`
    `Node<ElementType>* root;   //树根`
`};`
`//初始化`
`template< class ElementType>`
`BalanceBiTree<ElementType>::BalanceBiTree(Node<ElementType>*& T)//构造函数,创建一个空的平衡二叉树
{
    T = NULL;
}
//菜单
template< class ElementType>
void BalanceBiTree<ElementType>::menu()//菜单函数,提供功能菜单
{
    cout << "*************************************************" << endl;
    cout << "0退出并销毁平衡二叉树" << endl;
    cout << "1二分查找算法实现查找元素" << endl;
    cout << "2插入结点构建二叉排序树(二叉平衡树)" << endl;
    cout << "3二叉排序树中查找指定值的结点" << endl;
    cout << "4二叉排序树中删除特定值的结点" << endl;
    cout << "5数组A[1..26]递增有序,设计算法以构造一棵平衡的二叉排序树" << endl;
    cout << "6树形输出" << endl;
    cout << "*************************************************" << endl;
}
//销毁二叉树
template< class ElementType>
void BalanceBiTree<ElementType>::destory(Node<ElementType>*& T)`
`{`
    `if (T)//如果二叉树非空`
    `{`
        `destory(T->lChild);//删除二叉树的左子树`
        `destory(T->rChild);//删除二叉树的右子树`
        `delete T;`
    `}`
`}`
`//将指针S所指节点插入二叉排序中`
`template< class ElementType>`
`void BalanceBiTree<ElementType>::insert(Node<ElementType>*& T, Node<ElementType>* S)`
`{`
    `if (T == NULL)//如果二叉树为空二叉树,则把节点插入到根节点位置`
        `T = S;`
    `else if (S->data < T->data)//二叉搜索树插入方式,如果插入节点的值小于当前指针所指的值,则插入到左子树中`
        `insert(T->lChild, S);`
    `else//如果插入节点的值大于当前指针所指的值,则插入到右子树中`
        `insert(T->rChild, S);`
`}`
`//求树的高度`
`template< class ElementType>`
`int BalanceBiTree<ElementType>::BiTreeDepth(Node <ElementType>* T)`
`{`
    `int m, n;`
    `if (T == NULL)`
        `return 0;           //空树,高度为0`
    `else {`
        `m = BiTreeDepth(T->lChild);   //求左子树高度(递归)`
        `n = BiTreeDepth(T->rChild);   //求右子树高度(递归)`
        `if (m > n)//左子树高度较大,则输出左子树高度`
        `{`
            `return m + 1;//加上根节点`
        `}`
        `else {`
            `return n + 1;`
        `}`
    `}`
`}`
`//求树中节点的平衡因子,从树中节点开始计算,不一定从根节点开始计算`
`template< class ElementType>`
`int BalanceBiTree<ElementType>::getNodeFactor(Node<ElementType>* T)`
`{`
    `int m = 0, n = 0;`
    `if (T)`
    `{`
        `m = BiTreeDepth(T->lChild);///左子树高度`
        `n = BiTreeDepth(T->rChild);//右子树高度`
    `}`
    `return m - n;//左右子树的高度差`
`}`
`//求树中的每个节点的平衡因子`
`template< class ElementType>`
`void BalanceBiTree<ElementType>::factorForTree(Node<ElementType>*& T)
{
    if (T)
    {
        T->balanceFctor = getNodeFactor(T);//获得根节点的平衡因子
        factorForTree(T->lChild);//左子树的平衡因子
        factorForTree(T->rChild);//右子树的平衡因子
    }
}
//获得平衡因子为2或-2的节点,每次只会反回一个节点
template< class ElementType>
void BalanceBiTree<ElementType>::nodeFctorIsTwo(Node<ElementType>*& T, Node<ElementType>*& p)
{
    if (T)
    {
        if (T->balanceFctor == 2 || T->balanceFctor == -2)
        {
            p = T;
        }
        nodeFctorIsTwo(T->lChild, p);//左子树
        nodeFctorIsTwo(T->rChild, p);//右子树
    }
}
//获得平衡因子为2或-2的节点的父节点
template< class ElementType>
void BalanceBiTree<ElementType>::nodeFctorIsTwoFather(Node<ElementType>*& T, Node<ElementType>*& f)`
`{`
    `if (T)`
    `{`
        `if (T->lChild != NULL)//左子树非空`
        `{`
            `if (T->lChild->balanceFctor == 2 || T->lChild->balanceFctor == -2)`
            `{`
                `f = T;`
            `}`
        `}`
        `if (T->rChild != NULL)`
        `{`
            `if (T->rChild->balanceFctor == 2 || T->rChild->balanceFctor == -2)`
            `{`
                `f = T;`
            `}`
        `}`
        `nodeFctorIsTwoFather(T->lChild, f);//递归左子树`
        `nodeFctorIsTwoFather(T->rChild, f);//递归右子树`
    `}`
`}`
`//LL调整,二叉树中出现连续三个左节,当前节点平衡节点为2,左子树节点不为2`

`template< class ElementType>`
`void BalanceBiTree<ElementType>::LLAdjust(Node<ElementType>*& T, Node<ElementType>*& p, Node<ElementType>*& f)
{
    Node<ElementType>* r;`
    `if (T == p)           //->balanceFctor==2&&T->lChild->balanceFctor!=2`
    `{`
        `cout << "LL调整" << endl;`
        `T = p->lChild;        //将P的左孩子提升为新的根节点`
        `r = T->rChild;`
        `T->rChild = p;        //将p降为其左孩子的右孩子`
        `p->lChild = r;        //将p原来的左孩子的右孩子连接其p的左孩子`

    }
    else {
        if (f->lChild == p)     //f的左孩子是p
        {
            cout << "LL调整" << endl;
            f->lChild = p->lChild;        //将P的左孩子提升为新的根节点
            r = f->lChild->rChild;
            f->lChild->rChild = p;        //将p降为其左孩子的右孩子
            p->lChild = r;        //将p原来的左孩子的右孩子连接其p的左孩子
        }
        if (f->rChild == p)     //f的右孩子是p
        {
            cout << "LL调整" << endl;
            f->rChild = p->lChild;        //将P的左孩子提升为新的根节点
            r = f->rChild->rChild;
            f->rChild->rChild = p;        //将p降为其左孩子的右孩子
            p->lChild = r;        //将p原来的左孩子的右孩子连接其p的左孩子
        }
    }

`}`
`//LR调整`
`template< class ElementType>`
`void BalanceBiTree<ElementType>::LRAdjust(Node<ElementType>*& T, Node<ElementType>*& p, Node<ElementType>*& f)
{
    Node<ElementType>* l, * r;`
    `if (T == p)           //->balanceFctor==2&&T->lChild->balanceFctor!=2`
    `{`
        `cout << "LR调整" << endl;`
        `T = p->lChild->rChild;    //将P的左孩子的右孩子提升为新的根节点`
        `r = T->rChild;`
        `l = T->lChild;`
        `T->rChild = p;`
        `T->lChild = p->lChild;`
        `T->lChild->rChild = l;`
        `T->rChild->lChild = r;`
    `}`
    `else {`
        `if (f->rChild == p)     //f的左孩子是p`
        `{`
            `cout << "LR调整" << endl;`
            `f->rChild = p->lChild->rChild;    //将P的左孩子的右孩子提升为新的根节点`
            `r = f->rChild->rChild;`
            `l = f->rChild->lChild;`
            `f->rChild->rChild = p;`
            `f->rChild->lChild = p->lChild;`
            `f->rChild->lChild->rChild = l;`
            `f->rChild->rChild->lChild = r;`
        `}`
        `if (f->lChild == p)     //f的左孩子是p`
        `{`
            `cout << "LR调整" << endl;`
            `f->lChild = p->lChild->rChild;    //将P的左孩子的右孩子提升为新的根节点`
            `r = f->lChild->rChild;`
            `l = f->lChild->lChild;`
            `f->lChild->rChild = p;`
            `f->lChild->lChild = p->lChild;`
            `f->lChild->lChild->rChild = l;`
            `f->lChild->rChild->lChild = r;`
        `}`
    `}`
`}`
`//RL调整`
`template< class ElementType>`
`void BalanceBiTree<ElementType>::RLAdjust(Node<ElementType>*& T, Node<ElementType>*& p, Node<ElementType>*& f)
{
    Node<ElementType>* l, * r;`
    `if (T == p)           //->balanceFctor==-2&&T->rChild->balanceFctor!=-2`
    `{`
        `cout << "RL调整" << endl;`
        `T = p->rChild->lChild;`
        `r = T->rChild;`
        `l = T->lChild;`
        `T->lChild = p;`
        `T->rChild = p->rChild;`
        `T->lChild->rChild = l;`
        `T->rChild->lChild = r;`
    `}`
    `else {`
        `if (f->rChild == p)     //f的左孩子是p`
        `{`
            `cout << "RL调整" << endl;`
            `f->rChild = p->rChild->lChild;`
            `r = f->rChild->rChild;`
            `l = f->rChild->lChild;`
            `f->rChild->lChild = p;`
            `f->rChild->rChild = p->rChild;`
            `f->rChild->lChild->rChild = l;`
            `f->rChild->rChild->lChild = r;`
        `}`
        `if (f->lChild == p)     //f的左孩子是p`
        `{`
            `cout << "RL调整" << endl;`
            `f->lChild = p->rChild->lChild;`
            `r = f->lChild->rChild;`
            `l = f->lChild->lChild;`
            `f->lChild->lChild = p;`
            `f->lChild->rChild = p->rChild;`
            `f->lChild->lChild->rChild = l;`
            `f->lChild->rChild->lChild = r;`
        `}`
    `}`
`}`
`//RR调整`
`template< class ElementType>`
`void BalanceBiTree<ElementType>::RRAdjust(Node<ElementType>*& T, Node<ElementType>*& p, Node<ElementType>*& f)
{
    Node<ElementType>* l;`
    `if (T == p)                   //->balanceFctor==-2&&T->rChild->balanceFctor!=-2`
    `{`
        `cout << "RR调整" << endl;`
        `T = p->rChild;        //将P的右孩子提升为新的根节点`
        `l = T->lChild;`
        `T->lChild = p;        //将p降为其右孩子的左孩子`
        `p->rChild = l;        //将p原来的右孩子的左孩子连接其p的右孩子`
    `//注意:p->rChild->balanceFctor==0插入节点时用不上,删除节点时可用`
    `}`
    `else {`
        `if (f->rChild == p)     //f的右孩子是p`
        `{`
            `cout << "RR调整" << endl;`
            `f->rChild = p->rChild;        //将P的右孩子提升为新的根节点`
            `l = f->rChild->lChild;`
            `f->rChild->lChild = p;        //将p降为其右孩子的左孩子`
            `p->rChild = l;        //将p原来的右孩子的左孩子连接其p的右孩子`
        `}`
        `if (f->lChild == p)     //f的左孩子是p`
        `{`
            `cout << "RR调整" << endl;`
            `f->lChild = p->rChild;        //将P的左孩子提升为新的根节点`
            `l = f->lChild->lChild;`
            `f->lChild->lChild = p;        //将p降为其左孩子的左孩子`
            `p->rChild = l;        //将p原来的右孩子的左孩子连接其p的右孩子`
        `}`
    `}`
`}`
`//集成四种调整,并实时更新平衡因子`
`template< class ElementType>`
`void BalanceBiTree<ElementType>::AllAdjust(Node<ElementType>*& T)
{
    Node<ElementType>* f = NULL, * p = NULL;`
    `factorForTree(T);`
    `nodeFctorIsTwoFather(T, f);`
    `nodeFctorIsTwo(T, p);`
    `while (p)`
    `{`
        `factorForTree(T);`
        `if (p->balanceFctor == 2 && (p->lChild->balanceFctor == 1 || p->lChild->balanceFctor == 0))//LL调整`
        `{`
            `LLAdjust(T, p, f);`
            `factorForTree(T);`
        `}`
        `else if (p->balanceFctor == 2 && p->lChild->balanceFctor == -1)//LR调整`
        `{`
            `LRAdjust(T, p, f);`
            `factorForTree(T);`
        `}`
        `else if (p->balanceFctor == -2 && p->rChild->balanceFctor == 1)//RL调整`
        `{`
            `RLAdjust(T, p, f);`
            `factorForTree(T);`
        `}`
        `else if (p->balanceFctor == -2 && (p->rChild->balanceFctor == -1 || p->rChild->balanceFctor == 0))  //||p->rChild->balanceFctor==0RR调整`
        `{`
            `RRAdjust(T, p, f);`
        `}`
        `f = NULL;`
        `p = NULL;`
        `nodeFctorIsTwoFather(T, f);`
        `nodeFctorIsTwo(T, p);`
    `}`
`}`
`//先序遍历输出`
`template< class ElementType>`
`void BalanceBiTree<ElementType>::preOrderTraverse(Node<ElementType>* T, int level)`
`{`
    `if (T)`
    `{`
        `cout << "先序" << "(" << T->data << "," << level << ")" << " ";`
        `preOrderTraverse(T->lChild, level + 1);`
        `preOrderTraverse(T->rChild, level + 1);`
    `}`
`}`
`//中序遍历算法`
`template<class ElementType>`
`void BalanceBiTree<ElementType>::inOrderTraverse(Node <ElementType>* T, int level)`
`{`
    `if (T)`
    `{`
        `inOrderTraverse(T->lChild, level + 1);  //递归调用先序遍历左子树`
        `cout << "中序" << "(" << T->data << "," << level << ")" << " ";           //访问根节点`
        `inOrderTraverse(T->rChild, level + 1);  //递归调用先序遍历右子树`
    `}`
`}`
`//二叉树转数组`
`template<class ElementType>`
`void BalanceBiTree<ElementType>::BiTreeToArray(Node <ElementType>* T, ElementType A[], int i, int& count)`
`{`
    `if (T != NULL)`
    `{`
        `A[i] = T->data;`
        `if (i > count)`
            `count = i;`
        `BiTreeToArray(T->lChild, A, 2 * i, count);//左子树下标为根节点下标的两倍`
        `BiTreeToArray(T->rChild, A, 2 * i + 1, count);//右子树下标为根节点小标的两倍+1`
    `}`
`}`
`//对二叉链表表示的二叉树,按从上到下,从左到右打印结点值,即按层次打印,层次遍历(广度优先搜索)`
`//以数组形式来简化参次遍历,不需要进行递归,但是要求二叉树节点元素不为空的时候进行`
`template<class ElementType>`
`void BalanceBiTree<ElementType>::LevelTraverse(Node <ElementType>* T, ElementType B[], int num)`
`{`
    `int n, i, j, t, q, s, p, m = 0, k = 0;`
    `n = (int)((log(num) / log(2)) + 1);`
    `p = n;`
    `for (i = 0; i < n; i++)`
    `{`
        `k = pow(2, m) + k;`
        `t = pow(2, m);`
        `j = pow(2, p - 1) - 1;`
        `q = pow(2, p) - 1;`
        `s = q;`
        `for (j; j > 0; j--)`
        `{`
            `cout << " ";`
        `}`
        `for (t; t <= k; t++)`
        `{`
            `if (B[t] == 0)`
            `{`
                `cout << "*";
                for (q; q > 0; q--)
                    cout << " ";
                q = s;
            }
            else {
                cout << B[t];
                for (q; q > 0; q--)
                    cout << " ";
                q = s;
            }
        }
        m++;
        p--;
        j = n - i - 1;
        cout << endl;
    }
}
//交互创建二叉平衡树
template< class ElementType>
void BalanceBiTree<ElementType>::createSubBalanceBiTree(Node<ElementType>*& T)`
`{`
    `int level = 1;`
    `int i = 1, j = 0;`
    `int A[100] = { 0 };`
    `int length = 0;`
    `ElementType x;`
    `Node<ElementType>* S, * p;`
    `T = new Node<ElementType>;`
    `T->balanceFctor = 0;`
    `T->lChild = NULL;`
    `T->rChild = NULL;`
    `p = T;`
    `cout << "请输入元素(-9999退出):";`
    `cin >> x;`
    `T->data = x;`
    `while (x != -9999)`
    `{`
        `cout << "请输入元素:";`
        `cin >> x;`
        `if (x == -9999)`
            `return;`
        `S = new Node<ElementType>;`
        `S->data = x;`
        `S->balanceFctor = 0;`
        `S->lChild = NULL;`
        `S->rChild = NULL;`
        `insert(p, S);`
        `AllAdjust(T);`
        `p = T;`
        `inOrderTraverse(T, level);`
        `cout << endl;`
        `BiTreeToArray(T, A, i, length);`
        `cout << "其树状图为:" << endl;`
        `LevelTraverse(T, A, length);`
        `j = 0;`
        `for (j; j < 100; j++)`
            `A[j] = 0;`
        `level = 1;`
        `i = 1;`
    `}`
`}`
`//从数组中创建平衡二叉树`
`template< class ElementType>`
`void BalanceBiTree<ElementType>::createBalanceBiTreeFromArray(Node<ElementType>*& T, ElementType A[], int n)
{
    Node<ElementType>* S, * p;`
    `int i = 1;`
    `T = new Node<ElementType>;`
    `T->balanceFctor = 0;`
    `T->lChild = NULL;`
    `T->rChild = NULL;`
    `p = T;`
    `T->data = A[0];`
    `n = n - 1;`
    `while (n)`
    `{`
        `S = new Node<ElementType>;`
        `S->data = A[i];`
        `S->balanceFctor = 0;`
        `S->lChild = NULL;`
        `S->rChild = NULL;`
        `insert(p, S);`
        `AllAdjust(T);`
        `p = T;`
        `i++;`
        `n--;`
    `}`
`}`
`//查找元素x`
`template<class ElementType>`
`void BalanceBiTree<ElementType>::search(Node <ElementType>*& T, Node <ElementType>*& p, ElementType x)`
`{`
    `if (T)`
    `{`
        `if (T->data == x)`
            `p = T;`
        `search(T->lChild, p, x);`
        `search(T->rChild, p, x);`
    `}`
`}`
`//获取某个元素的父亲指针,不存在返回NULL`
`template<class ElementType>`
`Node <ElementType>* BalanceBiTree<ElementType>::getElementFatherPointer(Node <ElementType>*& T, Node <ElementType>*& f, ElementType x)`
`{`
    `if (T)`
    `{`
        `if (T->lChild != NULL)`
        `{`
            `if (T->lChild->data == x)`
                `f = T;`
        `}`
        `if (T->rChild != NULL)`
        `{`
            `if (T->rChild->data == x)`
                `f = T;`
        `}`
        `getElementFatherPointer(T->lChild, f, x);`
        `getElementFatherPointer(T->rChild, f, x);`
    `}`
    `return 0;`
`}`
`//获取前驱元素`
`template<class ElementType>`
`void BalanceBiTree<ElementType>::getPriorElement(Node <ElementType>*& T, ElementType& min, ElementType& max)
{
    if (T)
    {
        min = T->data;
        if (min > max)
            max = min;
        getPriorElement(T->lChild, min, max);
        getPriorElement(T->rChild, min, max);
    }
}
//获取某个元素的前驱指针
template<class ElementType>
Node <ElementType>* BalanceBiTree<ElementType>::getElementPriorPointer(Node <ElementType>*& T)
{
    Node <ElementType>* p;`
    `ElementType min = 0, max = -9999;`
    `getPriorElement(T, min, max);`
    `search(T, p, max);`
    `return p;`
`}`
`//获取后继元素`
`template<class ElementType>`
`void BalanceBiTree<ElementType>::getNextElement(Node <ElementType>*& T, ElementType& min, ElementType& max)
{
    if (T)
    {
        max = T->data;
        if (min > max)
            min = max;
        getNextElement(T->lChild, min, max);
        getNextElement(T->rChild, min, max);
    }
}
//获取某个元素的后继指针
template<class ElementType>
Node <ElementType>* BalanceBiTree<ElementType>::getElementNextPointer(Node <ElementType>*& T)
{
    Node <ElementType>* p;`
    `ElementType min = 9999, max = 0;`
    `getNextElement(T, min, max);`
    `search(T, p, min);`
    `return p;`
`}`
`//删除叶子节点操作`
`template<class ElementType>`
`void BalanceBiTree<ElementType>::deleteLeafNode(Node <ElementType>*& T, Node <ElementType>*& p, Node <ElementType>*& f)
{
    if (p == NULL)
    {
        cout << "此节点不存在,不能删除" << endl;
        return;
    }
    if (T == p)        //根节点即为叶子节点
    {
        delete p;
        T = NULL;
    }
    else {           //删除节点为非根节点的叶子节点
        if (f->lChild == p)
        {
            delete p;
            f->lChild = NULL;
        }
        if (f->rChild == p)
        {
            delete p;
            f->rChild = NULL;
        }
    }
}
//删除仅有左子树或只有右子树的节点
template<class ElementType>
void BalanceBiTree<ElementType>::deleteOneBranchNode(Node <ElementType>*& T, Node <ElementType>*& p, Node <ElementType>*& f)`
`{`
    `if (p == NULL)`
    `{`
        `cout << "此节点不存在,不能删除" << endl;`
        `return;`
    `}`
    `if (T == p)`
    `{`
        `if (T->lChild == NULL && T->rChild != NULL)`
        `{`
            `T = p->rChild;`
            `delete p;`
        `}`
        `if (T->rChild == NULL && T->lChild != NULL)`
        `{`
            `T = p->lChild;`
            `delete p;`
        `}`
    `}`
    `else {`
        `if (p->lChild != NULL)`
        `{`
            `if (f->lChild == p)`
                `f->lChild = p->lChild;`
            `else`
                `f->rChild = p->lChild;`
        `}`
        `if (p->rChild != NULL)`
        `{`
            `if (f->lChild == p)`
                `f->lChild = p->rChild;`
            `else`
                `f->rChild = p->rChild;`
        `}`
    `}`
`}`
`//删除既有左子树又有右子树的节点`
`template<class ElementType>`
`void BalanceBiTree<ElementType>::deleteTwoBranchNode(Node <ElementType>*& T, Node <ElementType>*& p)`
`{`
    `Node <ElementType>* f, * next, * prior;`
    `if (p == NULL)`
    `{`
        `cout << "此节点不存在,不能删除" << endl;`
        `return;`
    `}`
    `if (p->balanceFctor == 1)                             //p的平衡因子为1时,用p的前驱节点代替p`
    `{`
        `prior = getElementPriorPointer(p->lChild);             //获得x的前驱指针`
        `if (prior->lChild != NULL && prior->rChild == NULL)   //情况一前驱节点只有左孩子`
        `{`
            `p->data = prior->data;`
            `prior->data = prior->lChild->data;`
            `delete prior->lChild;`
            `prior->lChild = NULL;`
        `}`
        `if (prior->lChild == NULL && prior->rChild == NULL)    //情况二前驱节点为叶子节点`
        `{`
            `getElementFatherPointer(T, f, prior->data); //得到前驱节点的父节点`
            `p->data = prior->data;`
            `delete prior;`
            `f->rChild = NULL;`
        `}`
    `}`
    `else if (p->balanceFctor == -1)                             //p的平衡因子为-1时,用p的后继节点代替p`
    `{`
        `next = getElementNextPointer(p->rChild);                //获得x的后继指针`
        `cout << next->data;`
        `int level = 1;`
        `if (next->rChild != NULL && next->lChild == NULL)      //情况一后继节点只有右孩子`
        `{`
            `p->data = next->data;`
            `next->data = next->rChild->data;`
            `delete next->rChild;`
            `next->rChild = NULL;`
        `}`
        `else if (next->rChild == NULL && next->lChild == NULL)       //情况二后继节点为叶子节点`
        `{`
            `getElementFatherPointer(T, f, next->data);     //得到后继节点的父节点`
            `p->data = next->data;`
            `delete next;`
            `f->lChild = NULL;`
        `}`
    `}`
    `else if (p->balanceFctor == 0)     //p的平衡因子为0时,用p的前驱或后继节点代替p,这里用前驱`
    `{`
        `prior = getElementPriorPointer(p->lChild);               //获得x的前驱指针`
        `if (prior->lChild != NULL && prior->rChild == NULL)     //情况一前驱节点只有左孩子`
        `{`
            `p->data = prior->data;`
            `prior->data = prior->lChild->data;`
            `delete prior->lChild;`
            `prior->lChild = NULL;`
        `}`
        `if (prior->lChild == NULL && prior->rChild == NULL)      //情况二前驱节点为叶子节点`
        `{`
            `getElementFatherPointer(T, f, prior->data);     //得到前驱节点的父节点`
            `p->data = prior->data;`
            `delete prior;`
            `if (p == f)                                      //这块需要特殊记忆,唯独p->balanceFctor==0需要考虑***`
                `f->lChild = NULL;`
            `else`
                `f->rChild = NULL;`

        }
    }

`}`
`//集成删除的三种情况的操作`
`template<class ElementType>`
`void BalanceBiTree<ElementType>::deleteOperate(Node <ElementType>*& T, ElementType x)
{
    Node <ElementType>* f, * p = NULL;`
    `search(T, p, x);`
    `getElementFatherPointer(T, f, x);`
    `if (p == NULL)`
    `{`
        `cout << "不存在此节点,删除失败!" << endl;`
        `return;`
    `}`
    `if (p->lChild == NULL && p->rChild == NULL)  //情况一删除节点为叶子节点`
    `{`
        `deleteLeafNode(T, p, f);`
        `if (T != NULL)`
            `AllAdjust(T);`
    `}`
    `else if ((p->lChild == NULL && p->rChild != NULL) || (p->lChild != NULL && p->rChild == NULL))`
    `{`
        `deleteOneBranchNode(T, p, f);`
        `if (T != NULL)`
            `AllAdjust(T);`
    `}`
    `else                           //if(p->lChild!=NULL&&p->rChild!=NULL)`
    `{`
        `deleteTwoBranchNode(T, p);`
        `if (T != NULL)`
            `AllAdjust(T);`
    `}`
`}`
`template<class ElementType>`
`int BinarySearch(ElementType A[], int n, ElementType x)`
`{`
    `int mid, low = 0, high = n - 1;`
    `while (low <= high)`
    `{`
        `mid = (low + high) / 2;`
        `if (x == A[mid])`
        `{`
            `return mid;`
        `}`
        `else if (x < A[mid])`
        `{`
            `high = mid - 1;`
        `}`
        `else {`
            `low = mid + 1;`
        `}`
    `}`
    `return -1;`
`}`
`//初始化数组`
`void initArray(int A[])`
`{`
    `int i = 0;`
    `for (i; i < 100; i++)`
        `A[i] = 0;`
`}`
`int main()`
`{`
    `int x, y;`
    `int i = 1;`
    `int level = 1;`
    `int A[100] = { 0 };`
    `int B[100] = { 0 };`
    `int length = 0;       //存储数组A的有效元素个数`
    `Node<int>* root;`
    `Node<int>* p;`
    `BalanceBiTree<int> T(root);`
    `BalanceBiTree<int>::menu();`
    `cout << "请输入执行序号:";`
    `cin >> x;`
    `while (x != 0)`
    `{`
        `switch (x)`
        `{`
        `case 1:`
            `if (root != NULL)`
                `T.destory(root);`
            `length = 0;`
            `cout << "请输入数组元素的值:";`
            `cin >> y;`
            `while (y != -9999)`
            `{`
                `A[length] = y;`
                `length++;`
                `cout << "请输入数组元素的值:";`
                `cin >> y;`
            `}`
            `cout << "请输入要查询元素的值:";`
            `cin >> x;`
            `if (BinarySearch(A, length + 1, x) == -1)`
                `cout << "不存i=1;在!" << endl;`
            `else {`
                `cout << "存在,其下标为:" << BinarySearch(A, length + 1, x) << endl;`
            `}`
            `break;`
        `case 2:`
            `T.createSubBalanceBiTree(root);`
            `break;`
        `case 3:`
            `cout << "请输入要查询元素的值:";`
            `cin >> x;`
            `T.search(root, p, x);`
            `if (p != NULL)`
            `{`
                `if (p->data == x)`
                    `cout << "元素存在!" << endl;`
                `else`
                    `cout << "元素不存在!" << endl;`
            `}`
            `else {`
                `cout << "元素不存在!" << endl;`
            `}`
            `break;`
        `case 4:`
            `i = 1;`
            `initArray(A);`
            `level = 1;`
            `cout << "请输入要删除元素的值:";`
            `cin >> x;`
            `T.deleteOperate(root, x);`
            `T.inOrderTraverse(root, level);`
            `T.BiTreeToArray(root, A, i, length);`
            `cout << "其树状图为:" << endl;`
            `T.LevelTraverse(root, A, length);`
            `break;`
        `case 5:`
            `initArray(A);`
            `if (root != NULL)`
                `T.destory(root);`
            `length = 0;`
            `y = 1;`
            `for (y; y <= 26; y++)`
            `{`
                `A[length] = y;`
                `length++;`
            `}`
            `T.createBalanceBiTreeFromArray(root, A, length);`
            `level = 1;`
            `i = 1;`
            `T.inOrderTraverse(root, level);`
            `cout << endl;`
            `initArray(A);`
            `T.BiTreeToArray(root, A, i, length);`
            `cout << "其树状图为:" << endl;`
            `T.LevelTraverse(root, A, length);`
            `break;`
        `case 6:`
            `i = 1;`
            `initArray(A);`
            `T.AllAdjust(root);`
            `T.BiTreeToArray(root, A, i, length);`
            `cout << "其树状图为:" << endl;`
            `T.LevelTraverse(root, A, length);`
            `break;`
        `}`
        `system("PAUSE");`
        `system("CLS");`
        `BalanceBiTree<int>::menu();`
        `cout << "请输入执行序号:";`
        `cin >> x;`
    `}`
    `if (root != NULL)`
        `T.destory(root);`
    `return 0;`
`}`

B-树

三、散列表的查找

`

#include<stdio.h>`
`#include<stdlib.h>`
`#include<iostream>`
`#define M 13`
`using namespace std;`
`typedef int ElemType;`
`int kj=0;`
`typedef struct Node {//链表节点的数据结构`
	`ElemType data;`
	`struct Node* next;`
`}Node,*pNode;`
`typedef struct HashNode {//哈希表每个槽的数据结构`
	`pNode first;//指向第一个节点`

`}HashNode,*HashTable;`

`HashTable create_HashTable(int n) {`
	`int i;`
	`HashTable hashtable = (HashTable)malloc(n * sizeof(HashNode));`
	`if (!hashtable) {`
		`cout << "哈希表创建失败" << endl;`
		`exit(-1);`
	`}`
	`for (i = 0; i < n; i++) {`
		`hashtable[i].first = NULL;//哈希表制空`
	`}`
	`return hashtable;`
`}`
`//在哈希表中查找数据,哈希函数是key%M`
`//查找成功就返回在链表中的位置`
`//查找失败则返回NULL`
`pNode search_HashTable(HashTable hashtable, ElemType data,int &k) {`
	`if (!hashtable)`
		`return NULL;`
	`pNode pCur = hashtable[data % M].first;`
	`while (pCur && pCur->data != data) {`
		`k++;`
		`pCur = pCur->next;`
	`}`
	`return pCur;`
`}`
`bool insert_HashTable(HashTable hashtable, ElemType data) {`
	`if (search_HashTable(hashtable, data,kj))//如果已经存在,返回false`
       `return false;`
	`//否则为插入数据分配空间`
	`pNode pNew = (pNode)malloc(sizeof(Node));`
	`if (!pNew) {`
		`cout << "分配数据空间失败"<<endl;`
		`exit(-1);`
	`}`
	`pNew->data = data;`
	`pNew->next = NULL;`

	pNode pCur = hashtable[data % M].first;
	if (!pCur) {//插入位置为第一个位置
		hashtable[data % M].first = pNew;
	}
	else {//只有pCur->next才可以链接pNew
		while (pCur->next) {
			pCur = pCur->next;
			
		}
		pCur->next = pNew;
	}
	return true;

`}`
`//从哈希表中删除数据`
`//如果data不存在,则返回false`
`//否则,删除并返回true`
`bool delete_HashTable(HashTable hashtable, ElemType data) {`
	`if (!search_HashTable(hashtable, data,kj))`
		`return false;`

	pNode pCur = hashtable[data % M].first;
	pNode pPre = pCur;//被删节点的前一个节点,初始值与Cur相同
	if (pCur->data == data) {
		hashtable[data % M].first = pCur->next;
	}
	else {
		while (pCur && pCur->data != data) {
			pPre = pCur;
			pCur = pCur->next;
		}
		pPre->next = pCur->next;
	}
	free(pCur);
	pCur = 0;
	return true;

`}`
`void OutHashLink(HashTable hashtable) {`
	`for (int i = 0; i < M; i++) {`
		`pNode pCur=hashtable[i].first;`
		`cout << "关键字为:" << i;`
		`while (pCur) {`
			`cout << "数据为:" << pCur->data<<"   " ;`
			`pCur = pCur->next;`
		`}`
		`cout << endl;`
	`}`
`}`
`void destory_HashTable(HashTable hashtable, int n) {`
	`int i;`
	`for (int i = 0; i < n; i++) {`
		`pNode pCur = hashtable[i].first;`
		`pNode pDel = NULL;`
		`while (pCur) {`
			`pDel = pCur;`
			`pCur = pCur->next;`
			`free(pDel);`
			`pDel = 0;`
		`}`
	`}`
	`free(hashtable);`
	`hashtable = 0;`
`}`
`int main() {`
	`int len = 12;`
	`HashTable hashtable;`
	`int keys[12] = { 19,14,23,1,68,20,84,27,55,11,10,79 };`
	`hashtable = create_HashTable(10);`
	`for (int i = 0; i < 12; i++) {`
		`insert_HashTable(hashtable, keys[i]);`
	`}`
	`OutHashLink(hashtable);`
	`for (int i = 0; i < 12;i++) {`
		`int k = 0;`
		`search_HashTable(hashtable, keys[i], k);`
		`cout << "比较次数: " << k << "数据为:"<<keys[i]<<endl;`
	`}`
	`return 0;`
`}`
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值