数据结构(C语言)-队列

学习视频链接


队列也是一种运算受限的线性表。

一、队列的定义与基本运算

1、队列的定义

(1)队列的定义
假设有一个队列Q=(a1…an),队列中元素按(a1…an)的次序入队后,入队的第一个元素a1为队头元素,最后一个元素an为队尾元素,队列的操作是按先进先出的原则进行的,这种先进先出的规则应用在数据结构中称为队列,队列又称为先进先出的线性表。
(2)队列的特性

  • 队列的主要特性就是“先进先出”。
  • 队列也是一种特殊的线性表。插入操作限定在线性表的一端进行,删除操作限定在线性表的另一端进行。
    (3)几个术语
  • 入队和出队。队列插入操作又称为入队,删除操作又称为出队
  • 队头和队尾。允许进行插入的一端为队尾,允许进行删除的一端称为队头
  • 队头元素和队尾元素。处于队头位置的数据元素称为队头元素,处于队尾的位置的数据元素称为队尾元素。
  • 空队,不含任何数据元素的队列称为空队

2、队列的基本操作

(1)初始化队列
初始化条件:队列不存在。
操作结果:构造一个空队列
(2)判断队列是否为空
初始化条件:队列存在。
操作结果:队列为空返回0,不为空返回1。
(3)入队
初始化条件:队列存在。
操作结果:将数据元素插入到队尾
(4)出队
初始化条件:队列存在且不为空。
操作结果:将队头数据赋值给“X”,然后删除
(5)取队头元素
初始化条件:队列存在。
操作结果:将队头数据赋值给“X”,然后输出
(6)显示队列元素
初始化条件:队列存在且不为空。
操作结果:将队列元素按先进先出原则输出

二、队列的存储实现及运算实现

1、顺序队列

(1)顺序队列的定义
队列的顺序存储结构称为顺序队列。类似于顺序表的定义,顺序队列用了一个一位数组和两个分别指向队头和队尾元素的变量。
(2)顺序队列的定义

typedef int Datatype;
typedef struct Circularqueue{
	Datatype Data[100];//队列的大小 
	int  front;//记录头元素位置的变量 
	int rear; //记录尾元素位置的变量 
}Circularqueue;
  • 顺序队列有一个致命的缺点,就是当rear=100-1时,再加入新的元素,数组越界导致程序发生BUG错误。如果队列为空或有剩余存储单元的“假溢出”,就无法解决了。为了解决以上问题必须使用循环顺序队

2、循环队列

(1)循环队列就是将顺序队列的首尾相连接。形成一个“环形”,事实上循环队列依然是顺序队列,只是逻辑上不同。循环队列最大空间为100,数组下标为0~99之间,队头与队尾指针指向同一个位置为空队,非空时队中队头指针front指向队列中队头元素的前一个位置,队尾rear指向队列的队尾元素位置。
假设队列开辟的数组单元数为100,它们的数组下标在0~99之间,若使队头或队尾增加1,可以利用取摸运算及取余。
入队时尾指针增加1:

rear=(rear+1)%100;

出队时队头指针加1:

front=(front+1)%100;

-循环队列解决了假溢出的问题,但是有出现了一个新问题,队满不在是rear=100-1而是front==rear和队空条件相同。解决这一问题有三种解决方案,但是我觉得最方便的还是损失一个单元不用,当循环队列中元素的个数为100-1时就认为队满。及判断队满的条件为:

(rear+1)%100==front;

(2)循环队列的基本操作实现

  • 初始化:
void InitCircularqueue(Circularqueue *queue){//初始化队列 
	queue->front=queue->rear=0; //头元素与尾元素等于0 
	if(queue->front==queue->rear){
		printf("Circular queue created successfully。");
	}else{
		printf("Circular queue creation failed!");
		exit(1);
	}
}
  • 判断是否为空:
int Judge(Circularqueue *queue){//判断队空 
	if(queue->front==queue->rear){
		return 1;
	}else{
		return 0;
	}
} 
  • 判断队满
int Theteamisfull(Circularqueue *queue){//判断队满 
	if((queue->rear+1)%100==queue->front){//利用取余运算判断是否相等 
		return 0;
	}else{
		return 1;
	}
}
  • 输出队中元素
