Exemple #1
0
//测试单链队列的主程序 
int main() 
{ 
    SqQueue s; 
    int x; 
    //输入若干正整数以0结束,依次入栈,然后依次出栈并打印 
    InitQueue(&s); 
    printf("Is empty: %d\n",IsEmpty(s));
    printf("the length is: %d\n",QueueLength(s));
    printf("进入队列顺序:   1   2   3 \n"); 
	EnQueue(&s,1); 
	EnQueue(&s,2); 
	EnQueue(&s,3);
 	printf("the top is : %d\n",x);
 	printf("Is empty: %d\n",IsEmpty(s));
 	printf("the length is: %d\n",QueueLength(s));
    printf("\n退出队列结果:"); 
    while(!IsEmpty(s)) { 
        DEQueue(&s,&x); 
        printf("%4d",x); 
    }
	printf("\nIs empty: %d\n",IsEmpty(s)); 
     
     
    //------------------------------------- 
    // TODO (#1#): 其它测试程序  
     
    //------------------------------------- 
     
    DestroyQueue(&s); //销毁栈  
        
    return 0; 
}
int main()
{
	int i;
	QElemType d;
	LinkQueue q;
	i=InitQueue(&q);
	if(i)
		printf("成功地构造了一个空队列!\n");
	printf("是否空队列?%d(1:空 0:否)  ",QueueEmpty(q));
	printf("队列的长度为%d\n",QueueLength(q));
	EnQueue(&q,-5);
	EnQueue(&q,5);
	EnQueue(&q,10);
	printf("插入3个元素(-5,5,10)后,队列的长度为%d\n",QueueLength(q));
	printf("是否空队列?%d(1:空 0:否)  ",QueueEmpty(q));
	printf("队列的元素依次为:");
	QueueTraverse(q);
	i=GetHead(q,&d);
	if(i==OK)
	 printf("队头元素是:%d\n",d);
	DeQueue(&q,&d);
	printf("删除了队头元素%d\n",d);
	i=GetHead(q,&d);
	if(i==OK)
		printf("新的队头元素是:%d\n",d);
	ClearQueue(&q);
	printf("清空队列后,q.front=%u q.rear=%u q.front->next=%u\n",q.front,q.rear,q.front->next);
	DestroyQueue(&q);
	printf("销毁队列后,q.front=%u q.rear=%u\n",q.front, q.rear);
	
	return 0;
}
Exemple #3
0
int main()
{
  Status j;
  int i=0, l;
  QElemType d;
  SqQueue Q;

  InitQueue(&Q);
  printf("初始化队列后 队列是否为空%d  1:空 0:非空 \n", QueueEmpty(Q));

  printf("请输入整型队列元素(不超过%d个), -1为提前结束标识符 \n", MAXSIZE-1);

  do
  {
    scanf("%d", &d);
    if (d == -1)
      break;
    EnQueue(&Q, d);
    i++;
  }while(i < MAXSIZE-1);

  printf("队列长度为: %d \n", QueueLength(Q));

  printf("队列是否为空%d  1:空 0:非空 \n", QueueEmpty(Q));
  printf("连续%d次从队首删除元素, 从队尾插入元素: \n", MAXSIZE);

  for(l = 1; l <= MAXSIZE; l++)
  {
    DeQueue(&Q, &d);
    printf("删除的元素是: %d 插入的元素是 %d \n", d, l+100);

    d = l + 100;
    EnQueue(&Q, d);
  }

  printf("现在队列中的元素为: \n");
  QueueTraverse(Q);

  printf("共向队尾插入了 %d 个元素 \n", i+MAXSIZE);
  l = QueueLength(Q);
  if (l-2 > 0)
    printf("现在由队头开始删除 %d 个元素\n", l-2);

  while(QueueLength(Q) > 2)
  {
    DeQueue(&Q, &d);
    printf("删除的元素为 %d \n", d);
  }

  j = GetHead(Q, &d);
  if (j)
    printf("现在队首的元素为 %d \n", d);

  ClearQueue(&Q);
  printf("清空队列后队列是否为空%d  1:空 0:非空 \n", QueueEmpty(Q));
  return 0;
}
int main()
{
	Status j;
	int i=0,l;
	QElemType d;
	SqQueue Q;
	InitQueue(&Q);
	printf("初始化队列后,队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));

	printf("请输入整型队列元素(不超过%d个),-1为提前结束符: ",MAXSIZE-1);
	do
	{
		/* scanf("%d",&d); */
		d=i+100;
		if(d==-1)
			break;
		i++;
		EnQueue(&Q,d);
	}while(i<MAXSIZE-1);

	printf("队列长度为: %d\n",QueueLength(Q));
	printf("现在队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
	printf("连续%d次由队头删除元素,队尾插入元素:\n",MAXSIZE);
	for(l=1;l<=MAXSIZE;l++)
	{
		DeQueue(&Q,&d);
		printf("删除的元素是%d,插入的元素:%d \n",d,l+1000);
		/* scanf("%d",&d); */
		d=l+1000;
		EnQueue(&Q,d);
	}
	l=QueueLength(Q);

	printf("现在队列中的元素为: \n");
	QueueTraverse(Q);
	printf("共向队尾插入了%d个元素\n",i+MAXSIZE);
	if(l-2>0)
		printf("现在由队头删除%d个元素:\n",l-2);
	while(QueueLength(Q)>2)
	{
		DeQueue(&Q,&d);
		printf("删除的元素值为%d\n",d);
	}

	j=GetHead(Q,&d);
	if(j)
		printf("现在队头元素为: %d\n",d);
	ClearQueue(&Q);
	printf("清空队列后, 队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
	return 0;
}
/*-----------------------------------
    Breadth_First_Search
-----------------------------------*/
void BFSTraverse(MGraph G)
{
	int i, j;
	LinkQueue Q;

	for(i=0; i<G.numVertexs; i++)
		visited[i] = FALSE;
	InitQueue(&Q);
	for(i=0; i<G.numVertexs; i++)
	{
		if(visited[i] == TRUE)				//顶点是否已经被访问过
			continue;
		visited[i] = TRUE;
		printf("visited %c\n", G.vex[i]);	//访问顶点,或者进行其他操作
		EnQueue(&Q, i);						//该顶点序号入队列

		//当前队列不为空时,一直遍历
		while(QueueLength(Q)>0)
		{
			DeQueue(&Q,&i);					//出队列,得到出来的顶点的序号
			for(j=0; j<G.numVertexs; j++)
			{
				if((G.edge[i][j]!=0 || G.edge[i][j]!=INFINITY) && (visited[j]==FALSE))
				{
					printf("visited %c\n", G.vex[j]);
					visited[j] = TRUE;
					EnQueue(&Q, j);			//与i顶点相连的顶点j入队列
				}
			}
		}
	}

}
int main()
{
	int a;
	SqQueue S;
	QElemType x, e;
	if (InitQueue(S))    // 判断顺序表是否创建成功,请填空
	{
		printf("A Queue Has Created.\n");
	}
	while (1)
	{
		printf("1:Enter \n2:Delete \n3:Get the Front \n4:Return the Length of the Queue\n5:Load the Queue\n0:Exit\nPlease choose:\n");
		scanf("%d", &a);
		switch (a)
		{
		case 1: scanf("%d", &x);
			if (!EnQueue(S,x)) printf("Enter Error!\n"); // 判断入队是否合法,请填空
			else printf("The Element %d is Successfully Entered!\n", x);
			break;
		case 2: if (!DeQueue(S,e)) printf("Delete Error!\n"); // 判断出队是否合法,请填空
				else printf("The Element %d is Successfully Deleted!\n", e);
				break;
		case 3: if (!GetHead(S,e))printf("Get Head Error!\n"); // 判断Get Head是否合法,请填空
				else printf("The Head of the Queue is %d!\n", e);
				break;
		case 4: printf("The Length of the Queue is %d!\n", QueueLength(S));  //请填空
			break;
		case 5: QueueTraverse(S);//请填空
			break;
		case 0: return 1;
		}
	}
}
Exemple #7
0
void tcp_client_appcall_user(void)
{
    uint8 buffer[ELEMENT_SIZE];
    if (uip_aborted() || uip_timedout() || uip_closed())
    {
        tcp_client_reconnect();
        return;
    }

    if (uip_rexmit())
    {
        _uip_send_rexmit_http();
        return;
    }

    if (QueueLength(&queue) != 0)
    {
        FreeQueuePop(&queue, buffer);
        _uip_send_http(buffer);
    }
    else
    {
        if (nv_read_msg(buffer))
        {
            _uip_send_http(buffer);
        }
    }

    if (uip_newdata())
    {
        process_ip_command(uip_datalen(), (uint8*)uip_appdata);
    }
}
Exemple #8
0
/*  BFS: Breadth First Search */
int GetMinRingSize( inp_ATOM* atom, QUEUE *q, AT_RANK *nAtomLevel, S_CHAR *cSource, AT_RANK nMaxRingSize )
{
    int qLen, i, j;
    AT_RANK nCurLevel, nRingSize, nMinRingSize=MAX_ATOMS+1;
    qInt at_no, next;
    int  iat_no, inext;
    
    while ( qLen = QueueLength( q ) ) {
        /*  traverse the next level (next outer ring) */
        for ( i = 0; i < qLen; i ++ ) {
            if ( 0 <= QueueGet( q, &at_no ) ) {
                iat_no = (int)at_no;
                nCurLevel = nAtomLevel[iat_no] + 1;
                if ( 2*nCurLevel > nMaxRingSize + 4 ) {
                    /*  2*nCurLevel = nRingSize + 3 + k, k = 0 or 1  */
                    if ( nMinRingSize < MAX_ATOMS+1 ) {
                        return (nMinRingSize >= nMaxRingSize)? 0 : nMinRingSize;
                    }
                    return 0; /*  min. ring size > nMaxRingSize */
                }
                for ( j = 0; j < atom[iat_no].valence; j ++ ) {
                    next  = (qInt)atom[iat_no].neighbor[j];
                    inext = (int)next;
                    if ( !nAtomLevel[inext] ) {
                        /*  the at_no neighbor has not been traversed yet. Add it to the queue */
                        if ( 0 <= QueueAdd( q, &next ) ) {
                            nAtomLevel[inext] = nCurLevel;
                            cSource[inext] = cSource[iat_no]; /*  keep the path number */
                        } else {
                            return -1; /*  error */
                        }
                    } else
                    if ( nAtomLevel[inext]+1 >= nCurLevel &&
                         cSource[inext] != cSource[iat_no]
                         /*  && cSource[(int)next] != -1 */
                       ) {
                        /*  found a ring closure */
                        /*  debug */
                        if ( cSource[inext] == -1 ) {
                            return -1;  /*  error */
                        }
                        if ( (nRingSize = nAtomLevel[inext] + nCurLevel - 2) < nMinRingSize ) {
                            nMinRingSize = nRingSize;
                        }
                        /* return (nRingSize >= nMaxRingSize)? 0 : nRingSize; */
                    }
                }
            } else {
                return -1; /*  error */
            }
        }
    }

    if ( nMinRingSize < MAX_ATOMS+1 ) {
        return (nMinRingSize >= nMaxRingSize)? 0 : nMinRingSize;
    }

    return 0;
}
Status EnQueue(SqQueue &Q, const QElemType &e)
{
	if(QueueLength(Q) == QUEUE_MAX_SIZE - 1)
	{
		return ERROR;
	}
	
	Q.base[Q.rear] = e;
	Q.rear = (Q.rear + 1) % QUEUE_MAX_SIZE;
	return OK;
}
Status QueueTraverse(SqQueue &Q, Status(*visit)(QElemType &e))
{
	for(int i = 0, len = QueueLength(Q); i < len; i++)
	{
		Status status = visit(Q.base[(Q.front + i) % QUEUE_MAX_SIZE]);
		if(!status)
		{
			break;
		}
	}
}
void main()
{
	Status j;
	int i=0,m;
	QElemType d;
	SqQueue Q;
	InitQueue(Q);
	printf("初始化队列后,队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
	printf("请输入整型队列元素(不超过%d个),-1为提前结束符:",MAX_QSIZE-1);
	do
	{ scanf("%d",&d);
	  if(d==-1)
		  break;
	  i++;
	  EnQueue(Q,d); } while(i<MAX_QSIZE-1);
	printf("队列长度为%d,",QueueLength(Q));
	printf("现在队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
	printf("连续%d次由队头删除元素,队尾插入元素:\n",MAX_QSIZE);
	for(m=1; m<=MAX_QSIZE; m++)
	{ DeQueue(Q,d);
	  printf("删除的元素是%d,请输入待插入的元素:",d);
	  scanf("%d",&d);
	  EnQueue(Q,d); }
	m=QueueLength(Q);
	printf("现在队列中的元素为");
	QueueTraverse(Q,print);
	printf("共向队尾插入了%d个元素。",i+MAX_QSIZE);
	if(m-2>0)
		printf("现在由队头删除%d个元素,",m-2);
	while(QueueLength(Q)>2)
	{ DeQueue(Q,d);
	  printf("删除的元素值为%d,",d); }
	j=GetHead(Q,d);
	if(j)
		printf("现在队头元素为%d\n",d);
	ClearQueue(Q);
	printf("清空队列后,队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
	DestroyQueue(Q);
}
int Minimum(LinkQueue *q){
	//返回最小列队ID
	int n[5],k,l,i;
	for(i=1;i<=4;i++)n[i]=QueueLength(q[i]);
	k=1;l=n[1];
	for(i=2;i<=4;i++){
		if(n[i]<l){
			k=i;
			l=n[i];
		}
	}
	return k;
}
Exemple #13
0
 void main()
 {
   Status j;
   int i,n;
   QElemType d;
   SqQueue Q;
   InitQueue(Q);
   printf("初始化队列后,队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
   printf("队列长度为:%d\n",QueueLength(Q));
   printf("请输入队列元素个数n: ");
   scanf("%d",&n);
   printf("请输入%d个整型队列元素:\n",n);
   for(i=0;i<n;i++)
   {
     scanf("%d",&d);
     EnQueue(Q,d);
   }
   printf("队列长度为:%d\n",QueueLength(Q));
   printf("现在队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
   printf("现在队列中的元素为: \n");
   QueueTraverse(Q,visit);
   DeQueue(Q,d);
   printf("删除队头元素%d\n",d);
   printf("队列中的元素为: \n");
   QueueTraverse(Q,visit);
   j=GetHead(Q,d);
   if(j)
     printf("队头元素为: %d\n",d);
   else
     printf("无队头元素(空队列)\n");
   ClearQueue(Q);
   printf("清空队列后, 队列空否?%u(1:空 0:否)\n",QueueEmpty(Q));
   j=GetHead(Q,d);
   if(j)
     printf("队头元素为: %d\n",d);
   else
     printf("无队头元素(空队列)\n");
   DestroyQueue(Q);
 }
Exemple #14
0
 int Minimum(LinkQueue Q[]) // 返回最短队列的序号
 {
   int l[Qu];
   int i,k;
   for(i=0;i<Qu;i++)
     l[i]=QueueLength(Q[i]);
   k=0;
   for(i=1;i<Qu;i++)
     if(l[i]<l[0])
     {
       l[0]=l[i];
       k=i;
     }
   return k;
 }
/*Bianry Search Tree 层次遍历操作*/
void LevelOrder(BinaryTree btree) {
	Queue bQueue;
	if (btree) {
		InitalQueue(bQueue);
		EnQueue(bQueue, btree);
		//不需要再判断btree是否为空
		while (QueueLength(bQueue)!=0) {	
			DeQueue(bQueue, btree);
			printf("%d ", btree->key);
			if (btree->lchild!=NULL) EnQueue(bQueue, btree->lchild);
			if (btree->rchild!=NULL) EnQueue(bQueue, btree->rchild);
		}
		printf("\n");
	}

}
int main(int argc, char **argv)
{
	SqQueue sq;
	InitQueue(&sq);
	
	int input, count = MAXQSIZE;
	while(count){
		scanf("%d", &input);
		if(EnQueue(&sq,input)){
			printf("The Queue is full!\n");
			break;
		}
	}
	printf("Length of Queue: %d\n", QueueLength(&sq));
	
	return 0;
}
Status QueueTraverse(SqQueue Q)
{
	// 若队列不空,则从队头到队尾依次输出各个队列元素,并返回OK;否则返回ERROR.
	int i;
	i = Q.front;
	if (Q.rear+1==i)printf("The Queue is Empty!");  //请填空
	else {
		printf("The Queue is: ");
		int j = QueueLength(Q);
		while (j--)     
		{
			printf("%d ", Q.base[i]);   //用数组
			i = i+1;   //请填空
		}
	}
	printf("\n");
	return OK;
}
//----------------------------------------------------------------------
//
//	ProcessSchedule
//
//	Schedule the next process to run.  If there are no processes to
//	run, exit.  This means that there should be an idle loop process
//	if you want to allow the system to "run" when there's no real
//	work to be done.
//
//	NOTE: the scheduler should only be called from a trap or interrupt
//	handler.  This way, interrupts are disabled.  Also, it must be
//	called consistently, and because it might be called from an interrupt
//	handler (the timer interrupt), it must ALWAYS be called from a trap
//	or interrupt handler.
//
//	Note that this procedure doesn't actually START the next process.
//	It only changes the currentPCB and other variables so the next
//	return from interrupt will restore a different context from that
//	which was saved.
//
//----------------------------------------------------------------------
void
ProcessSchedule ()
{
  PCB		*pcb;
  int		i;

  dbprintf ('p', "Now entering ProcessSchedule (cur=0x%x, %d ready)\n",
	    currentPCB, QueueLength (&runQueue));
  // The OS exits if there's no runnable process.  This is a feature, not a
  // bug.  An easy solution to allowing no runnable "user" processes is to
  // have an "idle" process that's simply an infinite loop.
  if (QueueEmpty (&runQueue)) {
    printf ("No runnable processes - exiting!\n");
    exitsim ();	// NEVER RETURNS
  }

// Move the front of the queue to the end, if it is the running process.

  pcb = (PCB *)((QueueFirst (&runQueue))->object);
  if (pcb == currentPCB)
  {
    QueueRemove (&pcb->l);
    QueueInsertLast (&runQueue, &pcb->l);
  }

  // Now, run the one at the head of the queue.
  pcb = (PCB *)((QueueFirst (&runQueue))->object);
  currentPCB = pcb;
  dbprintf ('p',"About to switch to PCB 0x%x,flags=0x%x @ 0x%x\n",
	    pcb, pcb->flags,
	    pcb->sysStackPtr[PROCESS_STACK_IAR]);

  // Clean up zombie processes here.  This is done at interrupt time
  // because it can't be done while the process might still be running
  while (!QueueEmpty (&zombieQueue)) {
    pcb = (PCB *)(QueueFirst (&zombieQueue)->object);
    dbprintf ('p', "Freeing zombie PCB 0x%x.\n", pcb);
    QueueRemove (&pcb->l);
    ProcessFreeResources (pcb);
  }
  // Set the timer so this process gets at most a fixed quantum of time.
  TimerSet (processQuantum);
  dbprintf ('p', "Leaving ProcessSchedule (cur=0x%x)\n", currentPCB);
}
void CustomerArrived()
{ /* 处理客户到达事件,en.NType=Qu */
	QElemType f;
	int durtime, intertime, i;
	++CustomerNum;
	Random(&durtime, &intertime); /* 生成随机数 */
	et.OccurTime = en.OccurTime + intertime; /* 下一客户到达时刻 */
	et.NType = Qu; /* 队列中只有一个客户到达事件 */
	if (et.OccurTime < CloseTime) /* 银行尚未关门,插入事件表 */
		OrderInsert(&ev, et, cmp);
	i = Minimum(q); /* 求长度最短队列的序号,等长为最小的序号 */
	f.ArrivalTime = en.OccurTime;
	f.Duration = durtime;
	EnQueue(&q[i], f);
	if (QueueLength(q[i]) == 1)
	{
		et.OccurTime = en.OccurTime + durtime;
		et.NType = i;
		OrderInsert(&ev, et, cmp); /* 设定第i队列的一个离开事件并插入事件表 */
	}
}
Exemple #20
0
 void CustomerArrived()
 { // 处理客户到达事件,en.NType=Qu
   QElemType f;
   int durtime,intertime,i;
   ++CustomerNum;
   Random(durtime,intertime); // 生成随机数
   et.OccurTime=en.OccurTime+intertime; // 下一客户到达时刻
   et.NType=Qu; // 队列中只有一个客户到达事件
   if(et.OccurTime<CloseTime) // 银行尚未关门,插入事件表
     OrderInsert(ev,et,cmp);
   i=Minimum(q); // 求长度最短队列的序号,等长为最小的序号
   f.ArrivalTime=en.OccurTime;
   f.Duration=durtime;
   EnQueue(q[i],f);
   if(QueueLength(q[i])==1)
   {
     et.OccurTime=en.OccurTime+durtime;
     et.NType=i;
     OrderInsert(ev,et,cmp); // 设定第i队列的一个离开事件并插入事件表
   }
 }
void CustomerArrived(int CloseTime,int &CustomerNum,Event &en,EvenList &ev,LinkQueue *q){
	//处理到达事件 en.NType=0
	++CustomerNum;
	Event t;
	int durtime,intertime;
	Random(durtime,intertime);
	t.OccurTime=en.OccurTime+intertime;
	t.NType=0;
	if(t.OccurTime<CloseTime)//插入事件表
		OrderInsert(ev,t,cmp);
	int i=Minimum(q);
	
	QElemType t2;
	t2.ArrivaTime=en.OccurTime;
	t2.Duration=durtime;

	EnQueue(q[i],t2);
	t.OccurTime=en.OccurTime+durtime;
	t.NType=i;
	if(QueueLength(q[i])==1)//设定列队的离开事件
		OrderInsert(ev,t,cmp);
}
Exemple #22
0
int main(void)
{
	int select;		/*保存选择变量*/
	size_t pos;		/*位序*/
	Elem e;			/*保存从函数返回的结点的值*/
	Elem v;			/*保存传递给函数的结点的值*/
	
	size_t i= 0;
	LINKQUEUE Q;
	InitQueue(&Q);
	srand((int)time(NULL));
	while (i < 10)
	{
		InsertQueue(&Q, rand()%20);
		++i;
	}

	while (1)	/*while_@1*/
	{
		if (!Q.front)
		{
			printf("队列不存在!\n");
			break;
		}

		system("cls");
		Menu();

		printf("请输入您的选择(1~10):");
		scanf("%d", &select);
		getchar();

		switch (select)	/*switch_@1*/
		{
		case 1:			/*入队*/
			v = InputValue("入队元素为:");
			if (FAILE == InsertQueue(&Q, v))
			{
				printf("入队失败!\n");
			}
			else
			{
				printf("入队成功!\n");
			}
			
			getchar();
			break;
		case 2:			/*输出队列*/
			printf("队列为:");
			TraveQueue(&Q);
			
			getchar();
			break;
		case 3:			/*出队*/
			if (OK == DeleteQueue(&Q, &e))
			{
				printf("出队成功,删除的元素是%d!\n", e);
			}
			else
			{
				printf("删除失败!\n");
			}

			getchar();
			break;

		case 4:			/*输出队列的长度*/
			printf("表长为: %d \n", QueueLength(&Q));
			
			getchar();
			break;

		case 5:			/*清空队列*/
			ClearQueue(&Q);
			printf("该表已经清空!\n");
			
			getchar();
			break;

		case 6:			/*返回队头元素*/
			if (OK == GetHead(&Q, &e))
			{
				printf("该结点为:%d\n", e);
			}
			else
			{
				printf("不存在!\n");
			}

			getchar();	
			break;

		case 7:			/*判断队列是否为空*/
			if (QueueEmpty(&Q) == TRUE)
			{
				printf("队列为空!\n");
			}
			else
			{
				printf("队列非空!\n");
			}

			getchar();	
			break;
		
		case 8:			/*销毁队列*/
			DestroyQueue(&Q);
			printf("队列已删除!\n");

			getchar();	
			break;
		
		default:
			printf("请重新选择!\n");
			
			getchar();
			break;
		}/*switch_@1*/

	}	/*while_@1*/
	
	return EXIT_SUCCESS;
}
Exemple #23
0
QElemType getHead(LinkQueue &q){
	QElemType k={-1,-1} ;
	if(QueueLength(q)==0) return k; 
	return ((q.front)->next)->data;
}
Exemple #24
0
//----------------------------------------------------------------------
//
//	ProcessSchedule
//
//	Schedule the next process to run.  If there are no processes to
//	run, exit.  This means that there should be an idle loop process
//	if you want to allow the system to "run" when there's no real
//	work to be done.
//
//	NOTE: the scheduler should only be called from a trap or interrupt
//	handler.  This way, interrupts are disabled.  Also, it must be
//	called consistently, and because it might be called from an interrupt
//	handler (the timer interrupt), it must ALWAYS be called from a trap
//	or interrupt handler.
//
//	Note that this procedure doesn't actually START the next process.
//	It only changes the currentPCB and other variables so the next
//	return from interrupt will restore a different context from that
//	which was saved.
//
//----------------------------------------------------------------------
// You should modify this function to use 4.4BSD scheduling policy
//
void
ProcessSchedule ()
{
  PCB           *pcb;
  int           i;
  int empty;
  int count = 0;
  float pinfotime;
  PCB* tailPtrs[32];
  PCB *curr; 
  total_num_quanta++;
  currentPCB->estcpu++;
  currentPCB->estcputime++;

  if (currentPCB->p_info) {  
    pinfotime = currentPCB->estcputime *.1;
    printf(TIMESTRING1, (int)GetCurrentPid());
    printf(TIMESTRING2, pinfotime);
    printf(TIMESTRING3, (int)GetCurrentPid());
    printf(TIMESTRING4, currentPCB->prio);
  }

  empty = 1;
  for (i = 0; i < 32; i++) {
    count += QueueLength(&runQueue[i]);     
  }
  dbprintf ('p', "Now entering ProcessSchedule (cur=0x%x, %d ready)\n",
            currentPCB, count);
  // The OS exits if there's no runnable process.  This is a feature, not a
  // bug.  An easy solution to allowing no runnable "user" processes is to
  // have an "idle" process that's simply an infinite loop.
  if (!count) {
    printf ("No runnable processes - exiting!\n");
    exitsim (); // NEVER RETURNS
  }
  dbprintf('p', "About to check if estcpu is divisible by 4 (cur=0x%x\n", currentPCB);
  if ((int)currentPCB->estcputime % 4 == 0) {
    //printf("Updating prio");
    currentPCB->prio = PUSER + (int)(currentPCB->estcpu/4) + 2*currentPCB->p_nice;
  }
dbprintf('p', "About to move to end of queue (cur=0x%x\n", currentPCB);

  // Move the front of the queue to the end, if it is the running process.
  for (i = 0; i < 32; i++) {
    pcb = (PCB *)((QueueFirst (&runQueue[i]))->object);
    if (pcb == currentPCB)
    {
      QueueRemove(&pcb->l);
      QueueInsertLast(&runQueue[pcb->prio/4], &pcb->l);
      break;
    }
  }
dbprintf('p', "Before decay (cur=0x%x\n", currentPCB);


  //decay
  if (!(total_num_quanta % 10)) {
    //printf("Looping through all to update everything");
    for (i = 0; i < 32; i++) { // loop through each queue
      if (!QueueLength(&runQueue[i]))
          continue;
      curr = QueueFirst(&runQueue[i])->object;
      dbprintf('p', "Processing PCB in queue %d: 0x%x\n", i, curr);
      while (curr && curr->processed != processedFlag) { // all the elements not previously processed in the queue
        curr->estcpu = 2.0f/(2 + 1) *curr->estcpu + curr->p_nice;
        curr->prio = PUSER + (int)(curr->estcpu/4) + 2*curr->p_nice;
        curr->processed = processedFlag;
        QueueRemove(&curr->l);
        QueueInsertLast(&runQueue[curr->prio/4], &curr->l);
        curr = QueueFirst(&runQueue[i])->object;
        dbprintf('p', "Processing PCB in queue %d: 0x%x\n", i, curr);
      }
    }
  
    processedFlag = 1 - processedFlag;
  }
  // Now, run the one at the head of the queue.
  dbprintf ('p',"About to switch 0x%x", currentPCB);

  for (i = 0; i < 32; i++) {
    if (!QueueLength(&runQueue[i]))
      continue;
    pcb = (PCB *)((QueueFirst (&runQueue[i]))->object);
    currentPCB = pcb;
    dbprintf ('p',"About to switch to PCB 0x%x,flags=0x%x @ 0x%x\n",
              pcb, pcb->flags,
              pcb->sysStackPtr[PROCESS_STACK_IAR]);
    break;
  }

  // Clean up zombie processes here.  This is done at interrupt time
  // because it can't be done while the process might still be running
  while (!QueueEmpty (&zombieQueue)) {
    pcb = (PCB *)(QueueFirst (&zombieQueue)->object);
    dbprintf ('p', "Freeing zombie PCB 0x%x.\n", pcb);
    QueueRemove (&pcb->l);
    ProcessFreeResources (pcb);
  }
  // Set the timer so this process gets at most a fixed quantum of time.
  TimerSet (processQuantum);
  dbprintf ('p', "Leaving ProcessSchedule (cur=0x%x)\n", currentPCB);
}
/**
 *MAIN函数
 */
int main()
{
    //初始化操作,建立一个队列
    queue* testqueue = NULL;
    testqueue = InitQueue();

    //判断队列是否为空
    QueueEmpty(testqueue)?printf("True\n"):printf("False\n");
    printf("\n");

    //数据进入队列
    int i;
    for(i=0;i<15;i++)
    {
        EnQueue(testqueue,i);
    }
    QueueEmpty(testqueue)?printf("True\n"):printf("False\n");
    printf("\n");

    //数据退出队列
    int temp;
    for(i=0;i<10;i++)
    {
        DeQueue(testqueue,&temp);
        printf("%d ",temp);
    }
    QueueEmpty(testqueue)?printf("\nTrue\n"):printf("\nFalse\n");
    printf("\n");

    //数据进入队列
    for(i=0;i<15;i++)
    {
        EnQueue(testqueue,i);
    }
    QueueEmpty(testqueue)?printf("True\n"):printf("False\n");
    printf("\n");

    //数据退出队列
    for(i=0;i<17;i++)
    {
        DeQueue(testqueue,&temp);
        printf("%d ",temp);
    }
    QueueEmpty(testqueue)?printf("\nTrue\n"):printf("\nFalse\n");
    printf("\n");

    //获取队首数据
    GetHead(testqueue,&temp);
    printf("%d\n\n",temp);

    //获取队列长度
    int len;
    len = QueueLength(testqueue);
    printf("%d\n\n",len);

    //清除一个队列
    ClearQueue(testqueue);
    len = QueueLength(testqueue);
    printf("%d\n\n",len);

    //销毁一个队列
    testqueue = DestroyQueue(testqueue);
    len = QueueLength(testqueue);
    printf("%d\n\n",len);

    return 0;
}