仲舟のMOOC第十一周编程作业

这次作业比图的作业好做多了!这边建议直接手撕,自己写不出来的可以为挂科做个心理准备。
第一题二分,算法基础题不多哔哔

///*题目:二分检索算法的实现
///*作者:仲舟                                       
///*难度:★★
///*完成时间: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
}

仲舟原创,未经允许禁止转载

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值