数据结构(c语言版)队列基本操作的实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构(c语言版)队列基本操作的实现相关的知识,希望对你有一定的参考价值。

【实验内容】
1、 编程实现26个英文字母的顺序队和链队存储;
2、 要求先把“A~Z”26个英文字母入队,然后让所有字母出队;
3、 要求采用结构化编程,用init( )函数实现队列的初始化,用EnQueue( )函数实现入队,用OutQueue( )函数实现出队,build( )函数建立队列,display( )函数显示队列。
请把“自己填写”的部分补上去,感激不尽

参考技术A /***************/
/* 链式队列 */
/***************/
#include "stdlib.h"
#include "stdio.h"

/* 定义链式队列类型 */
typedef int ElemType;
typedef struct QNode
ElemType data;
struct QNode *next;
QNode, *QueuePtr;
typedef struct
QueuePtr front;
QueuePtr rear;
LinkQueue;

/* 1、初始化链式队列 */
void InitQueue(LinkQueue *Q)
Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));
if (!(Q->front)) exit(0);
Q->front->next=NULL;

/* 2、销毁链式队列 */
void DestroyQueue(LinkQueue *Q)
while (Q->front)
Q->rear=Q->front->next;
free(Q->front);
Q->front=Q->rear;


/* 3、清空链式队列 */
void ClearQueue(LinkQueue *Q)
QueuePtr p;
p=Q->front->next;
while (p)
Q->front->next=p->next;
free(p);
Q->rear=Q->front;


/* 4、判断空队列 */
int QueueEmpty(LinkQueue Q)
if (Q.front==Q.rear)
return 1;
else
return 0;

/* 5、求链式队列长度 */
int QueueLength(LinkQueue Q)
QueuePtr p; int n=0;
p=Q.front;
while (p!=Q.rear)
n++; p=p->next;
return n;


/* 6、取队头元素 */
ElemType GetHead(LinkQueue Q)
if (Q.front!=Q.rear)
return Q.front->next->data;


/* 7、入队列 */
void EnQueue(LinkQueue *Q, ElemType e)
QueuePtr p;
p=(QueuePtr)malloc(sizeof(QNode));
if (!p) exit(0);
p->data=e; p->next=NULL;
Q->rear->next=p;
Q->rear=p;

/* 8、出队列 */
void DeQueue(LinkQueue *Q, ElemType *e)
QueuePtr p;
if (Q->front!=Q->rear)
p=Q->front->next;
*e=p->data;
Q->front->next=p->next;
if (Q->rear==p) Q->rear=Q->front;
free(p);


/* 9、遍历链式队列并输出元素 */
void QueueTraverse(LinkQueue Q)
QueuePtr p;
printf("\nQueue: ");
p=Q.front->next;
while (p)
printf("%d\t",p->data);
p=p->next;


/* 约瑟夫问题 */
void Joseffer(int n)
LinkQueue Q; int i; ElemType x;
InitQueue(&Q);
for(i=1; i<=n; i++)
EnQueue(&Q,i);
while (!QueueEmpty(Q))
for(i=1; i<=3; i++)
DeQueue(&Q,&x);
if (i!=3)
EnQueue(&Q,x);
else
printf("%5d",x);




/* 主函数 */
main()
LinkQueue Q; int i; ElemType x;
InitQueue(&Q);
for(i=2; i<=5; i++)
EnQueue(&Q,i);
printf("len:%d\n",QueueLength(Q));
while (!QueueEmpty(Q))
DeQueue(&Q,&x);
printf("%d\t",x);
//QueueTraverse(Q);
//Joseffer(6);


自己去调试吧,这个是C语言版的链式队列,如果看不懂或者调不出来就去看书吧。否则你这门是白学了。
注:这里是链式队列

/***************/
/* 循环队列 */
/***************/
#include "stdlib.h"
#include "stdio.h"
#define N 100

/* 定义循环队列类型 */
typedef int ElemType;
typedef struct
ElemType *base;
int front;
int rear;
SqQueue;

/* 1、初始化循环队列 */
void InitQueue(SqQueue *Q)
Q->base=(ElemType*)malloc(N*sizeof(ElemType));
Q->front=Q->rear=0;

