经典算法题每日演练——第十九题 双端队列
???? 話說大學(xué)的時(shí)候老師說妹子比工作重要~,工作可以再換,妹子這個(gè)。。。所以。。。這兩個(gè)月也就一直忙著Fall in love,嗨,慢慢調(diào)整心態(tài)吧,
這篇就選一個(gè)簡單的數(shù)據(jù)結(jié)構(gòu)聊一聊,話說有很多數(shù)據(jù)結(jié)構(gòu)都在玩組合拳,比如說:塊狀鏈表,塊狀數(shù)組,當(dāng)然還有本篇的雙端隊(duì)列,是的,它就是
棧和隊(duì)列的組合體。
一:概念
?????我們知道普通隊(duì)列是限制級的一端進(jìn),另一端出的FIFO形式,棧是一端進(jìn)出的LIFO形式,而雙端隊(duì)列就沒有這樣的限制級,也就是我們可以在
隊(duì)列兩端進(jìn)行插入或者刪除操作。
二:編碼
1:定義結(jié)構(gòu)體
????通常情況下,隊(duì)列的內(nèi)部都是采用數(shù)組來實(shí)現(xiàn),而且?guī)в袃蓚€(gè)指針head和tail來指向數(shù)組的區(qū)間段,為了充分利用數(shù)組空間,我們也會用%來實(shí)
現(xiàn)邏輯上的循環(huán)數(shù)組,如下圖。
1 public class MyQueue 2 { 3 public int head; 4 5 public int tail; 6 7 public int maxSize; 8 9 public int size; 10 11 public T[] list; 12 13 public MyQueue() 14 { 15 head = tail = size = 0; 16 maxSize = 3; 17 list = new T[maxSize]; 18 } 19 }這里有一個(gè)注意的細(xì)節(jié)就是“size字段“,它是為了方便統(tǒng)計(jì)隊(duì)列是否為滿或者隊(duì)列是否為空。
2:隊(duì)尾入隊(duì)
????剛才也說了,雙端隊(duì)列是可以在隊(duì)列的兩端進(jìn)行插入和刪除的,要注意的是我們用head和tail指針的時(shí)候,tail指針是指向元素的下一個(gè)位置,
而head指針是指向當(dāng)前元素,所以我們可以從tail端push數(shù)據(jù)的時(shí)候只要”順時(shí)針“下移一個(gè)位置即可。
1 /// <summary> 2 /// 隊(duì)尾入隊(duì) 3 /// </summary> 4 /// <param name="t"></param> 5 /// <returns></returns> 6 public bool Push_Tail(T t) 7 { 8 //判斷隊(duì)列是否已滿 9 if (myQueue.size == myQueue.list.Length) 10 return false; 11 12 myQueue.list[myQueue.tail] = t; 13 14 //順時(shí)針旋轉(zhuǎn) 15 myQueue.tail = (myQueue.tail + 1) % myQueue.maxSize; 16 17 myQueue.size++; 18 19 return true; 20 }
3:隊(duì)尾出隊(duì)
????和隊(duì)尾入隊(duì)一樣,我們只要將tail指針”逆時(shí)針“下移一個(gè)位置,當(dāng)然有一個(gè)細(xì)節(jié)需要注意,就是tail指針有存在負(fù)值的情況,畢竟我們是做”--操作“的,
所以需要tail+maxSize,即:myQueue.tail = (--myQueue.tail + myQueue.maxSize) % myQueue.maxSize;
1 /// <summary> 2 /// 隊(duì)尾出隊(duì) 3 /// </summary> 4 /// <param name="edges"></param> 5 /// <param name="t"></param> 6 public T Pop_Tail() 7 { 8 //判斷隊(duì)列是否已空 9 if (myQueue.size == 0) 10 return default(T); 11 12 //逆時(shí)針旋轉(zhuǎn)(防止負(fù)數(shù)) 13 myQueue.tail = (--myQueue.tail + myQueue.maxSize) % myQueue.maxSize; 14 15 var temp = myQueue.list[myQueue.tail]; 16 17 //賦予空值 18 myQueue.list[myQueue.tail] = default(T); 19 20 myQueue.size--; 21 22 return temp; 23 }4:隊(duì)首入隊(duì)
????從head端來說,我們push數(shù)據(jù)的時(shí)候是head指針“逆時(shí)針”旋轉(zhuǎn),要注意的是同樣要防止負(fù)數(shù)的產(chǎn)生,并且head指針是指向當(dāng)前元素。
1 /// <summary> 2 /// 隊(duì)首入隊(duì) 3 /// </summary> 4 /// <param name="t"></param> 5 /// <returns></returns> 6 public bool Push_Head(T t) 7 { 8 //判斷隊(duì)列是否已滿 9 if (myQueue.size == myQueue.list.Length) 10 return false; 11 12 //逆時(shí)針旋轉(zhuǎn)(防止負(fù)數(shù)產(chǎn)生) 13 myQueue.head = (--myQueue.head + myQueue.maxSize) % myQueue.maxSize; 14 15 //賦予元素 16 myQueue.list[myQueue.head] = t; 17 18 myQueue.size++; 19 20 return true; 21 }5:隊(duì)首出隊(duì)
????說到這個(gè)方法,我想大家應(yīng)該都懂了雙端隊(duì)列的大概流程了,這個(gè)方法我也不用贅敘了。
1 /// <summary> 2 /// 隊(duì)首出隊(duì) 3 /// </summary> 4 /// <param name="edges"></param> 5 /// <param name="t"></param> 6 public T Pop_Head() 7 { 8 //判斷隊(duì)列是否已空 9 if (myQueue.size == 0) 10 return default(T); 11 12 //獲取隊(duì)首元素 13 var temp = myQueue.list[myQueue.head]; 14 15 //原來單位的值賦默認(rèn)值 16 myQueue.list[myQueue.head] = default(T); 17 18 //順時(shí)針旋轉(zhuǎn) 19 myQueue.head = (myQueue.head + 1) % myQueue.maxSize; 20 21 myQueue.size--; 22 23 return temp; 24 }
從上面的四個(gè)方法可以看出:
當(dāng)我們只使用Push_Tail和Pop_Tail的話,那它就是棧。
當(dāng)我們只使用Push_Tail和Pop_Head的話,那它就是隊(duì)列。
最后是全部代碼:
View Code 1 using System.Net; 2 using System; 3 using System.IO; 4 using System.Collections.Generic; 5 using System.Text; 6 using System.Drawing; 7 using System.Drawing.Imaging; 8 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 DoubleQueue<int> queue = new DoubleQueue<int>(); 14 15 queue.Push_Tail(10); 16 queue.Push_Tail(20); 17 queue.Push_Tail(30); 18 19 queue.Pop_Tail(); 20 queue.Pop_Tail(); 21 queue.Pop_Tail(); 22 23 queue.Push_Tail(10); 24 queue.Push_Head(20); 25 queue.Push_Head(30); 26 queue.Push_Head(30); 27 28 queue.Pop_Tail(); 29 queue.Pop_Tail(); 30 queue.Pop_Head(); 31 32 queue.Push_Head(40); 33 queue.Push_Tail(50); 34 queue.Push_Tail(60); 35 } 36 } 37 38 /// <summary> 39 /// 雙端隊(duì)列 40 /// </summary> 41 public class DoubleQueue<T> 42 { 43 public class MyQueue 44 { 45 public int head; 46 47 public int tail; 48 49 public int maxSize; 50 51 public int size; 52 53 public T[] list; 54 55 public MyQueue() 56 { 57 head = tail = size = 0; 58 maxSize = 3; 59 list = new T[maxSize]; 60 } 61 } 62 63 MyQueue myQueue = new MyQueue(); 64 65 /// <summary> 66 /// 隊(duì)尾入隊(duì) 67 /// </summary> 68 /// <param name="t"></param> 69 /// <returns></returns> 70 public bool Push_Tail(T t) 71 { 72 //判斷隊(duì)列是否已滿 73 if (myQueue.size == myQueue.list.Length) 74 return false; 75 76 myQueue.list[myQueue.tail] = t; 77 78 //順時(shí)針旋轉(zhuǎn) 79 myQueue.tail = (myQueue.tail + 1) % myQueue.maxSize; 80 81 myQueue.size++; 82 83 return true; 84 } 85 86 /// <summary> 87 /// 隊(duì)尾出隊(duì) 88 /// </summary> 89 /// <param name="edges"></param> 90 /// <param name="t"></param> 91 public T Pop_Tail() 92 { 93 //判斷隊(duì)列是否已空 94 if (myQueue.size == 0) 95 return default(T); 96 97 //逆時(shí)針旋轉(zhuǎn)(防止負(fù)數(shù)) 98 myQueue.tail = (--myQueue.tail + myQueue.maxSize) % myQueue.maxSize; 99 100 var temp = myQueue.list[myQueue.tail]; 101 102 //賦予空值 103 myQueue.list[myQueue.tail] = default(T); 104 105 myQueue.size--; 106 107 return temp; 108 } 109 110 /// <summary> 111 /// 隊(duì)首入隊(duì) 112 /// </summary> 113 /// <param name="t"></param> 114 /// <returns></returns> 115 public bool Push_Head(T t) 116 { 117 //判斷隊(duì)列是否已滿 118 if (myQueue.size == myQueue.list.Length) 119 return false; 120 121 //逆時(shí)針旋轉(zhuǎn)(防止負(fù)數(shù)產(chǎn)生) 122 myQueue.head = (--myQueue.head + myQueue.maxSize) % myQueue.maxSize; 123 124 //賦予元素 125 myQueue.list[myQueue.head] = t; 126 127 myQueue.size++; 128 129 return true; 130 } 131 132 /// <summary> 133 /// 隊(duì)首出隊(duì) 134 /// </summary> 135 /// <param name="edges"></param> 136 /// <param name="t"></param> 137 public T Pop_Head() 138 { 139 //判斷隊(duì)列是否已空 140 if (myQueue.size == 0) 141 return default(T); 142 143 //獲取隊(duì)首元素 144 var temp = myQueue.list[myQueue.head]; 145 146 //原來單位的值賦默認(rèn)值 147 myQueue.list[myQueue.head] = default(T); 148 149 //順時(shí)針旋轉(zhuǎn) 150 myQueue.head = (myQueue.head + 1) % myQueue.maxSize; 151 152 myQueue.size--; 153 154 return temp; 155 } 156 }?
posted on 2015-01-16 11:47 NET未來之路 閱讀(...) 評論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/lonelyxmas/p/4228234.html
總結(jié)
以上是生活随笔為你收集整理的经典算法题每日演练——第十九题 双端队列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 子查询二(在HAVING子句中使用子查询
- 下一篇: BlueMind 3.0.17 发布,消