“这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战”
关注我,以下内容持续更新
动态队列的介绍
队列和栈一样是一种受限的线性表,队列它是“先进先出”的存储结构,栈是后进先出的数据结构。 栈是只能在同一位置增加或删减元素,队列只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,我们分别称之为队头和队尾。
队列分为动态队列和静态队列两种。动态队列用链表实现,动态队列易于实现。静态队列用数组实现,静态队列通常都必须是循环队列。用链表实现队列,分别在表头和表尾进行入队和出队,当然也可以链表头出队,链表尾入队,两种方式都可以保证先进先出的特性,链表不用考虑队列的最大容量,只需要考虑链表是否为空,而用数组实现队列需要判断队列是否为空和队列是否已满.
下面我们来看一下用单链表实现队列,本篇文章选择用表头入队和表尾出队的方式
动态队列的结构
初始化队列,返回一个空链表的头结点,用 length 记录队列的长度,入队时length+1,出队时 length-1;
-
判空:该方法会传入初始化返回的头结点header,如果header.next == NULL,则队列为空
-
入队:该方法会传入一个header和数据data,先初始化一个新节点new:
LinkNode*new = [LinkNode new];new.data = data;,然后插入new:new.next = header.next; header.next = new;,并令length++; -
出队:该方法会传入初始化返回的头结点header,先判空,然后用 while 循环找出倒数第二个元素,如下:
while (current.next.next != NULL) {current = current.next;},然后把倒数第二个节点的下一个节点置空,current.next = NULL; -
查看队列的第一个元素:该方法会传入链表的头结点 header,先判空,如果不为空则返回
header.next.data -
输出队列的所有元素: 如果用 while 循环是逆序输出,如果想按插入顺序正序输出,有很多方案:
方案一:比如可以用数组实现,先用 while循环把每个元素加入到一个新数组,然后把数组逆序输出;
方案二:用while循环将元素逆序加入一个新的队列,然后将新队列逆序输出,逆序+逆序=正序
动态队列的完整代码
//LinkQueue.h 文件
@class LinkNode;
@interface LinkQueue : NSObject
/**队列的长度*/
@property (nonatomic,assign) int length;
-(LinkNode*)createQueue;
//队空
-(BOOL)isEmpty:(LinkNode*)header;
//入队
-(void)enqueue:(NSString*)data header:(LinkNode*)header;
//出队
-(NSString*)dequeue:(LinkNode*)header;
//查看头元素
-(NSString*)getFront:(LinkNode*)header;
//显示多有元素
-(void)showQueue:(LinkNode*)header;
@end
@interface LinkNode : NSObject
/**存放的真实数据,data可以是任意类型*/
@property (nonatomic,strong) NSString * data;
/**next 指针,指向下一个元素*/
@property (nonatomic,strong) LinkNode * next;
@end
//LinkQueue.m 文件
@implementation LinkQueue
//初始化,返回一个带有头结点的空链表
-(LinkNode*)createQueue{
LinkNode*header = [LinkNode new];
header.next = NULL;
return header;
}
//队空
-(BOOL)isEmpty:(LinkNode*)header{
return header.next == NULL;
}
//入队,链表头插入数据
-(void)enqueue:(NSString*)data header:(LinkNode*)header{
LinkNode*new = [LinkNode new];
new.data = data;
new.next = header.next;
header.next = new;
self.length++;
}
//出队,链表尾删除数据
-(NSString*)dequeue:(LinkNode*)header{
if ([self isEmpty:header]) {
printf("队列为空 \n");
return NULL;
}
LinkNode*current = header;
while (current.next.next != NULL) {//找到倒数第二个结点
current = current.next;
}
LinkNode*node = current.next;
current.next = NULL;
self.length--;
return node.data;
}
//查看头元素
-(NSString*)getFront:(LinkNode*)header{
if ([self isEmpty:header]) {
printf("队列为空 \n");
return NULL;
}
return header.next.data;
}
//顺序输出所有元素(借助数组)
-(void)showQueue:(LinkNode*)header{
if ([self isEmpty:header]) {
printf("队列为空 \n");
return;
}
NSMutableArray<NSString*>*arr = [NSMutableArray array];
LinkNode*current = header;
while (current.next != NULL) {
current = current.next;
[arr addObject:current.data];
}
for (int i = (int)arr.count - 1; i>=0; i--) {
printf("%s-->",arr[i].UTF8String);
}
printf("\n");
}
//顺序输出所有元素
//用while循环将元素逆序加入一个新的队列,然后将新队列逆序输出,逆序+逆序=正序
-(void)showQueue2:(LinkNode*)header{
if ([self isEmpty:header]) {
printf("队列为空 \n");
return;
}
LinkQueue*queue = [LinkQueue new];
LinkNode*header_new = [queue createQueue];
LinkNode*current = header;
while (current.next != NULL) {
current = current.next;
[queue enqueue:current.data header:header_new];
}
LinkNode*current_new = header_new;
while (current_new.next != NULL) {
current_new = current_new.next;
printf("%s-->",current_new.data.UTF8String);
}
printf("\n");
}
//输出所有元素(这是逆序输出)
/*
-(void)showQueue3:(LinkNode*)header{
if ([self isEmpty:header]) {
printf("队列为空 \n");
return;
}
LinkNode*current = header;
while (current.next != NULL) {
current = current.next;
printf("%s-->",current.data.UTF8String);
}
printf("\n");
}
*/
@end
@implementation LinkNode
@end
// 测试队列是否正确
-(void)LinkQueueCase{
LinkQueue*queue = [LinkQueue new];
LinkNode*header = [queue createQueue];
//打印队列
[queue showQueue:header];
//入队
[queue enqueue:@"a" header:header];
[queue enqueue:@"b" header:header];
//打印队列
[queue showQueue:header];
//出队
NSString*data1 = [queue dequeue:header];
printf("出队:%s \n",data1.UTF8String);
//打印队列
[queue showQueue:header];
//继续出队
NSString*data2 = [queue dequeue:header];
printf("出队:%s \n",data2.UTF8String);
//继续出队
NSString*data3 = [queue dequeue:header];
printf("出队:%s \n",data3.UTF8String);
//打印队列
[queue showQueue:header];
}
关注我
如果觉得我写的不错,请点个赞 关注我 您的支持是我更文最大的动力!