首页 > 代码库 > 数据结构(C实现)------- 顺序队列(非循环队列)

数据结构(C实现)------- 顺序队列(非循环队列)

         和栈相反,队列是一种先进先出的的线性表。它只允许在表的一端进行插入,而在另一端删除元素。这和我们日常生活中的队列是一致的,最早进入队列的元素最早离开。在队列中,允许插入的一端叫做队尾,允许删除的一端则稀烂为队头。

         顺序队列,即队列的顺序存储结构。由于队列的队头和队尾的位置均发生变化,因此在队列顺序存储结构中,除了用一组地址连续的存储单元依次存放从队头到队尾的元素之外,还需要附设两个指针front和rear指向队头和队尾元素。

        为了操作方便,在此约定:在非空队列中,队头指针front始终指向队头元素,而队尾rear始终指向队尾元素下一个位置。

      顺序队列的类型描述:        

//顺序队列的类型描述#define MAXSIZE 100typedef int ElemType;typedef struct{	ElemType *data;	int front,rear;}SqQueue;


      基本操作:

            1. 初始化顺序队列Init_SqQueue(SqQueue* Q):

//初始化顺序队列void Init_SqQueue(SqQueue* Q){    Q->data = http://www.mamicode.com/(SqQueue*)malloc(sizeof(SqQueue) * MAXSIZE);>

           2. 销毁顺序队列Destroy_SqQueue(SqQueue* Q)

//销毁顺序队列void Destroy_SqQueue(SqQueue* Q){	if(Q->data){		free(Q->data);		Q->front = Q->rear = 0;	}} 

           3. 清空顺序队列Clear_SqQueue(SqQueue* Q)

//清空顺序队列void Clear_SqQueue(SqQueue* Q){	Q->front = Q->rear = 0;}

          4. 判断顺序队列是否为空IsEmpty_SqQueue(SqQueue* Q)

//判断顺序队列是否为空int IsEmpty_SqQueue(SqQueue* Q){	if(Q->front == Q->rear)		return 1;	else{		return 0;	}}

         5. 判断顺序队列是否已满iSFull_SqQueue(SqQueue* Q)

//判断顺序队列是否已满int iSFull_SqQueue(SqQueue* Q){	if(Q->rear == MAXSIZE)		return 1;	else		return 0;}

         因为没有设置额外的指针,所以这里判断顺序队列是否已满,实际上是假溢出,并不是真的顺序队列满,原因:

         随着入队,出队的进行,整个队列会整体向后移动,这样就出现队尾指针已经移动到了最后,再有元素入队就会出现队满,即溢出,而事实上此时队中并未真正的满员,这种现象即称为“假溢出”。

         

         6.  求得顺序队列的长度GetLength_SqQueue(SqQueue* Q)

//求得顺序队列的长度int GetLength_SqQueue(SqQueue* Q){	return Q->rear - Q->front;}

        7. 取得顺序队列的的队头GetHead_SqQueue(SqQueue* Q,ElemType *x)

//取得顺序队列的的队头void GetHead_SqQueue(SqQueue* Q,ElemType *x){	if(IsEmpty_SqQueue(Q)){		printf("顺序队列空!\n");		exit(0);	}	else{		*x = Q->data[Q->front];	}}

         8. 取得顺序队列的的队尾GetRear_SqQueue(SqQueue* Q,ElemType *x)

//取得顺序队列的的队尾void GetRear_SqQueue(SqQueue* Q,ElemType *x){	if(IsEmpty_SqQueue(Q)){		printf("顺序队列空!\n");		exit(0);	}	else{		*x = Q->data[Q->rear - 1];	}}

        9. 入顺序队列En_SqQueue(SqQueue* Q,ElemType x)

//入顺序队列void En_SqQueue(SqQueue* Q,ElemType x){	Q->data[Q->rear] = x;	Q->rear++;}

       10. 出顺序队列De_SqQueue(SqQueue* Q,ElemType *x)

//出顺序队列void De_SqQueue(SqQueue* Q,ElemType *x){	if(IsEmpty_SqQueue(Q)){		printf("顺序队列空!\n");		exit(0);	}	else{		*x = Q->data[Q->front];		Q->front++;	}	}

       11. 打印顺序队列Print_SqQueue(SqQueue* Q)

//打印顺序队列void Print_SqQueue(SqQueue* Q){	int i = Q->front;	if(IsEmpty_SqQueue(Q)){		printf("顺序队列空!\n");		exit(0);	}	else{		while(i < Q->rear)			printf("%d\t",Q->data[i++]);			printf("\n");	}}

     

    说明:

          以上这种顺序队列会出现“假溢出”,随着入队,出队的进行,整个队列会整体向后移动,这样就出现队尾指针已经移动到了最后,再有元素入队就会出现队满,即溢出,而事实上此时队中并未真正的满员。

          为了能充分的利用空间,解决顺序队列的“假溢出”问题,可以采用两种方法:一种是将数据向前移动,让空的存储单元留在队尾;另一种是将顺序队列构造成一个环状的空间,即将队列的数据区data[0....MAXSIZE-1]看成头尾相接的循环结构,使得data[0]接在data[MAXSIZE-1]之后,这就是循环队列。







 

 

        

 

数据结构(C实现)------- 顺序队列(非循环队列)