队列的链式存储

简称链队列,它是限制仅在表头进行删除操作和表尾进行插入操作的单链表。

队列的链式存储类型描述:

 

//链式队列结点 
typedef struct LinkNode{
    dataType data;
    struct LinkNode *next;
}LinkNode;

 

//链式队列 
typedef struct{
    LinkNode *front;    //队列的队头 
    LinkNode *rear;     //队列的队尾 
}LinkQueue;

不带头结点 带头结点
头指针指向队头结点,尾指针指向队尾结点 头指针指向头结点,尾指针指向队尾结点,即单链表的最后一个结点(注意与顺存储的不同)

1.当Q.front == NULL 且 Q.rear == NULL时,链式队列为空。

2.出队时,首先判断队是否为空,若不空,则取出队头元素,将其从链表中删除,并让Q.front指向下一个结点(若该结点为最后一个结点,则置Q.front和Q.rear都为NULL)。

3.入队时,建立一个新结点,将该结点插入到链表的尾部,并改让Q.rear指向这个新插入的结点(若原队列为空队,则令Q.front也指向该结点)

 
该方法在操作上比较麻烦,因此常用带头结点的单链表  

 

实验书上都没有释放的代码,都是自己根据之前朱老师的理解自己仿照着写的。

 

释放时参考了当年朱老师的方法:https://mp.csdn.net/postedit/82722253

数据结构:队列之链队列

 

               

正确形式为从前往后释放,理解如上,终止条件理解如下:

数据结构:队列之链队列

 

while(head->next){
        p = head->next;                  
        head->next = p->next;
        free(p);
    }

正确 错误
typedef struct LinkNode{
    dataType data;
    struct LinkNode *next;
}LinkNode;
//assignment from incompatible pointer type 不兼容的指针间赋值  
//后面的程序一直有这样的问题  就是说  LinkNode *p;  p的类型和它的next的类型不一样 
typedef struct{    
    dataType data;
    struct LinkNode *next;
}LinkNode;
*/

 

正确 错误

//出队列 
boolean deQueue(LinkQueue *q, dataType *x){
    LinkNode *p;
    
    if(isQueueEmpty(q)){
        return FALSE;
    }
    
    p = q->front->next;
    q->front->next = p->next;
    *x = p->data; 


    //若原队列中仅有一个有效结点,删除后变空   自己没有考虑到这种情况 

//如果不置队尾指针,则无法判空
    if(q->rear == p){  
        q->rear = q->front;
    }

    free(p);
    
    return TRUE;
}

//出队列 
boolean deQueue(LinkQueue *q, dataType *x){
    LinkNode *p;
    
    if(isQueueEmpty(q)){
        return FALSE;
    }
    
    p = q->front->next;
    q->front->next = p->next;
    *x = p->data; 
    
    
    free(p);
    
    return TRUE;
}
数据结构:队列之链队列 数据结构:队列之链队列

 


#include<stdio.h>
#include<malloc.h>

typedef unsigned char  boolean;
#define  TRUE    1
#define  FALSE   0


typedef  int dataType;

//链式队列结点 
typedef struct LinkNode{
	dataType data;
	struct LinkNode *next;
}LinkNode;

/*
//assignment from incompatible pointer type 不兼容的指针间赋值  
//后面的程序一直有这样的问题  就是说  LinkNode *p;  p的类型和它的next的类型不一样 
typedef struct{    
	dataType data;
	struct LinkNode *next;
}LinkNode;
*/

//链式队列 
typedef struct{
	LinkNode *front;    //队列的队头 
	LinkNode *rear;     //队列的队尾 
}LinkQueue;

boolean initQueue(LinkQueue **q);
void destroyQueue(LinkQueue **q);
boolean isQueueEmpty(LinkQueue *q);
void enQueue(LinkQueue *q, dataType x);
boolean deQueue(LinkQueue *q, dataType *x);
boolean getFrontData(LinkQueue *q, dataType *x);
boolean getRearData(LinkQueue *q, dataType *x);
int lengthOfQueue(LinkQueue *q);
void showData(LinkQueue *q);

