实验八 查找算法的实现

 

1.实验目的

熟练掌握顺序表和有序表的查找方法,掌握其时间复杂度的分析方法

2.实验内容

(1)验证并设计顺序表的查找(顺序查找、折半查找)算法

(2)验证二叉排序树上的查找(创建、查找、插入)算法

(3)验证Hash表查找(Hash函数定义、建立,查找,插入)算法

 

 

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
typedef int Status;
typedef int ElemType;
typedef int KeyType;

typedef struct {
	KeyType key;//关键字域
						//其他域
}SElemType;

typedef struct {
	SElemType *elem;//数据元素存储空间基址,建表时按照实际长度分配,0号元素留空
	int length;//表长度
}SSTable;

int Search_Seq(SSTable ST, KeyType key)
{//在顺序表中顺序查找其关键字等于key的数据元素,
//若找到,函数值为该元素在表中的位置,否则为0
	int i;
	ST.elem[0].key = key;//哨兵
	for (i = ST.length; !EQ(ST.elem[i].key, key); --i);//从后往前找
	if (i == 0)
		printf("该元素不在顺序表中");
	return i;//找不到时,i为0

}

Status EQ(ElemType a, ElemType b)
{
	if (a == b)
		return TRUE;
	else
		return FALSE;
}


Status CreateTable(SSTable *ST)
{
	printf("输入顺序表长度:");
	scanf_s("%d", &ST->length);
	ST->elem = (SElemType*)malloc((ST->length + 1) * sizeof(ElemType));
	printf("请输入表中各个元素的值:");
	for (int i = 1; i <= ST->length; i++)
	{
		scanf_s("%d", &ST->elem[i].key);
	}
	return OK;
}

int main()
{
	SSTable ST;
	int  key, n;
	CreateTable(&ST);
	printf("请输入你要查找的值:");
	scanf_s("%d", &key);
	n = Search_Seq(ST, key);
	printf("你要查找的元素在表中的位置是%d\n", n);
	system("pause");
	return 0;
}


 

 

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
typedef int Status;
typedef int ElemType;
typedef int KeyType;
typedef struct {
	KeyType key;//关键字域
						//其他域
}SElemType;

typedef struct {
	SElemType *elem;//数据元素存储空间基址,建表时按照实际长度分配,0号元素留空
	int length;//表长度
}SSTable;
Status EQ(ElemType a, ElemType b)
{
	if (a == b)
		return OK;
	else
		return FALSE;
}
Status LT(ElemType a, ElemType b)
{
	if (a < b)
		return OK;
	else
		return FALSE;
}

int Search_Bin(SSTable ST, KeyType key)
{//在有序查找表中折半查找其关键字等于key的数据元素,若找到,则函数值
//为该元素在表中的位置,否则为0
	int low, high, mid;
	low = 1;
	high = ST.length;//置区间初值
	while (low <= high)
	{
		mid = (low + high) / 2;
		if (EQ(key, ST.elem[mid].key))
			return mid;//找到待查元素
		else if (LT(key, ST.elem[mid].key))
			high = mid - 1;//继续在前半区间进行查找
		else
			low = mid + 1;//继续在后半区间进行查找
	}
	return 0;//顺序表中不存在待查元素
}


Status CreateTable(SSTable *ST)
{
	printf("输入顺序表长度:");
	scanf_s("%d", &ST->length);
	ST->elem = (SElemType*)malloc((ST->length + 1) * sizeof(ElemType));
	printf("请输入表中各个元素的值:");
	for (int i = 1; i <= ST->length; i++)
	{
		scanf_s("%d", &ST->elem[i].key);
	}
	return OK;
}

