做网站后端的是什么部门,苏州城乡住房建设厅网站,电商外贸有什么平台,网谱网络科技还是先放这张图#xff0c;以便对比和理解#xff1a; 队列是限制在两端进行插入操作和删除操作的线性表#xff0c;允许进行存入操作的一端称为“队尾”#xff0c;允许进行删除操作的一端称为“队头”。当线性表中没有元素时#xff0c;称为“空队”。特点#xff1a;先… 还是先放这张图以便对比和理解 队列是限制在两端进行插入操作和删除操作的线性表允许进行存入操作的一端称为“队尾”允许进行删除操作的一端称为“队头”。当线性表中没有元素时称为“空队”。特点先进先出FIFO。 一、顺序队列建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间并设置两个指针进行管理。一个是队头指针front它指向队头元素另一个是队尾指针rear它指向下一个入队元素的存储位置如图所示每次在队尾插入一个元素是rear增1每次哎队头删除一个元素时front增1。随着插入和删除操作的进行队列元素的个数不断变化队列所占的存储空间也在为队列结构所分配的连续空间中移动。当frontrear时队列中没有任何元素称为空队列。当rear增加到指向分配的连续空间之外时队列无法再插入新元素但这时往往还有大量可用空间未被占用这些空间是已经出队的队列元素曾经占用过得存储单元。 在实际使用队列时为了使队列空间能重复使用往往对队列的使用方法稍加改进无论插入或删除一旦rear指针增1或front指针增1 时超出了所分配的队列空间就让它指向这片连续空间的起始位置。自己真从NMaxSize增1变到0可用取余运算rear%N和front%N来实现。这实际上是把队列空间想象成一个环形空间环形空间中的存储单元循环使用用这种方法管理的队列也就称为循环队列。 在循环队列中当队列为空时有frontrear而当所有队列空间全占满时也有frontrear。为了区别这两种情况规定循环队列最多只能有MaxSize-1个队列元素当循环队列中只剩下一个空存储单元时队列就已经满了。因此队列判空的条件时frontrear而队列判满的条件时frontrear1%MaxSize。 总结 1、队头指针front指向队头元素的位置的前一个位置。即指向预留的位置 2、队尾指针rear指向队尾元素的位置 3、入队 rear (rear 1) % N (maxsize)然后元素放入队尾rear所指向的位置 4、出队 front (front 1) % N然后取出队头指针front所指向的元素 5、队空 front rear; 6、队满 (rear 1) % N front, N为数组的元素个数 7、为了区别空队和满队满队元素个数比数组元素个数少一个。 下面是顺序队列的运算 顺序队列也是顺序表的一种具有顺序表同样的存储结构由数组定义配合使用数组下表表示的队头指针和队尾完成各种操作 [cpp] view plaincopy #define N 64 //队列中数据元素的数据类型 typedef int data_t; typedef struct { data_t data[N]; //用数组作为队列的储存空间 int front,rear; //指示队头位置和队尾位置的指针 }sequeue_t; 1、创建空队列 [cpp] view plaincopy sequeue_t *CreateEmptySequeue() { sequeue_t *queue; queue (sequeue_t *)malloc(sizeof(sequeue_t)); if (NULL queue) return NULL; queue-front queue-rear 0; return queue; } 2、摧毁一个队列 [cpp] view plaincopy void DestroySequeue(sequeue_t *queue) { if (NULL ! queue) { free(queue); } } 3、判断一个队列是否为空 [cpp] view plaincopy int EmptySequeue(sequeue_t *queue) { if (NULL queue) return -1; return (queue-front queue-rear ? 1 : 0); } 4、判断一个队列是否为满 [cpp] view plaincopy int FullSequeue(sequeue_t *queue) { if (NULL queue) return -1; return ((queue-rear 1) % N queue-front ? 1 : 0); } 5、清空一个队列 [cpp] view plaincopy void ClearSequeue(sequeue_t *queue) { if (NULL queue) return; queue-front queue-rear 0; return; } 6、入队 [cpp] view plaincopy int EnQueue(sequeue_t *queue, data_t x) { if (NULL queue) return - 1; if (1 FullSequeue(queue)) return -1; /* full */ queue-rear (queue-rear 1) % N; queue-data[queue-rear] x; return 0; } 7、出队 [cpp] view plaincopy int DeQueue(sequeue_t *queue, data_t *x) { if (NULL queue) return -1; if (1 EmptySequeue(queue)) return -1; /* empty */ queue-front (queue-front 1) % N; if (NULL ! x) { *x queue-data[queue-front]; } return 0; } 二、链式队列 用链表表示的队列简称为链队列如下图所示 一个链队列显然需要两个分别指示队头和队尾的指针(分别成为头指针和尾指针)才能唯一确定。这里和线性表的单链表一样为了操作方便起见我们也给队列添加一个头结点并令头指针指向头节点。由此空的链队列的判决条件为头指针和尾指针均指向头结点如下图所示 链队列的操作记为单链表的插入和删除操作的特殊情况插入操作在队尾进行删除操作在队头进行由队头指针和队尾指针控制队列的操作 [cpp] view plaincopy typedef int data_t; typedef struct node_t { data_t data; struct node_t *next; }linknode_t,*linklist_t; typedef struct { linklist_t front,rear; }linkqueue_t; 1、创建空队列 [cpp] view plaincopy linkqueue_t *CreateEmptyLinkqueue() { linkqueue_t *lp (linkqueue_t *)malloc(sizeof(linkqueue_t)); if(lp NULL) return; lp-front lp-rear (linknode_t *)malloc(sizeof(linknode_t)); if(lp-front NULL) return; lp-front-next NULL; return lp; } 2、摧毁一个链队列 [cpp] view plaincopy void DestroyLinkqueue(linkqueue_t *queue) { if(queue ! NULL) { ClearLinkqueue(queue); free(queue); } } 3、清空一个链队列 [cpp] view plaincopy void ClearLinkqueue(linkqueue_t *queue) { linknode_t *qnode; while(q-front) { qnode queue-front; queue-front qnode-next; free(qnode); } queue-rear NULL;} 4、判断链队列为空 [cpp] view plaincopy int EmptyLinkqueue(linkqueue_t *queue) { if(queue NULL) return -1; return(queue-front queue-rear ? 1 : 0); } 5、入队 [cpp] view plaincopy int EnQueue(linkqueue_t *queue,data_t x) { linknode_t *node_new; if(queue NULL) return -1; node_new (linknode_t *)malloc(sizeof(linknode_t)); if(node_new NULL) return -1; node_new-data x; node_new-next NULL; if(queue-front-next NULL) { queue-front-next queue-rear node_new; } else { queue-rear-next node_new; queue-rear node_new; } return 0; } 6、出队 [cpp] view plaincopy int DeQueue(linkqueue_t *queue,data_t *x) { linknode_t *node_remove; if(queue NULL || queue-front-next NULL) return -1; node_remove queue-front-next; queue-front-next node_remove-next; if(x ! NULL) *x node_remove-data; free(node_remove); return 0; }