void Displayelements(Circularqueue *queue){//输出队中元素 
    int i=queue->front;
	if(Judge(queue)==1){
		printf("Circular queue is empty, no element\n");
	}else{
		printf("\nThe elements in the circular queue are:");
		while(i!=queue->rear){
			printf("%5d",queue->Data[i+1]);
			i++;
		} 
	}
}
  • 入队操作
void Jointheteam(Circularqueue *queue){//入队操作 
	char p[50];
	int k,i;
	k=i=0;
    static char Start[]="Start";
    static char End[]="End";
    if(Theteamisfull(queue)==0){
    	printf("Circular queue is full, cannot operate!");
    	k++;
	}else{
		printf("Enter “Start” to start, enter “End”to end the team:");
		gets(p);
		while(strcmp(p,Start)!=0){
			if(strcmp(p,End)==0){
				printf("You didn't join the team!");
				i++;
				break;
			}
			printf("\nInput error, please re-enter:");
			memset(p,0,sizeof p);
	        gets(p);
		} 
		if(strcmp(p,Start)==0){
			printf("\nPlease enter the entry element:");
			memset(p,0,sizeof p);
	        gets(p);
		}
		while(strcmp(p,End)!=0){
	        queue->rear=(queue->rear+1)%100;
	        queue->Data[queue->rear]=atoi(p);
	        printf("\nPlease enter the entry element:");
	        memset(p,0,sizeof p);
	        gets(p);
	        i++;
	        continue;  
		}
	}
	if(k+i==i&&i==1){
		printf("Failed to join the team!");
		if(k==1){
			printf("The team is full!");
		}
	}else{
		Displayelements(queue);
	}
} 
  • 出队操作
void Getoutoftheteam(Circularqueue *queue){//出队操作 
	char p[50];
	int k,i,x,l;
	k=i=0;
    static char Start[]="Start";
    static char End[]="End";
	if(Judge(queue)==1){
		printf("Circular queue is empty, no element\n");
		k++;
	}else{
        printf("Enter “Start” to start the team, enter “End” to end:"); 
        gets(p);
       while(strcmp(p,Start)!=0){
			if(strcmp(p,End)==0){
				printf("You are not out of the team!");
				exit(1);
			}
			printf("\nInput error, please re-enter:");
			memset(p,0,sizeof p);
	        gets(p);
		} 
		if(strcmp(p,Start)==0){
			printf("\nPlease input the element of out of team:");
			memset(p,0,sizeof p);
	        gets(p);
		}
		l=queue->front;
		while(strcmp(p,End)!=0){
			    x=(l+1)%100;
				if(queue->Data[x]==atoi(p)){
					queue->front=(queue->front+1)%100;
				    x=queue->Data[queue->front];
		            printf("\nPlease input the element of out of team:");
			        memset(p,0,sizeof p);
	                gets(p);
				    l++;
	                i++;
				 }else{
                   printf("It doesn't meet the rules! Please re-enter:");
				   memset(p,0,sizeof p);
	               gets(p);
				 }

	             continue;  
		}
	}
	if(k+i==i&&i==0){
	   printf("Failed to get out of the team!");
	}else{
	   Displayelements(queue);
	}
}
  • 显示队头元素
void Lineheadelement(Circularqueue *queue){//显示队头元素 
	int x;
      if(Judge(queue)==1){
	    printf("The team is empty! Unable to take the top operation!");
	  }else{
	    printf("The line head elements are:");
		x=queue->Data[(queue->front+1)%100];
		printf("%5d",x);
	  }
} 

3、链队

(1)用链式存储结构实现的队列称为链队,一个链队列需要一哥队头指针和一个队尾指针才能唯一确定,队列中元素的结构和前面单链表的结点的结构一样。
(2)链队的类型定义

typedef int Data;
typedef struct Chainteam{
	Data data;//数据域 
	struct Chainteam *next;//指针域 
}Chainteam;
typedef struct{
	Chainteam *front ,*rear;//头,尾指针 
}LinkQueue;

(3)链队的基本操作与实现

  • 初始化队列操作
