这次作业比图的作业好做多了!这边建议直接手撕,自己写不出来的可以为挂科做个心理准备。
第一题二分,算法基础题不多哔哔
///*题目:二分检索算法的实现
///*作者:仲舟
///*难度:★★
///*完成时间:2021.06.13
#include <stdio.h>
#include <stdlib.h>
int BinSearch(int data[],int low,int high,int key);
int main()
{
int *data,N,X,pos,i,M;
scanf("%d",&N);
data=(int *)malloc((N+1)*sizeof(int));
for (i=1;i<=N;i++)
scanf("%d",&data[i]);
scanf("%d",&M);
while(M--)
{
scanf("%d",&X);
pos=BinSearch(data,1,N,X);
if (pos==0)
printf("find Error\n");
else
printf("find Success,data[%d]=%d\n",pos,X);
}
}
int BinSearch(int data[],int low,int high,int key)
{
int mid=(high+low)/2;//取中间的值
/*如果找到*/
if(data[mid]==key)//中间的值等于找的值
return mid;//返回下标
/*如果没找到*/
else if(low>=high)//如果该递归已经是最小递归(小下标大于等于大下标时,此递归为1个,不能再二分)
return 0;//没找到,返回0
else//不是最小递归,继续分
return BinSearch(data,low,mid-1,key)+BinSearch(data,mid+1,high,key);//在[low,mid-1]和[mid+1,high]找(因为mid已经找到了)
}
第二题略,不要侮辱我智商→_→
第三题有个迷惑问题:函数bool InsertBST(bstree *pt,ElementType X);用了二级指针pt,由于会对头节点进行修改,需将指针的地址传进去,到了函数里面就成了二级指针,就像void swap(int *a,int *b)一样。而bstree SearchBST(bstree t,ElementType X);不需要二级指针是因为它的作用是传出修改后的指针。
///*题目:二叉排序树的基本运算
///*作者:仲舟
///*难度:★★★★
///*完成时间:2021.06.15
#include<stdio.h>
#include<stdlib.h>
typedef enum {false, true} bool;
typedef int ElementType;
typedef struct node { /*二叉排序树结点定义*/
ElementType key; /*结点值*/
struct node *lchild,*rchild; /*左、右孩子指针*/
} bsnode;
typedef bsnode *bstree;
bstree CreateBST(ElementType Data[],int N);//创建一棵二叉排序树,并返回根结点
bool InsertBST(bstree *pt,ElementType X);//在以*pt为根结点的二叉排序树中,插入一个关键字为X的结点,返回二叉排序树的根结点
//若存在关键字为X的结点,不插入并返回false,否则插入该结点,并返回true
bstree SearchBST(bstree t,ElementType X);//在以t为根结点的二叉排序树中,查找一个关键字为X的结点,
//若不存在关键字为X的结点,返回NULL,否则返回该结点的指针。
void DispBinTree(bstree t);/* 以括号表示法输出二叉排序树t*/
void DestroyBST(bstree t);//销毁一棵二叉排序树t
int main() {
int N,i,M;
ElementType *Data,key;
bstree p,t;
scanf("%d",&N);
Data=(ElementType *)malloc(N*sizeof(ElementType));
for (i=0; i<N; i++)
scanf("%d",&Data[i]);
t=CreateBST(Data,N); /*创建二叉排序树*/
scanf("%d",&M);
printf("\n");
while(M--) {
scanf("%d",&key);
p=SearchBST(t,key);
if (p==NULL) printf("the key %d not found.\n",key);
else printf("the key %d found.\n",key);
}
DestroyBST(t);
return 0;
}
void DispBinTree(bstree t) {
if (t!=NULL) {
printf("%d",t->key);
if (t->lchild || t->rchild) {
printf("(");
DispBinTree(t->lchild);
if (t->rchild) printf(",");
DispBinTree(t->rchild);
printf(")");
}
}
}
void DestroyBST(bstree t) {
if(t!=NULL) {
DestroyBST(t->lchild);
DestroyBST(t->rchild);
free(t);
}
}
bstree CreateBST(ElementType Data[],int N) {
/*根据输入的结点序列,建立一棵二叉排序树,并返回根结点的地址*/
int i;
bstree t=NULL;
for (i=0; i<N; i++) {
if(InsertBST(&t,Data[i])) {
printf("\nthe %d step, insert %d:",i+1,Data[i]);
DispBinTree(t);
} else printf("\nthe %d step, %d exist",i+1,Data[i]);
}
return t;
}
// InsertBST,SearchBST函数写在这里,注意提交完成程序
bstree SearchBST(bstree t,ElementType X) {
/*仲舟提示:设苹果价钱为X,你猜猜X是多少*/
if(t) { //如果t存在
if(t->key==X)//猜对了
return t;//返回指针
if(t->key<X)//少了
return SearchBST(t->rchild,X);//找右孩子(更大的)
if(t->key>X)//多了
return SearchBST(t->lchild,X);//找左孩子(更小的)
}
return NULL;//如果t不存在
}
bool InsertBST(bstree *pt,ElementType X) {
/*仲舟提示:设苹果价钱为X,你猜猜X是多少*/
/*1.找到插入位置*/
bstree now,past=NULL;//拷贝(因为头结点不能动,所以从头节点开始寻找需要拷贝)
now=*pt;
while(now) { //如果当前处理的结点存在
past=now;//保存上次指针,方便新建
if(now->key==X)
return false;//说明已经存在,直接返回
if(now->key<X)//少了
now=now->rchild;//找右孩子
else//多了
now=now->lchild;//找左孩子
}
/*2.新建结点*/
now=(bstree)malloc(sizeof(bsnode));
now->key=X;
now->lchild=now->rchild=NULL;
/*3.结点连接*/
if(past) {//如果pt不为空,就需要连接
if(X<past->key)//比它小连左
past->lchild=now;
else//比它大连右
past->rchild=now;
}
else//如果pt为空,直接将now赋给头节点*pt
*pt=now;
return true;//处理成功
}
第四题没什么难度,主要是注意enum函数的使用。
///*题目:实现散列表的相关运算
///*作者:仲舟
///*难度:★★
///*完成时间:2021.06.15
#include <stdio.h>
#include<stdlib.h>
#define MAXTABLESIZE 100000 /* 允许开辟的最大散列表长度 */
#define ERROR -1
typedef int ElementType; /* 关键词类型用整型 */
/* 散列单元状态类型,含三种状态,分别对应:合法元素、空单元、有已删除元素 */
typedef enum {Legitimate, Empty, Deleted } NodeStateType;
typedef struct HashNode{
ElementType data; /* 存放元素 */
NodeStateType state; /* 单元状态 */
int count;//线性探测次数
}HashCell; //散列单元定义
typedef struct TableNode{ /* 散列表结点定义 */
int tableSize; /* 表的最大长度不超过MAXTABLESIZE */
HashCell *HCs; /* 存放散列单元数据的数组 */
}*HashTable; /* 散列表类型 */
HashTable InitTable(); /* 初始化Hash表 */
int Hash( ElementType Key, int TableSize ) ; //hash函数
void InsertHash(HashTable H, ElementType Key);
//将关键字为Key的记录插入到H中,状态默认为Legitimate,若关键字为Key的记录已经在Hash表中,则不作任何处理。不考虑表满的情况,假设表足够大。
int DeleteHash(HashTable H, ElementType Key);
//将关键字为Key的记录从H中删除,修改单元状态为Deleted,并返回1,若关键字为Key的记录不存在,返回0
int Find( HashTable H, ElementType Key );
//函数Find 使用的散列函数Hash( Key, H->tableSize )从散列表H中查到Key的位置并返回。
//如果Key不存在,则返回ERROR。
void DispHash( HashTable H); //输出Hash表
void DestroyHash( HashTable H); //释放Hash表
int main()
{
HashTable H;
ElementType Key;
int P,N;
H = InitTable();
scanf("%d",&N);
while(N--){
scanf("%d", &Key);
InsertHash(H,Key);
}
DispHash(H);
scanf("%d",&N);
while(N--){
scanf("%d", &Key);
DeleteHash(H,Key);
}
DispHash(H);
scanf("%d",&N);
while(N--){
scanf("%d", &Key);
P = Find(H, Key);
if (P==ERROR)
printf("ERROR: %d is not found.\n", Key);
else printf("%d is at position %d.\n", Key, P);
}
DestroyHash(H);
return 0;
}
void DispHash( HashTable H){
int i;
printf("Hash Addr:");
for(i=0;i<H->tableSize;i++)
printf("%d,",i);
printf("\n");
printf("Hash Key:");
for(i=0;i<H->tableSize;i++)
if (H->HCs[i].state==Legitimate)
printf("%d,",H->HCs[i].data);
else
printf("*,");
printf("\n");
printf("Hash Count:");
for(i=0;i<H->tableSize;i++)
if (H->HCs[i].state==Legitimate)
printf("%d,",H->HCs[i].count);
else
printf("*,");
printf("\n");
}
void DestroyHash( HashTable H){
free(H->HCs);
free(H);
}
int Hash( ElementType Key, int TableSize ) //hash函数
{
return (Key % TableSize);
}
HashTable InitTable()
{
HashTable H;
int tableSize,N,pos,i;
ElementType data;
NodeStateType state;
scanf("%d",&tableSize);
H=(HashTable) malloc(sizeof(struct TableNode));
H->HCs=(HashCell *)malloc(tableSize*sizeof(HashCell));
H->tableSize=tableSize;
for(i=0;i<tableSize;i++)
{
H->HCs[i].state=Empty;
H->HCs[i].count=0;
} //初始化Hash表
return H;
}
//你的代码写在这里
void InsertHash(HashTable H, ElementType Key)
{
/*1.如果有重复则不做处理*/
for(int i=0;i<H->tableSize;i++)
if(H->HCs[i].state==Legitimate&&H->HCs[i].data==Key)//如果数据存在并且数据值等于Key
return ;//不处理
/*2.插入*/
for(int i=0;i<H->tableSize;i++)
{
int pos=(i+Hash(Key,H->tableSize))%H->tableSize;//pos一开始为Hash(Key,H->tableSize),每找一次pos++,超过H->tableSize后归零(所以对H->tableSize求余)
if(H->HCs[pos].state==Empty)//如果为空,就插入
{
H->HCs[pos].state=Legitimate;//状态:已存
H->HCs[pos].data=Key;//保存数据
H->HCs[pos].count=i+1;//线性探测次数=移动次数+1
break;
}
}
}
int DeleteHash(HashTable H, ElementType Key)
{
int flag=0;
for(int i=0;i<H->tableSize;i++)
if(H->HCs[i].data==Key)//如果找到
{
H->HCs[i].state=Deleted;//状态:删除
flag=1;//已找到
break;
}
return flag;
}
int Find( HashTable H, ElementType Key )
{
for(int i=0;i<H->tableSize;i++)
{
int pos=(i+Hash(Key,H->tableSize))%H->tableSize;//同上
if(H->HCs[pos].state==Legitimate&&H->HCs[pos].data==Key)//如果数据存在并且数据值等于Key
return pos;//返回下标
}
return ERROR;//否则返回-1
}
仲舟原创,未经允许禁止转载