欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(算法)

程序员文章站 2024-03-21 13:57:46
...

内容:

      假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的置空队、判空对、入队和出队等算法

步骤:

1.算法分析:

       要写出置空队、判空队、入队和出队的算法之前,需要先定义链队结构。其中,首先需要定义结点类型,而且只设置一个指向队尾元素的指针。

       定义好链队结构之后,先写置空队的算法。所谓置空队,就是使头结点成为队尾元素,将队尾指针指向头结点。但是这里可能会出现一个意外情况,就是队中元素非空,所以接下来需要将队中元素逐个出队,这里使用while语句进行操作,条件为Q->rear!=Q->rear->next,将队中元素全部出队后,回收其结点空间,避免空间浪费。

       判队空的算法十分简单,就是头结点的next指针指向自己时为空队。

      入队,也就是在尾结点处插入元素。插入前需要申请新结点,申请完成后,初始化新结点并链入,最后将尾指针移动至新结点,完成入队。

      出队,即为把头结点之后的元素摘下,p指向将要摘下的结点,操作为:p=Q->rear->next->next;并且保存结点中的数据。这里需要注意的是,当队列只有一个结点时,需要将p结点出队,此时需要将队尾指针指向头结点。否则摘下结点p,释放被删结点。

2.概要设计:

                             函数                         作用
                      InitQueue()                       置空队
                   EmptyQueue()                       判空队
                      EnQueue()                       入    队
                      DeQueue()                       出     队

3.源代码(算法):

首先定义链队结构:

  //先定义链队结构
    typedf struct queuenode{        //结点类型的定义 
	     Datetype data;
	     struct queuenode *next;
	} QueueNode;
	typedef struct{      //只设一个指向队尾元素的指针 
		queuenode *rear;
	}LinkQueue; 

置空队:

//置空队
	void InitQueue(LinkQueue *Q)
	{                    //置空队:就是使头结点成为队尾元素 
		QueueNode *s;
		Q->rear=Q->rear->next;      //将队尾指针指向头结点
		while(Q->rear!=Q->rear->next)  //当队列非空,将队中元素逐个出队 
		{
			s=Q->raer->next;
			Q->rear->next=s->next;
			free(s);
		}         //回收结点空间 
	 } 
	 

判空队:

 //判队空
	 int EmptyQueue(LinkQueue *Q)
	 {                     
	 	return Q->rear->next==Q->rear; //判队空,当头结点的next指针指向自己时为空队 
	  } 

入队:
 

//入队
	  void EnQueue(LinkQueue *Q,Datatype x)   //入队,也就是在尾节点 处插入元素 
	  {
	  	QueueNode *p=(QueueNode *)malloc(sizeof(QueueNode));  //申请新结点 
	  	p->data=x;p->next=Q->rear->next;       //初始化新结点并链入 
		Q-rear->next=p;
		Q->rear=p;                  //将尾指针移至新结点 
	   } 

出队:

// 出队
	Datatype DeQueue(LinkQueue *Q)     //出队,把头结点之后的元素摘下 
	{
		Datatype t;
		QueueNode *P;
		if(EmptyQueue(Q))
		    Error("Queue underflow");
		p=Q->rear->next->next;            //p指向将要摘下得结点 
		x=p->data;                        //保存结点中的数据 
		if(p==Q->rear)                    //当队列中只有一个结点时,p结点出队后,要将队尾指针指向头结点 
		{
			Q->rear=Q->rear->next;Q->rear->next=p->next;
		}
		else
		    Q->rear->next=p->next;
		free(p);                            //摘下结点p 
		return x;                           //释放被删结点 
	 }