;队列之链表实现 算法详解及算法演示请参考 《队列【讲解】》及《队列【演示程序说明及下载】》
null equ 0
true equ 1
false equ 0
data segment
Copyright db 'Copyright (c) 2007 www.asmedu.net','$';版权声明字符串
;队列元素定义/队列头结点
node_Def dw 0 ;data element
data_Len equ $ - node_Def ;the length of data element
next_OA dw 0 ;pointer element OA
next_OA_Len equ $ - next_OA ;the length OA
next_SA dw 0 ;pointer element SA
next_SA_Len equ $ - next_SA ;the length of SA
node_Len equ $ - node_Def ;the length of the whole node_Def
;队列 一个头指针,一个尾指针
pointer_Len equ next_SA_Len + next_OA_Len
head_Node_Len equ pointer_Len
rear_Node_len equ pointer_Len
head db head_Node_Len dup(0)
rear db rear_Node_Len dup(0)
queue_Len dw 0
queue_Max_Len equ 20 ;可自定义
data ends
code segment
start:
;相关准备工作
;算法调用
call create_Queue;创建队列
call entry_Queue ;入队
call peek_Queue ;取队头元素
call out_Queue ;出队
call clear_Queue ;清空队列
call exit ;退出程序
exit:
call cls
mov ax,4c00h
int 21h
;------------------------------------------------------------------------------------------
;-----------队列操作算法-------------------------------------------------------------------
;--1 equ success or true ------------------------------------------------------------------
;--0 equ failure or false------------------------------------------------------------------
;--返回值由 BX 携带------------------------------------------------------------------------
init_Queue:;初始化队列 (bx) = 0 失败 ,(bx) = 1 成功
push ax;保护现场
push ds
mov ax,data
mov ds,ax
mov bx,offset head;将head和rear指向一个空Node置空
mov word ptr [bx],null
mov word ptr [bx+next_OA_Len],null
mov bx,offset rear
mov word ptr [bx],null
mov word ptr [bx+next_OA_Len],null
mov bx,true
jmp short init_Queue_Ret
init_Queue_Failure:
sub bx,bx
init_Queue_Ret:
pop ds
pop ax;恢复现场
ret
clear_Queue:;清除队列;(bx) = 1 清除成功 ,(bx) = 0清除失败
push ax;保护现场
delete_All_Nodes:;依次删除队列中的每一个结点,最后使队首指针为空,同时置队尾指针为空
mov bx,null
call out_Queue
cmp bx,false
jne delete_All_Nodes
mov bx,true
jmp short clear_Queue_Ret
clear_Queue_Failure:
sub bx,bx
clear_Queue_Ret:
pop ax;恢复现场
ret
entry_Queue:;新节点入队(ax) = new_Node.data;(bx) = 0 入队失败 ,(bx) = 1 成功
push ax;保护现场
push cx
push dx
push ds
push es
push ax
mov bx,offset queue_Len
cmp word ptr [bx],queue_Max_Len
je entry_Queue_Failure
mov bx,node_Len;(bx) = 申请空间大小(节点大小)
call malloc_Memory
cmp bx,false
je entry_Queue_Failure;申请内存空间失败
mov ds,cx
mov bx,dx;cx:dx-->ds:bx新申请的节点空间的地址
pop ax
mov [bx],ax;数据存储进新的节点
mov word ptr [bx+data_Len],null
mov word ptr [bx+data_Len+next_OA_Len],null;new_Node.next = null
call empty_Queue
cmp bx,false
je only_Change_Rear
mov ax,data;
mov ds,ax
mov bx,offset head
mov [bx],dx
mov [bx+next_OA_Len],cx;head -> new_Node
mov ax,data
mov ds,ax
mov bx,offset rear
mov [bx],dx
mov [bx+next_OA_Len],cx;rear -> new_Node
jmp short entry_Queue_Success
only_Change_Rear:;只改变尾指针即可
mov ax,data
mov ds,ax
mov bx,offset rear
mov ax,[bx+next_OA_Len]
mov es,ax
mov bx,[bx]
mov es:[bx+data_Len],dx
mov es:[bx+data_Len+next_OA_Len],cx;rear.next --> new_Node
mov ax,data
mov ds,ax
mov bx,offset rear
mov [bx],dx
mov [bx+next_OA_Len],cx;rear -->new_Node
entry_Queue_Success:
mov bx,offset queue_Len;队列长度增加
add word ptr [bx],1;
mov bx,true
jmp short entry_Queue_Ret
entry_Queue_Failure:
pop ax
sub bx,bx
entry_Queue_Ret:
pop es;恢复现场
pop ds
pop dx
pop cx
pop ax
ret
out_Queue:;读取队首元素, (ax) = head->data ; head -> head.next;(bx) = 0 队列为空 ,读取失败 ,(bx) = 1读取成功
push cx;保护现场
push dx
push ds
call empty_Queue;若链队为空则停止出队操作
cmp bx,false
jne to_Out_Queue_Failure
jmp short go_Out
to_Out_Queue_Failure:
jmp out_Queue_Failure
go_Out:
mov ax,data
mov ds,ax
mov bx,offset head;取头指针所指节点首地址
mov cx,[bx+next_OA_Len];head->SA
mov bx,[bx];head->OA
mov ds,cx
mov ax,[bx]
push ax;暂存队头元素以便返回
mov word ptr [bx],null
mov dx,[bx+data_Len];使队首指针指向下一个结点
mov cx,[bx+data_Len+next_OA_Len]
mov ax,data
mov ds,ax
mov bx,offset head
mov [bx],dx
mov [bx+next_OA_Len],cx
call empty_Queue;若删除后链队为空,则需同时使队尾指针为空
cmp bx,false
je no_Empty_Queue
mov ax,data
mov ds,ax
mov bx,offset rear;使队尾指针为空
mov word ptr [bx],dx
mov word ptr [bx+next_OA_Len],cx
no_Empty_Queue:
mov ax,data
mov ds,ax
mov bx,offset queue_Len;队列长度减小
sub word ptr [bx],1
pop ax;return out data
mov bx,true
jmp short out_Queue_Ret
out_Queue_Failure:
sub bx,bx
out_Queue_Ret:
pop ds;恢复现场
pop dx
pop cx
ret
peek_Queue:;读取队首元素,不改变队列状态 (ax) = head->data;(bx) = 0 队列为空 ,读取失败 ,(bx) = 1读取成功
push cx;保护现场
push dx
push ds
call empty_Queue;若链队为空则停止运行
cmp bx,false
jne peek_Queue_Failure
mov ax,data
mov ds,ax
mov bx,offset head
mov cx,[bx+next_OA_Len]
mov bx,[bx]
mov ds,cx
mov ax,[bx];return out data
mov bx,true
jmp short peek_Queue_Ret
peek_Queue_Failure:
sub bx,bx
peek_Queue_Ret:
pop ds;恢复现场
pop dx
pop cx
ret
empty_Queue:;判断队列是否为空,判断队首或队尾任何一个指针为空即队列为空 (bx) = 1 空;(bx) = 0 非空
push ax
push ds
mov ax,data
mov ds,ax
mov bx,offset head;判断队首为空
mov ax,[bx]
add ax,[bx+next_OA_Len]
cmp ax,null
jne empty_Queue_Failure
mov bx,true;队列为空 返回 1
jmp short empty_Queue_Ret
empty_Queue_Failure:
sub bx,bx;队列非空返回 0
empty_Queue_Ret:
pop ds
pop ax
ret
full_Queue:;判队列是否已满 返回 (bx) = 1 满 ,(bx) = 0 未满
;保护现场
sub bx,bx;永远也不会满
;恢复现场
ret
malloc_Memory: ;申请内存空间 (bx) = 申请空间大小,返回 cx:申请空间段地址,dx:申请空间偏移地址 ,成功,(bx) = 0申请失败,
push ax
push ds
push bx;保存参数
mov ax,queue;查看是否有大于等于可申请空间中空余的内存空间
mov ds,ax
mov cx,ax;返回SA
mov bx,offset queue_Space_Alloc_Count
mov ax,[bx]
pop bx
push bx
push ax;保存当前已分配计数
add ax,bx ;计算分配后计数器值
mov bx,queue_Space_Max_Len;判断如此分配后是否超过内存空间限制
cmp ax,bx
ja malloc_Memory_Failure;超过限制,申请失败
pop dx;返回OA ---实际是分配空间计数器的当前值
mov bx,offset queue_Space_Alloc_Count
pop ax
push ax
add word ptr [bx],ax;计数器调整--增加
pop bx
jmp short malloc_Memory_Ret
malloc_Memory_Failure:
pop ax
pop bx
sub bx,bx
malloc_Memory_Ret:
pop ds
pop ax
ret
;------------------------------------------------------------------------------------------
;----算法定义完毕--------------------------------------------------------------------------
;------------------------------------------------------------------------------------------
code ends
queue segment ;队列放置内存空间,可自定义
queue_Space db 0fff0h dup(0)
queue_Space_Max_Len equ $-queue_Space
queue_Space_Alloc_Count dw 0;记录已经分配的内存数量
queue ends
end start
[07/09/21] |