erlang 佇列(queue)模組
阿新 • • 發佈:2021-01-18
技術標籤:erlang
queue模組部分api說明
文章目錄
- queue:new -> {[], []}
- queue:is_queue -> boolean | badarg
- queue:is_empty -> boolean | badarg
- queue:len -> integer | badarg
- queue:to_list({In,Out}) -> list | badarg
- queue:from_list(L) -> queue | badarg
- queue:in(X, {In,Out})-> queue | badarg
- queue:in_r(X, Queue)-> queue | badarg
- queue:out({In,Out})
- queue:member(X, Queue) -> boolean | badarg
- queue:drop(Queue) -> queue | badarg
- queue:reverse(Queue) -> queue | badarg
- queue:join(Queue1, Queue2) -> queue | badarg
- 最後
queue:new -> {[], []}
新建一個佇列,返回兩個為空的列表組成的元組
queue:is_queue -> boolean | badarg
是否是佇列,通過判斷元組是否由兩個列表組成
queue:is_empty -> boolean | badarg
是否為空佇列,通過判斷兩個列表是否為空
queue:len -> integer | badarg
佇列長度,通過獲取兩個列表長度相加實現
queue:to_list({In,Out}) -> list | badarg
佇列轉為列表,由Out列表拼接反轉後的In列表實現
queue:from_list(L) -> queue | badarg
列表轉為佇列,呼叫了f2r
f2r([]) ->
{[],[]};
f2r([_]=F) ->
{F,[]};
f2r([X,Y] ) ->
{[Y],[X]};
f2r(List) ->
{FF,RR} = lists:split(length(List) div 2 + 1, List),
{lists:reverse(RR, []),FF}.
其中分幾種情況
1、列表為空,則返回空佇列
2、列表只有一個元素時放入In,兩個元素時,按序放入Out、In
3、元素數量>=3,則將列表根據列表長度進行分割,分割成In、Out列表
queue:in(X, {In,Out})-> queue | badarg
將元素放在佇列尾部,存元素X時將元素放進In列表中([X|In]),當Out為空時則將In替換Out,這樣效率會更高,因為佇列是先進先出的,當Out不是空列表取Out列表第一個元素即可
queue:in_r(X, Queue)-> queue | badarg
與queue:in類似,不過是將元素放在佇列頭部。關於從佇列中獲取元素還有get、get_r、peek、peek_r這幾個方法都是從佇列中獲取元素,但是不會返回新的佇列
queue:out({In,Out})
我在原始碼上加了註釋,由以下原始碼,很清晰的可以看出佇列是怎麼取出元素的
-spec out(Q1 :: queue(Item)) ->
{{value, Item}, Q2 :: queue(Item)} |
{empty, Q1 :: queue(Item)}.
out({[],[]}=Q) ->
{empty,Q};
out({[V],[]}) ->
{{value,V},{[],[]}};
out({[Y|In],[]}) ->
[V|Out] = lists:reverse(In, []), %% 反轉後下次取元素直接取Out的頭元素
{{value,V},{[Y],Out}};
out({In,[V]}) when is_list(In) -> %% 取完Out為空時,呼叫r2f(),作用是將In的一半元素截取出來反轉形成Out,下次取元素就很方便
{{value,V},r2f(In)};
out({In,[V|Out]}) when is_list(In) -> %% 直接從Out中取出頭元素,它一定是最早進去的
{{value,V},{In,Out}};
out(Q) ->
erlang:error(badarg, [Q]).
queue:out_r(Queue) 與queue:out類似,不過取出來的是尾部元素
queue:member(X, Queue) -> boolean | badarg
佇列是否包含此元素,通過判斷兩個列表是否包含此元素實現
queue:drop(Queue) -> queue | badarg
刪除佇列第一個元素並返回新的佇列
queue:drop_r(Queue) -> queue | badarg 則是刪除佇列最後一個元素並返回新的佇列
queue:reverse(Queue) -> queue | badarg
將佇列反轉,實現方式是Queue = {In, Out}, NewQueue = {Out, In}
queue:join(Queue1, Queue2) -> queue | badarg
合併兩個佇列
最後
如果需求是需要按照順序先進先出的取出資料,用佇列是很高效的