void showData(LinkQueue *q){
	LinkNode *p = q->front->next;
	
	printf("队列中的元素为:");
	while(p){
		printf("%d ", p->data);
		p = p->next;
	}
	
	printf("\n");
}

//计算队列元素的个数 
int lengthOfQueue(LinkQueue *q){
	int count = 0;
	LinkNode *p = q->front->next;
	
	while(p){		
		count++;
		p = p->next;
	}
	return count;
}

//取队尾元素的值 
boolean getRearData(LinkQueue *q, dataType *x){
	if(isQueueEmpty(q)){
		return FALSE;
	} 
		
	*x = q->rear->data;
	return TRUE;		
}

//取队头元素的值 
boolean getFrontData(LinkQueue *q, dataType *x){
	if(isQueueEmpty(q)){
		return FALSE;
	} 
	
	*x = q->front->next->data;
	return TRUE;	
}

//出队列 
boolean deQueue(LinkQueue *q, dataType *x){
	LinkNode *p;
	
	if(isQueueEmpty(q)){
		return FALSE;
	}
	
	p = q->front->next;
	q->front->next = p->next;
	*x = p->data; 
	
	//若原队列中仅有一个有效结点,删除后变空 ? 自己没有考虑到这种情况?
    //如果不置队尾指针,则无法判空
	if(q->rear == p){   
		q->rear = q->front;
	}
	free(p);
	
	return TRUE;
}

//元素x进队列 
void enQueue(LinkQueue *q, dataType x){
	LinkNode *p;

	p = (LinkNode *)malloc(sizeof(LinkNode));
	p->data = x;
	p->next = NULL;
	
	q->rear->next = p;  //连接到队列上
	q->rear = p; 
}

boolean isQueueEmpty(LinkQueue *q){
	return q->front == q->rear;
}


//销毁队列(实验书上都没有销毁队列) 
void destroyQueue(LinkQueue **q){
	LinkNode *p;
	
	//释放除头结点以外的结点 
	while((*q)->front->next){
		p = (*q)->front->next;   
		(*q)->front->next = p->next;
		free(p);
	}
	free((*q)->front);  //释放头结点 
	
	free(*q);
	*q = NULL; 
	 
}

//初始化链队列(自己根据课本及之前的程序写的) 
boolean initQueue(LinkQueue **q){
	LinkNode *p;   
	
	if(*q != NULL){
		return FALSE;
	} 
	//开辟新结点(作头结点用)
	p = (LinkNode *)malloc(sizeof(LinkNode));
	p->next = NULL;
	
	//创建空链队列 
	*q = (LinkQueue *)malloc(sizeof(LinkQueue));
	(*q)->front = (*q)->rear = p;    //队头指针和队尾指针都指向头结点 
	
	return TRUE;
}



void main(void){
	LinkQueue  *q = NULL;
	dataType x1, x2; 
	
	printf("\n**初始化**\n");
	initQueue(&q);
	printf("队列空吗:%d\n", isQueueEmpty(q));
	
	printf("\n**入队**\n");
	enQueue(q, 70);
	enQueue(q, 80);
	enQueue(q, 90);
	showData(q);
	printf("队列空吗:%d\n", isQueueEmpty(q));
	
	printf("\n**出队**\n");
	deQueue(q, &x1);
	deQueue(q, &x1);
	deQueue(q, &x1);
	showData(q);
	printf("队列空吗:%d\n", isQueueEmpty(q));
	
	printf("\n**取元素**\n");
	getFrontData(q, &x1);
	getRearData(q, &x2);
	printf("队头元素为:%d,队尾元素为:%d\n", x1, x2);
	
	printf("\n**求队长**\n");
	printf("队长为:%d\n", lengthOfQueue(q));
	
	destroyQueue(&q);
	
} 

 

相关文章:

  • 2021-08-11
  • 2021-09-27
  • 2020-06-13
猜你喜欢
  • 2021-05-17
  • 2021-10-31
  • 2021-08-01
  • 2021-08-13
  • 2021-11-27
  • 2021-12-24
相关资源
相似解决方案