队列和哈希表的算法实现

1 队列

1.1 功能函数
#define _CRT_SECURE_NO_WARNINGS 1
#include "queue.h"
Linklist que1 = NULL;

/*
* Purpose:申请空间
* 
* Entry:  无
* 
* return:返回申请空间的首地址
*/
queue new_que()
{
    //申请空间
    queue q = malloc(sizeof(Queue));
    //置空队列
    q->front = q->tail = 0;
    return q;
}

/*
* Purpose:队列菜单选择打印
*
* Entry:  无
*
* return: 无
*/
void queue_menu()
{
    printf("\n***************************\n");
    printf("******** 1 顺序队列 *******\n");
    printf("******** 2 循环队列 *******\n");
    printf("******** 3 链式队列 *******\n");
    printf("******** 4 折半查找 *******\n");
    printf("******** 0 退出程序 *******\n");
    printf("***************************\n");
}

/*
* Purpose:顺序队列菜单选择打印
*
* Entry:  无
*
* return: 无
*/
void order_menu(queue q)
{
    int num = 1;
    while (num)
    {
        printf("\n*******************************\n");
        printf("******** 1 顺序队列入队 *******\n");
        printf("******** 2 顺序队列删除 *******\n");
        printf("******** 3 顺序队列遍历 *******\n");
        printf("******** 0 上级菜单     *******\n");
        printf("*******************************\n");

        printf("请选择:");
        scanf("%d", &num);
        switch (num)
        {
        case 1:
        {
            Eletype ele = 0;
            printf("请输入数据元素:");
            scanf("%d", &ele);
            in_queue(q, ele);
        }break;
        case 2:
        {
            dele_queue(q);
        }break;
        case 3:
        {
            output_queue(q);
        }break;
        case 0:break;
        default:printf("输入有误,请重新选择");
        }
    }
}

/*
* Purpose:循环队列菜单选择打印
*
* Entry:  无
*
* return: 无
*/
void loop_menu(queue q)
{
    int num = 1;
    while (num)
    {
        printf("\n*******************************\n");
        printf("******** 1 循环队列入队 *******\n");
        printf("******** 2 循环队列删除 *******\n");
        printf("******** 3 循环队列遍历 *******\n");
        printf("******** 4 循环队列个数 *******\n");
        printf("******** 0 上级菜单     *******\n");
        printf("*******************************\n");

        printf("请选择:");
        scanf("%d", &num);
        switch (num)
        {
        case 1:
        {
            Eletype ele = 0;
            printf("请输入数据元素:");
            scanf("%d", &ele);
            in_loop_queue(q, ele);
        }break;
        case 2:
        {
            dele_loop_queue(q);
        }break;
        case 3:
        {
            output_loop_queue(q);
        }break;
        case 4:
        {
            printf("个数:%d", (MAXSIZE - q->front + q->tail) % MAXSIZE);
            break;
        }
        case 0:break;
        default:printf("输入有误,请重新选择");
        }
    }
}



/*
 * Purpose:入队
 *
 * Entry:  q:队列地址
 *         ele:用户输入的数据元素
 *
 * return: 成功0;失败-1
 */
int in_queue(queue q, Eletype ele)
{
    if (q == NULL || (q->tail == MAXSIZE))
    {
        printf("队列不存在或者队列已满\n");
        return -1;
    }
    q->data[q->tail++] = ele;
    return 0;
}

/*
* Purpose:出队
*
* Entry:  q:队列地址
*
* return: 成功0;失败-1
*/
int dele_queue(queue q)
{
    if (q == NULL || (q->front == q->tail))
    {
        printf("队列不存在或者队列为空\n");
        return -1;
    }
    //先将删除的位置赋值默认值
    q->data[q->front] = 0;
    ++q->front;
    return 0;
}

/*
* Purpose:遍历
*
* Entry:  q:队列地址
*
* return: 成功0;失败-1
*/
int output_queue(queue q)
{
    if (q == NULL || (q->front == q->tail))
    {
        printf("队列不存在或者队列为空\n");
        return -1;
    }
    for (int i = q->front; i < q->tail; i++)
    {
        printf("%d\t", q->data[i]);
    }
    return 0;
}

/*
* Purpose:入队
*
* Entry:  q:队列地址
*         ele:用户输入的数据元素
*
* return: 成功0;失败-1
*/
int in_loop_queue(queue q, Eletype ele)
{
    if ((q->front == (q->tail + 1) % MAXSIZE) || q == NULL)
    {
        printf("队列不存在或者队列已满\n");
        return -1;
    }
    q->data[q->tail] = ele;
    q->tail = (q->tail + 1) % MAXSIZE;
    return 0;
}

