数据结构丿丶队列


队列存储及相关操作

 队列和堆栈一样,也是一种具有操作约束的线性表,只允许在一端插入而在另一端删除

  • 顺序存储
     循环队列,为防止队列为空和队列已满不好区分,只需允许队列存放n-1个数,front指针指向第一个元素的前一个位置,尾指针指向最后一个元素
struct QNode 
{
    ElementType Data[MAXSIZE];     /* 存储元素的数组 */
    int front;  /* 队列的头指针 */
    int rear;   /* 队列的尾指针 */         
};
typedef struct QNode *Queue;

建队

Queue CreateQueue(  )
{
    Queue Q = (Queue)malloc(sizeof(struct QNode));
    Q->Front = Q->Rear = 0; //front和rear相等时为空
    return Q;
}

入队和判断队列是否已满

void Add( Queue Q, ElementType X )
{
    if ( IsFull(Q) )   printf("队列满");
    else 
    {
        Q->Rear = (Q->Rear+1)%MaxSize;
        Q->Data[Q->Rear] = X;
    }
}
bool IsFull( Queue Q )
{
    return ((Q->Rear+1)%MaxSize == Q->Front);
}

出队和判断队列是否为空

ElementType Delete( Queue Q )
{
    if ( IsEmpty(Q) )
     { 
        printf("队列为空");
        return ERROR;  /* ERROR是ElementType的特殊值,标志错误 */
     }
    else 
    {
        Q->Front =(Q->Front+1)%MaxSize; //注意是+而非-
        return  Q->Data[Q->Front];
    }
}
bool IsEmpty( Queue Q )
{
    return (Q->Front == Q->Rear);
}
  • 链式存储
     队列的链式存储结构也可以用一个单链表来表示,叫做链队,插入和删除操作分别在链表的两头进行;其中front只能是链表的头结点这一头,否则删除操作的时候,找不到前一个结点。与线性表和堆栈不同的是,要定义一个特殊的结构体存储头、尾指针,这个可以看作一个特殊的头结点
struct Node 
{
   ElementType Data;
   struct Node *Next;
};
struct QNode
{
    struct Node *Front;  /* 队列的头指针 */
    struct Node *rear;  /* 队列的尾指针 */
};
typedef struct QNode *Queue;

建队

Queue CreateQueue( ) 
{ /* 构建一个队列的头、尾指针结构体,返回该结构体指针 */
    Queue Q;
    Q = (Queue)malloc(sizeof(struct QNode));
    Q->Front=Q->rear=NULL;
    return Q;
}

入队

void Add( Queue PtrQ, ElementType X )
{ 
    Struct Node *Q;
    Q = (struct Node*)malloc(sizeof(struct Node));
    Q->Data = X;
    Q->Next = NULL;
    PtrQ->rear->Next = Q;
    PtrQ->rear=Q;
}

出队和判断队列是否为空

ElementType Delete( Queue PtrQ )
{
    Struct Node *Q; 
    ElementType X; 
    if  ( IsEmpty(PtrQ) )
     {
        printf("队列空");
        return ERROR;
     }
    else
     {
        Q = PtrQ->Front; //即Q指向第一个结点
        if ( PtrQ->Front == PtrQ->Rear )  /* 即队列只有一个元素 */
            PtrQ->Front = PtrQ->Rear = NULL;  /* 删除后队列置为空 */
        else                     
            PtrQ->Front = Q->Next;
        X = Q->Data;
        free( Q);  /* 释放被删除结点空间  */
        return  X;
    }
}
bool IsEmpty( Queue Q )
{
    return ( Q->Front == NULL);
}

队列应用


舞伴配对问题

 周末舞会上,男士们和女士们进入舞厅时,各自排成一队,跳舞开始时,先入队的男士和女士先出队配成舞伴。考虑设置两个队列分别存放男士和女士入队者,先将男士和女士的记录存放在一个数组里作为输入,然后依次扫描该数组的各元素,依据性别来决定进入男队还是女队,构造完成后将队头元素配队,直到某个队列为空,然后输入非空队列的队头元素。,此人即是下一轮首先获得舞伴的人

算法步骤
①初始化两个队列 Mdancers 和 Fdancers
②反复循环,依次将跳舞者根据性别插入两个队列中
③当 Mdancers 和 Fdancers队列均为非空时,反复循环,依次输出男女舞伴的名字
④如果 Mdancers队列为空,而 Fdancers不为空,则输出 Fdancers的队头女士的名字
⑤如果 Fdancers 队列为空,而 Mdancers不为空,则输出 Mdancers的队头男士的名字
typedef struct{
char name[20];          /*构造舞者*/
char sex;
}Person;

#define MAXSIZE 100
typedef struct{
Person person[MAXSIZE];
int front;                  /*构造队列*/
int rear;
}Queue;

Queue Mdancers,Fdancers    /*分别存放男士和女士队列*/

void DancePartner( Person dancers[], int num )
{/*结构数组dancers中存放跳舞的男女,num是跳舞的人数*/
	InitQueue(Mdancers);  InitQueue(Fdancers);
	
	for(int i=0;i<num;i++)
	{
		Person p=dancers[i];
		if(p.sex=='F')  EnQueue(Fdancers,p);       /*按性别入队*/
		else  EnQueue(Mdancers,p);
	}
	
	printf("The dancing partners are  :\n");
	
	while(!IsEmpty(Mdancers)&&!IsEmpty(Fdancers));
	{
		Person p = DeQueue(Mdancers);
		printf("%s ",p.name);
		Person p = DeQueue(Fdancers);      /*队头舞者配对*/
		printf("%s\n",p.name);
	}
	
	if(!IsEmpty(Mdancers))
	{
		Person p = GetHeadQueue(Mdancers);            /*取男士队头*/
		printf("The first man to get a partner is %s \n",p.name);
	}
	else if(!IsEmpty(Fdancers))
	{
		Person p = GetHeadQueue(Fdancers);       /*取女士队头*/
		printf("The first woman to get a partner is %s \n",p.name);
	}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值