/* 2、销毁循环队列 */
void DestroyQueue(SqQueue *Q)
free(Q->base);

/* 3、清空循环队列 */
void ClearQueue(SqQueue *Q)
Q->front=Q->rear=0;

/* 4、判断空队列 */
int QueueEmpty(SqQueue Q)
if (Q.front==Q.rear)
return 1;
else
return 0;

/* 5、求循环队列长度 */
int QueueLength(SqQueue Q)
return (Q.rear+N-Q.front)%N;

/* 6、取队头元素 */
void GetHead(SqQueue Q, ElemType *e)
if (Q.front!=Q.rear)
*e=Q.base[Q.front];


/* 7、入队列 */
int EnQueue(SqQueue *Q, ElemType e)
if ((Q->rear+1)%N==Q->front)
return 0;
Q->base[Q->rear]=e;
Q->rear=(Q->rear+1)%N;
return 1;

/* 8、出队列 */
int DeQueue(SqQueue *Q, ElemType *e)
if (Q->front==Q->rear)
return 0;
*e=Q->base[Q->front];
Q->front=(Q->front+1)%N;
return 1;

/* 9、遍历循环队列并输出元素 */
void QueueTraverse(SqQueue Q)
int i;
printf("\nQueue: ");
if (Q.rear<Q.front) Q.rear=Q.rear+N;
for(i=Q.front; i<Q.rear; i++)
printf("%d\t",Q.base[i%N]);

/* 主函数 */
main()
SqQueue Q; int i; ElemType x;
InitQueue(&Q);
for(i=2; i<=5; i++)
EnQueue(&Q,i);
printf("len:%d\n",QueueLength(Q));
while (!QueueEmpty(Q))
DeQueue(&Q,&x);
printf("%d\t",x);
QueueTraverse(Q);


在给你个循环队列吧
参考技术B 0.0本回答被提问者采纳

数据结构(C语言版)严蔚敏->队列的顺序存储(循环队列)和链式存储

1. 队列的顺序存储

1.1 队列的顺序存储结构:
#define MaxSize 50 // 定义队列中的元素的最大个数
typedef struct
	ElemType data[MaxSize];
	int front,rear; // 对头指针和队尾指针
SqQueue;
1.2 队列的初始状态、进队操作及出队操作
  • 初始状态:Q.front = Q.rear = 0;
  • 进队操作:队列不满时,先送值到队尾元素,再将队尾指针加1;
  • 出队操作:队列不空时,先取对头元素值,再将对头指针加1;

【注】:队列为空时,有Q.front==Q.rear=0成立;不能用Q.rear = MaxSize 来队列已满。

1.3 循环队列

把存储队列元素的表从逻辑上视为一个环,称为循环队列。

  • 初始状态:Q.front = Q.rear = 0
  • 入队操作后队尾指针进1:Q.rear =(Q.rear+1)%MaxSize;
  • 出队操作后对头指针进1:Q.front = (Q.front+1)%MaxSize;
  • 队列长度:(Q.rear-Q.front+MaxSize)%MaxSize;

【注】:队列为空的条件是Q.front = Q.rear;若入队元素的速度快于出队元素的速度,则队尾指针很快就追上了对头指针,此时对满时也有Q.front = Q.rear,为了区分对空还是对满,有如下3中处理方式。

  • 牺牲一个单元来区分对空还是对满,入队时少用一个队列单元。
    • 对满的条件为:(Q.rear+1)%MaxSize == Q.front;
    • 对空的条件为:Q.front == Q.rear
    • 队列中元素个数:(Q.rear-Q.front+MaxSize)%MaxSize
  • 类型中增设表示元素个数的数据成员。这样对空条件为Q.size == 0,对满条件为Q.size==MaxSize。
    • 此时队列的结构如下:
#define MaxSize 50 // 定义队列中的元素的最大个数
typedef struct
	ElemType data[MaxSize];
	int front,rear; // 对头指针和队尾指针
	int size;