/*
* Purpose:出队
*
* Entry:  q:队列地址
*
* return: 成功0;失败-1
*/
int dele_loop_queue(queue q)
{
    if (q == NULL || (q->front == q->tail))
    {
        printf("队列不存在或者队列为空\n");
        return -1;
    }
    //先将删除的位置赋值默认值
    printf("%d", q->data[q->front]);
    q->data[q->front] = 0;
    q->front = (q->front + 1) % MAXSIZE;
    return 0;
}

/*
* Purpose:遍历
*
* Entry:  q:队列地址
*
* return: 成功0;失败-1
*/
int output_loop_queue(queue q)
{
    if (q == NULL || (q->front == q->tail))
    {
        printf("队列不存在或者队列为空\n");
        return -1;
    }
    for (int i = q->front; q->tail != i;)
    {
        printf("%d\t", q->data[i]);
        i = (i + 1) % MAXSIZE;
    }
    return 0;
}

/*
* Purpose:链式队列菜单选择打印
*
* Entry:  无
*
* return: 无
*/
void link_menu(Linklist L)
{
    Linklist q = L;
    int num = 1;
    while (num)
    {
        printf("\n*******************************\n");
        printf("******** 1 链式队列入队 *******\n");
        printf("******** 2 链式队列删除 *******\n");
        printf("******** 3 链式队列遍历 *******\n");
        //printf("******** 4 链式队列个数 *******\n");
        printf("******** 0 上级菜单     *******\n");
        printf("*******************************\n");

        printf("请选择:");
        scanf("%d", &num);
        switch (num)
        {
        case 1:
        {
            Eletype ele = 0;
            printf("请输入数据元素:");
            scanf("%d", &ele);
            in_link_queue(q, ele);
        }break;
        case 2:
        {
            dele_link_queue(q);
        }break;
        case 3:
        {
            output_link_queue(q);
        }break;
        /*case 4:
        {
            printf("个数:%d", (MAXSIZE - q->front + q->tail) % MAXSIZE);
            break;
        }*/
        case 0:break;
        default:printf("输入有误,请重新选择");
        }
    }
}

/*
* Purpose:初始化头结点
*
* Entry:  无
*
* return: 成功0;失败-1
*/
Linklist Init_link()
{
    Linklist L = malloc(sizeof(LNode));
    L->len = 0;
    L->next = NULL;
    que1 = L;
    return L;
}

/*
* Purpose:新建结点
*
* Entry:  无
*
* return: 成功0;失败-1
*/
Linklist new_node()
{
    Linklist p = malloc(sizeof(LNode));
    p->data = 0;
    p->next = NULL;
    
    return p;
}

/*
* Purpose:链式入队
*
* Entry:  L:头结点地址
*         ele:用户输入的数据元素
*
* return: 成功0;失败-1
*/
int in_link_queue(Linklist L, Eletype ele)
{
    if (L == NULL)
    {
        return -1;
    }
    Linklist p = new_node();
    p->data = ele;
    que1->next = p;
    que1 = p;
    ++L->len;
    return 0;
}

/*
* Purpose:遍历
*
* Entry:  q:队列地址
*
* return: 成功0;失败-1
*/
int output_link_queue(Linklist L)
{
    if (L == NULL || L->next == NULL)
    {
        return -1;
    }
    Linklist s = L->next;
    while (s)
    {
        printf("%d\t", s->data);
        s = s->next;
    }
    return 0;
}

/*
* Purpose:出队
*
* Entry:  L:头结点地址
*
* return: 成功0;失败-1
*/
int dele_link_queue(Linklist L)
{
    if (L == NULL || L->next == NULL)
    {
        printf("不存在或为空");
        return -1;
    }
    Linklist s = L->next;
    L->next = s->next;
    if (s->next == NULL)
        que1 = L;
    free(s);
    s = NULL;
    --L->len;
    return 0;
}




/*============折半查找=============*/

int binary_seek(int arr[], int low, int high, int key)
{
    int mid = (low + high) / 2;
    if (low > high)
    {
        return -1;
    }
    if (key < arr[mid])
    {
        high = mid - 1;
        binary_seek(arr, low, high, key);
    }
    else if (key > arr[mid])
    {
        low = mid + 1;
        binary_seek(arr, low, high, key);
    }
    else
    {
        return  mid;
    }
}
1.2 头文件
#pragma once
#ifndef __QUEUE_H__
#define __QUEUE_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 3

typedef int Eletype;

typedef struct Queue
{
    //数据域
    Eletype data[MAXSIZE];
    //队头
    int front;
    //队尾
    int tail;
}Queue, *queue;