LinkQueue *Initializethechain(){
	LinkQueue *Team;
	Chainteam *P;
	Team=(LinkQueue *)malloc(sizeof(LinkQueue));
	P=(Chainteam *)malloc(sizeof(Chainteam));
	Team->front=P;
	Team->rear=P;
	if(Team->front==Team->rear){
		printf("Initialize the chain team successfully.");
	}else{
		printf("Initialization chain failed! Please check and try again.");
	}
	return Team;
}
  • 判断是否为空
int JudgmentChain(LinkQueue *Team){
	if(Team->front==Team->rear){
		return 0;
	}else{
		return 1;
	}
}
  • 入队
void Jointhechainteam(LinkQueue *Team){
	int j;
	j=0;
	Chainteam *p;
	char q[50];
	static char Start[]="Start";
	static char End[]="End";
	printf("Enter “Start” out of the chain, enter “End”to end:");
	gets(q);
	while(strcmp(q,Start)!=0){
		if(strcmp(q,End)==0){
			printf("\nYou didn't get out of the team!");
			break;
		}
		printf("\nInput error, please enter “Start”to start joining the queue:");
		memset(q,0,sizeof q);
	    gets(q);
	}
	if(strcmp(q,Start)==0){
		printf("\nEnter the queue element:");
		memset(q,0,sizeof q);
	    gets(q);
	}
	while(strcmp(q,End)!=0){
		p=(Chainteam *)malloc(sizeof(Chainteam));
		p->data=atoi(q);
		p->next=NULL;
		Team->rear->next=p;
		Team->rear=p;
	    printf("\nEnter the queue element:");
	    memset(q,0,sizeof q);
	    gets(q);
	    j++;
	}
	if(j!=0){
		Output(Team);
	}
	else{
		printf("Failed to join the team!");
	}
}
  • 出队
void Outofthechainteam(LinkQueue *Team){
   int j,x;
	j=0;
	Chainteam *p;
	char q[50];
	static char Start[]="Start";
	static char End[]="End";
	printf("Enter “Start” out of the chain, enter “End”to end:");
	gets(q);
	while(strcmp(q,Start)!=0){
		if(strcmp(q,End)==0){
		     printf("You didn't go out of the team.");
		     break;
		}
		printf("Input error, enter “Start”to start queuing:");
		memset(q,0,sizeof q);
	    gets(q);
	}
	if(strcmp(q,Start)==0){
		printf("Open input and outbound elements:");
		memset(q,0,sizeof q);
	    gets(q);
	}
	while(strcmp(q,End)!=0){
		if(Team->front->next->data==atoi(q)){
			p=Team->front->next;
		    x=p->data;
		    Team->front->next=p->next;
		    if(p->next=NULL){
		    	Team->rear=Team->front;
			}
			free(p);
		    printf("Open input and outbound elements:");
		    memset(q,0,sizeof q);
	        gets(q);
		    j++;
			continue;  
		}
		printf("Do not meet the queuing rules, please re-enter:");
		memset(q,0,sizeof q);
	    gets(q);
		
	}
	if(j!=0){
		Output(Team);
	}else
	{
		printf("Failed to get out of the team!");
	}
}
  • 输出队中元素
void Output(LinkQueue *Team){
	Chainteam *q=Team->front->next;
	if(JudgmentChain(Team)==0){
		printf("Air team! ");
	}else{
		printf("\nElements in the team:");
		while(q!=NULL){
			printf("%5d",q->data);
			q=q->next;
		}
	}
}
  • 取队头元素
void Teamleader(LinkQueue *Team){
	int x;
    if(JudgmentChain(Team)==0){
         printf("The team is empty! No team leader!");
	}else{
		x=Team->front->next->data;
		printf("The line head elements are:%5d",x);
	}
}
  • 销毁队列
void Destruction(LinkQueue *Team){
    while(Team->front){
    	Team->rear=Team->front->next;
    	free(Team->front);
    	Team->front=Team->rear;
	}
	if(Team->front==NULL){
	printf("Queue destroyed successfully.");
	}else
	{
		printf("Queue destroy failed!");
	}	
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页