int main()
{
	SSTable ST;
	int  key, n;
	CreateTable(&ST);
	printf("请输入你要查找的值:");
	scanf_s("%d", &key);
	n = Search_Bin(ST, key);
	printf("你要查找的元素在表中的位置是%d\n", n);
	system("pause");
	return 0;
}

 

 

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 1
typedef int Status;
typedef int KeyType;
typedef int ElemType;
typedef struct BiTNode {
	KeyType data;
	struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

Status SearchBST(BiTree T, KeyType key, BiTree f, BiTree *p) {
	//二叉排序树查找算法

	//在根指针T所指二叉排序树中递归的查找其关键字等于key的数据元素,若查找成功
	//则根指针p指向该数据元素结点,并返回TRUE,否则指针p指向查找路径上访问的
	//最后一个结点并返回TRUE,指针f指向T的双亲,其初始调用值为NULL
	if (!T) {
		*p = f;
		return FALSE;
	}//查找不成功
	else if (key == T->data) {
		*p = T;
		return TRUE;
	}//查找成功
	else if (key < T->data)
		return SearchBST(T->lchild, key, T, p);//在左子树中继续查找
	else
		return SearchBST(T->rchild, key, T, p);//在右子树中继续查找
}

Status InsertBST(BiTree *T, ElemType e)
{
	BiTree p, s;
	if (!SearchBST(*T, e, NULL, &p))
	{
		s = (BiTree)malloc(sizeof(BiTNode));
		s->data = e;
		s->lchild = s->rchild = NULL;
		if (!p) {
			*T = s;     // 被插结点* s 为新的根结点     
		}
		else if (e < p->data)
		{
			p->lchild = s;  // 被插结点* s 为左孩子   
		}
		else
		{
			p->rchild = s;  // 被插结点* s 为右孩子    
		}
		return TRUE;
	}
	else
	{
		return FALSE;   // 树中已有关键字相同的结点,不再插入   
	}
}

Status Delete(BiTree *p)
{//从二叉排序树中删除结点p ,并重接他的左或者右子树
	BiTree q, s;
	if (!(*p)->rchild)
	{//右子树为空则只需重接他的左或者右子树
		q = *p;
		*p = (*p)->lchild;
		free(q);
	}
	else if (!(*p)->lchild)//左子树为空,重接右子树
	{
		q = *p;
		*p = (*p)->rchild;
		free(q);
	}
	else//左右子树都不空 
	{
		q = *p;
		s = (*p)->lchild;
		while (s->rchild)
		{
			q = s;
			s = s->rchild;
		} //转左,然后向右走到尽头 
		(*p)->data = s->data;//s指向被删结点的“前驱” 
		if (q != *p)
			q->rchild = s->lchild;//重接*p的右子树 
		else
			q->lchild = s->lchild;//重接*p的左子树 
		free(s);
	}
	return OK;
}

Status DeleteBST(BiTree *T, KeyType key) {
	//若二叉排序树上存在关键字等于key的元素,删除该数据元素结点
//并返回true,否则返回FALSE
	if (!*T)
		return FALSE;//不存在关键字等于key的元素
	else {
		if (key == (*T)->data)
			return  Delete(T);
		else if (key < (*T)->data)
			return DeleteBST(&(*T)->lchild, key);
		else  return DeleteBST(&(*T)->rchild, key);
	}
}

Status PrintElement(ElemType e)
{//输出元素e的值
	printf("%4d", e);
	return OK;
}

Status InOrderTraverse(BiTree T, Status(*Visit)(ElemType e))
{
	if (T)
	{
		if (InOrderTraverse(T->lchild, Visit))//访问左子树
			if (Visit(T->data))//访问根结点
				if (InOrderTraverse(T->rchild, Visit))//访问右子树
					return OK;
		return ERROR;
	}
	else
		return OK;
}

int main()
{
	int e, length;
	BiTree T, f, p;
	T = NULL;
	f = NULL;
	printf("输入要构造的二叉排序树的长度:");
	scanf_s("%d", &length);
	printf("输入元素:");
	while (length--)
	{
		scanf_s("%d", &e);
		InsertBST(&T, e);
	}
	printf("二叉排序树的中序遍历结果是:");
	InOrderTraverse(T, PrintElement);
	printf("\n");

	printf("输入要查找的元素:");
	scanf_s("%d", &e);
	if (SearchBST(T, e, f, &p))
		printf("该元素在此二叉排序树中\n");
	else
		printf("该元素不在此二叉排序树中\n");

	printf("输入要插入的元素:");
	scanf_s("%d", &e);
	InsertBST(&T, e);
	printf("插入元素后二叉排序树的中序遍历结果是:");
	InOrderTraverse(T, PrintElement);
	printf("\n");

	printf("输入要删除的元素:");
	scanf_s("%d", &e);
	DeleteBST(&T, e);
	printf("插入元素后二叉排序树的中序遍历结果是:");
	InOrderTraverse(T, PrintElement);
	printf("\n");

	system("pause");
	return 0;
}




 

 

  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值