码迷,mamicode.com
首页 > 其他好文 > 详细

链队列——队列的链式表示和实现

时间:2014-11-10 15:33:54      阅读:306      评论:0      收藏:0      [点我收藏+]

标签:线性表   链队列   数据结构   算法   adt   

一、单链队列的链式存储结构

相关代码下载链接:http://download.csdn.net/detail/shengshengwang/8141633

队列是操作受限的线性表,只允许在队尾插入元素,在队头删除元素。对于链队列结构,为了便于插入元素,设立了队尾指针,这样插入元素的操作便与队列长度无关。存储结构,如下所示:

typedef int QElemType;
typedef struct QNode
{
	QElemType data;
	QNode *next;
} *QueuePtr;
struct LinkQueue
{
	QueuePtr front, rear;  // 队头、队尾指针
};


二、单链队列的链式存储结构的基本操作

(1)构建队列

void InitQueue(LinkQueue &Q)
{ // 构造一个空队列Q
	Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));  // 生成头结点
	if(!Q.front)  // 生成头结点失败
		exit(3);
	Q.front->next = NULL;  // 头结点的next域为空
}

(2)销毁队列

void DestroyQueue(LinkQueue &Q)
{ // 销毁队列Q(无论空否均可)
	while(Q.front)  // Q.front不为空
	{
		Q.rear = Q.front->next;  // Q.rear指向Q.front的下一个结点
		free(Q.front);  // 释放Q.front所指结点
		Q.front = Q.rear;  // Q.front指向Q.front的下一个结点
	}
}

(3)队列判空

int QueueEmpty(LinkQueue Q)
{ // 若队列Q为空队列,则返回TRUE;否则返回FALSE
	if(Q.front->next == NULL)
		return 1;
	else
		return 0;
}

(4)插入队列

void EnQueue(LinkQueue &Q, QElemType e)
{ // 插入元素e为队列Q的新的队尾元素
	QueuePtr p;
	p = (QueuePtr)malloc(sizeof(QNode));  // 动态生成新结点
	if(!p)
		exit(3);  // 若分配堆内存失败,则退出 
	p->data = e;  // 将值e赋给新结点
	p->next = NULL;  // 新结点的指针域为空

	Q.rear->next = p;  // 原队尾结点的指针指向新结点
	Q.rear = p;  // 尾指针指向新结点
}

(5)删除队列

int DeQueue(LinkQueue &Q, QElemType &e)
{ // 若队列Q不空,删除Q的队头元素,用e返回其值
  // 并返回OK;否则返回ERROR
	QueuePtr p;
	if(Q.front == Q.rear)  // 队列空
		return 0;

	p = Q.front->next;  //  p指向队头结点
	e = p->data;  // 将队头元素的值赋给e
	Q.front->next = p->next;  // 头结点指向下一个结点

	if(Q.rear == p)  // 删除的是队尾结点
		Q.rear = Q.front;  // 修改队尾指针指向头结点(空队列)

	free(p);  // 释放队头结点
	return 1;
}

(6)取得队列首元素

int GetHead(LinkQueue Q, QElemType &e)
{ // 若队列Q不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
	QueuePtr p;
	if(Q.front == Q.rear)  // 队列空
		return 0;
	p = Q.front->next;  // p指向队头结点
	e = p->data;  // 将队头元素的值赋给e
	return 1;
}

(7)遍历队列

void print(QElemType e)
{
	printf("%d ", e);
}

void QueueTraverse(LinkQueue Q, void(*visit)(QElemType))
{ // 从队头到队尾依次对队列Q中的每个元素调用visit()
	QueuePtr p = Q.front->next;  // p指向队头结点
	while(p)  // p指向结点
	{
		visit(p->data);  // 对p所指元素调用visit()
		p = p->next;
	}
	printf("\n");
}


三、检验基本操作的主函数

void main()
{
	QElemType d;
	LinkQueue q;

	InitQueue(q);  // 构造空队列q,失败则退出
	// 依次入队3个元素
	EnQueue(q, -5);
	EnQueue(q, 5);
	EnQueue(q, 10);
	printf("队列的元素依次为:");
	QueueTraverse(q, print);

	GetHead(q, d);
	DeQueue(q, d);
	printf("队列的元素依次为:");
	QueueTraverse(q, print);
}


四、队列抽象数据类型定义

ADT Queue{
    数据对象:D={ai|ai∈ElemSet, i=1,2, …,n, n≥0}
    数据关系:R1={<ai-1,ai>|ai-1,ai∈D, i=1,2, …,n }
		  约定a1为队列头,an为队列尾。
    基本操作:
    InitQueue( &Q )
      操作结果:构造一个空队列Q。
    DestroyQueue ( &Q )
      初始条件:队列Q已存在。
      操作结果:销毁队列Q。
    ClearQueue ( &Q )
      初始条件:队列Q已存在。
      操作结果:将Q清为空队列。
    QueueEmpty( Q )
      初始条件:队列Q已存在。
      操作结果:若Q为空队列,则返回TRUE,否则返回FALSE。
    QueueLength( Q )
      初始条件:队列Q已存在。
      操作结果:返回Q的数据元素个数,即队列的长度。
    GetHead( Q, &e )
      初始条件:队列Q已存在且非空。
      操作结果:用e返回Q的队头元素。
    EnQueue( &Q, e )
      初始条件:队列Q已存在。
      操作结果:插入元素e为Q的新的队尾元素。
    DeQueue( &Q, &e )
      初始条件:队列Q已存在且非空。
      操作结果:删除Q的队头元素,并用e返回其值。
QueueTraverse( Q, visit() )
      初始条件:队列Q已存在且非空。
      操作结果:从队头到队尾依次对Q的每个数据元素调用函数visit()。一旦visit()失败,则操作失败。
}ADT Queue

链队列——队列的链式表示和实现

标签:线性表   链队列   数据结构   算法   adt   

原文地址:http://blog.csdn.net/ssw_1990/article/details/40980583

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!