《数据结构》严蔚敏 链式存储实现队列 算法3_4_2

这个用链表代替数组来实现队列
这个代码书写的时候注意ClearQueue(Link_Queue *q)DestroyQueue(Link_Queue *q)这两个函数

前者在写的时候:要注意第一步是先将rear指针挪到指向队列首元素的位置,然后一举将剩下的元素一并释放,接着再释放首元素,然后使两个指针都指向头节点

后者在写的时候:要注意第一步也是先将rear指针挪到指向队列首元素的位置,但是此时是将包括首元素在内一并都释放掉。然后让两个指针都指向空。

剩下的和链表操作就差不多了,无需多费口舌
在这里插入图片描述

//用链式存储队列
//注意ClearQueue(Link_Queue *q) 写得很全面
#include<stdio.h>
#include<stdlib.h>

#define OK 0
#define ERROR -1


typedef int Status;
typedef int QElemType;


//链表上链的每一个结构
typedef struct QNode
{
	QElemType data;
	struct QNode *next;
	
}QNode,*QueuePtr;

//链表本身

typedef struct
{
	QueuePtr front;
	QueuePtr rear;
}Link_Queue;

Status
InitQueue(Link_Queue * q)
{
	//创建一个头节点和一个头指针

	q->front = (QueuePtr)malloc(sizeof(QNode));
	if(q->front == NULL)
		//return ERROR;
		exit(ERROR);
	
	q->rear = q->front;
	q->front->next = NULL;

	return OK;	

}

Status
DestroyQueue(Link_Queue *q)
{
	//free(q);
	//这考虑的也太navie了

	while(q->front)
	{
		q->rear = q->front->next;
		free(q->front);
		q->front = q->rear;
	}
	return OK;
}

//巧妙

Status
ClearQueue(Link_Queue *q)
{
	// if(q->front != q->rear)
	// 	q->front --;
	// q->front->next = NULL;

	q->rear = q->front->next;//先保存一下
	while(q->rear)
	{
		q->front->next = q->rear->next;
		free(q->rear);
		q->rear = q->front->next;
	}

	q->rear = q->front;

	return OK;
}

Status
QueueEmpty(Link_Queue q)
{
	if(q.front == q.rear)
		return OK;
	else
		return ERROR;

}

int
QueueLength(Link_Queue q)
{
	int count = 0;
	QueuePtr p = q.front;
	while(p != q.rear)
	{
		count++;
		p=p->next;
	}

	return count;
	//return q.rear - q.front;
	//this have a little question
	//算不算上头节点呢,是用头减尾还是尾减头呢?

}

Status
GetHead(Link_Queue q,QElemType *e)
{
	*e = q.front->next->data;

	return OK;

}

Status
EnQueue(Link_Queue *q,QElemType e)
{
	QueuePtr temp;
	temp = (QueuePtr)malloc(sizeof(QNode));
	if(temp == NULL)
		//return ERROR;
		exit(ERROR);

	temp->data = e;
	//temp = q->front;
	// while( temp != q->rear) //这里有尾指针啊大哥
	// {
	// 	temp = temp->next;
	// }

	//q->rear->next = temp;
	temp->next = NULL;

	q->rear->next = temp;
	q->rear = temp;
	//最后要把为指针改变一下

	return OK;


}

Status
DeQueue(Link_Queue *q,QElemType *e)
{
	if( q->front == q->rear ) return ERROR;
	//删除的时候要把原来的保存一下,好释放空间

	QueuePtr temp;
	temp = q->front->next;
	*e = temp->data;
	q->front->next = temp->next;

	//当删除最后一个元素时需要注意⚠️此时队尾指针丢了
	if(q->rear == temp)
		q->rear = q->front;

	free(temp); 

	//q->front->next = q->front->next->next;

	return OK;
	
}

Status
QueueTraverse(Link_Queue q,void(*visit)(QElemType ))
{
	if( q.front == q.rear ) return ERROR;
	while(q.front != q.rear)
	{
		q.front = q.front->next;
		visit(q.front->data);	
	}

	printf("\n");

	return OK;
}

void
visit(QElemType c)
{
	printf("%d ", c);
}

int main(int argc, char const *argv[])
{
	Link_Queue q;
	QElemType delete,length;
	InitQueue(&q);

	EnQueue(&q,1);
	EnQueue(&q,2);
	EnQueue(&q,3);
	EnQueue(&q,4);

	GetHead(q,&delete);
	printf("top is %d ", delete);
	printf("\nAfter insert: ");
	QueueTraverse(q,visit);

	length = QueueLength(q);

	printf("queue length is %d \n", length);

	DeQueue(&q,&delete);

	printf("\ndelete %d is ok!\n", delete);
	printf("\nAfter delete: ");

	QueueTraverse(q,visit);

	length = QueueLength(q);

	printf("queue length is %d \n", length);

	printf("\n");


	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37414405/article/details/86099400
今日推荐