SqQueue;
  • 类型中增设tag数据成员,以区分对满还是对空。tag等于0时,若因删除导致Q.front==Q.rear,则为对空;tag等于1时,若因插入导致Q.front = Q.rear,则为对满。
    • 此时队列的结构如下:
#define MaxSize 50 // 定义队列中的元素的最大个数
typedef struct
	ElemType data[MaxSize];
	int front,rear; // 对头指针和队尾指针
	int tag;
SqQueue;

其实就是初始化时Q.tag=0,当执行入队操作时,Q.tag赋值为1,当执行出队操作时,Q.tag赋值为0.

2. 队列的链式存储

linkqueue.h

#ifndef LINKQUEUE_H_INCLUDED
#define LINKQUEUE_H_INCLUDED

typedef int ElemType;

typedef struct LinkNode
    ElemType data;
    struct LinkNode *next;
LinkNode;

typedef struct
    LinkNode *front2,*rear;
LinkQueue;


void InitQueue(LinkQueue &Q);
// 初始化队列
bool QueueEmpty(LinkQueue Q);
// 判断队列是否为空
bool EnQueue(LinkQueue &Q,ElemType e);
// 入队操作
bool DeQueue(LinkQueue &Q,ElemType &e);
// 出队操作
bool GetHead(LinkQueue Q,ElemType &e);
//获取队头元素
int QueueLength(LinkQueue Q);
//获取队列长度
#endif // LINKQUEUE_H_INCLUDED

linkqueue.cpp

#include <stdlib.h>
#include "linkqueue.h"

// 带头节点
void InitQueue(LinkQueue &Q)
    Q.rear = (LinkNode *)malloc(sizeof(LinkNode));
    if(!Q.rear)
        exit(-1);
    // 分配资源失败
    Q.front2=Q.rear;
    Q.front2->next = NULL;

// 初始化队列
bool QueueEmpty(LinkQueue Q)
    return Q.front2 == Q.rear;

// 判断队列是否为空
bool EnQueue(LinkQueue &Q,ElemType e)
    LinkNode *p = (LinkNode *)malloc(sizeof(LinkNode));
    if(!p)
        exit(-1);
    // 资源分配失败
    p->data = e;
    p->next = NULL;
    // 创建新节点,插入到链尾
    Q.rear->next = p;
    Q.rear = p;
    return false;

// 入队操作
bool DeQueue(LinkQueue &Q,ElemType &e)
    if(QueueEmpty(Q))
        return false;
    // 如果队列已经为空
    LinkNode *p = Q.front2->next;
    // p节点才是出队的节点
    e = p->data;
    Q.front2->next = p->next;
    if(Q.rear == p)
        Q.rear = Q.front2;
    // 原队列中只有一个节点,删除后变空
    free(p);
    return true;

// 出队操作
bool GetHead(LinkQueue Q,ElemType &e)
    if(QueueEmpty(Q))
        return false;
    e = Q.front2->next->data;
    return true;

//获取队头元素
int QueueLength(LinkQueue Q)
    LinkNode *p = Q.front2->next;
    int i = 0;
    while(p)
        ++i;
        p = p->next;
    
    return i;

//获取队列长度


main.cpp

#include <stdio.h>
#include "linkqueue.h"

int main()

    LinkQueue Q;
    InitQueue(Q);
    int a[] =1,2,3,4,5,6,7,8,9,10;
    int e;
    for(int i=0;i<10;i++)
        EnQueue(Q,a[i]);
    GetHead(Q,e);
    printf("The head node element of the queue is %d\\n",e);
    int q_len = QueueLength(Q);
    printf("The length of the queue is %d\\n",q_len);
    while(!QueueEmpty(Q))
        DeQueue(Q,e);
        printf("%d\\t",e);
    
    printf("\\n");
    return 0;


运行结果:

以上是关于数据结构(c语言版)队列基本操作的实现的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法栈与队列C语言版

数据结构实用教程(C语言版)大纲

数据结构(C语言版)严蔚敏->队列的顺序存储(循环队列)和链式存储

C语言版数据结构算法

数据结构与算法全套数据结构笔记持续更新

数据结构(C语言版) 栈和队列 算法设计Demo11