typedef struct LNode
{
    union Ele
    {
        int len;
        Eletype data;
    };
    struct LNode* next;
}LNode, *Linklist;


typedef struct que
{
    struct que* next;
}que;



queue new_que();
void queue_menu();
void order_menu(queue q);
void loop_menu(queue q);
int in_queue(queue q, Eletype ele);
int dele_queue(queue q);
int output_queue(queue q);
int in_loop_queue(queue q, Eletype ele);
int dele_loop_queue(queue q);
int output_loop_queue(queue q);
void link_menu(Linklist L);
Linklist Init_link();
Linklist new_node();
int in_link_queue(Linklist L, Eletype ele);
int output_link_queue(Linklist L);

int binary_seek(int arr[], int low, int high, int key);

#endif
1.3 主函数
#define _CRT_SECURE_NO_WARNINGS 1
#include "queue.h"


int main(void)
{
    queue q = new_que();
    Linklist L = Init_link();

    int num = 1;
    while (num)
    {
        queue_menu();
        printf("请选择:");
        scanf("%d", &num);
        switch (num)
        {
        case 1: 
        {
            order_menu(q);
        }break;
        case 2:
        {
            q->front = q->tail = 0;//防止上一个步骤干扰此项
            loop_menu(q);
        }break;
        case 3:
        {
            link_menu(L);
        }break;
        case 4:
        {
            int arr[] = { 12, 23, 34, 45, 56, 67 };
            int len = sizeof(arr) / sizeof(arr[0]);
            int key = 0;
            printf("请输入要查找的数:");
            scanf("%d", &key);
            int ret = binary_seek(arr, 0, len - 1, key);
            printf("\n%d", ret);
        }
        case 0:break;
        default:printf("输入有误,请重新选择");
        }
    }
    return 0;
}

2 哈希表

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int p = 0;

//结点结构体
typedef struct Node
{
    //数据域
    int data;
    //指针域
    struct Node* next;
}Node, *node;

/*
* Purpose:初始化指针数组
*
* Entry:  hash表, 长度
*
* return: 无
*/
void Init_hash(node hash[], int len)
{
    for (int i = 0; i < len; i++)
    {
        hash[i] = NULL;
    }
}

/*
* Purpose:找最大质数
*
* Entry:  哈希表长
*
* return: 成功返回质数
*/
int prime_seek(int m)
{
    
    for (int i = m; i >= 2; i--)
    {
        int cnt = 0;
        for (int j = 1; j <= i; j++)
        {
            if (i % j == 0)
            {
                ++cnt;
            }
        }
        if (cnt == 2)
        {
            return i;
        }
    }
    return -1;
}

/*
* Purpose:将数组元素映射到哈希表中
*
* Entry:  hash表,数组元素,哈希表长度
*
* return: 无
*/
void insert_hash(node hash[], int ele, int len)
{
    //找到该元素所对应的哈希下标

    p = prime_seek(len);
    int sub = ele % p;
    //新建节点,头插
    node n = malloc(sizeof(Node));
    n->data = ele;
    n->next = hash[sub];
    hash[sub] = n;
}

/*
* Purpose:打印输出
*
* Entry:  哈希表、哈希表长
*
* return: 无
*/
void output_hash(node hash[], int len)
{
    for (int i = 0; i < len; i++)
    {
        node p = hash[i];
        printf("%d:", i);
        while (p)
        {
            printf("%d\t", p->data);
            p = p->next;
        }
        printf("\n");
    }
}

/*
* Purpose:查找元素
*
* Entry:  哈希表、元素
*
* return: 成功则返回该元素值,否则返回-1
*/
int ele_seek(node hash[], int ele)
{
    //找出该元素多对应的哈希表下标
    int sub = ele % p;
    node t = hash[sub];
    //根据下标中的链表地址找该元素
    while (t)
    {
        if (t->data == ele)
        {
            return t->data;
        }
        t = t->next;
    }
    return -1;
}


int main(void)
{
    int arr[] = { 23, 22, 34, 23, 26, 56, 55, 34 };
    int len = sizeof(arr) / sizeof(arr[0]);
    //哈希表长度计算
    int hash_len = len * 4 / 3;
    //创建哈希表
    node hash[hash_len];
    //初始化赋值
    Init_hash(hash, hash_len);

    for (int i = 0; i < len; i++)
    {
        //
        insert_hash(hash, arr[i], hash_len);
    }
    //打印输出哈希表
    output_hash(hash, hash_len);
    //查找数据元素
    int ele = 0;
    printf("请输入要查找的元素:");
    scanf("%d", &ele);
    printf("\n%d\n", ele_seek(hash, ele));

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值