<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          棧和隊列互相實(shí)現(xiàn),一文弄懂它們的關(guān)系

          共 4595字,需瀏覽 10分鐘

           ·

          2021-03-01 15:40

          前言

          棧和隊列是比較基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)。無論在工作中,還是在面試中,棧和隊列都用的比較多。在計算機(jī)的世界,你會看到隊列和棧,無處不在。


          棧:一個先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)

          隊列:一個先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)


          棧和隊列這兩種數(shù)據(jù)結(jié)構(gòu),同時也存在某種聯(lián)系。用??梢詫?shí)現(xiàn)隊列,用隊列也可以實(shí)現(xiàn)棧。



          海邊風(fēng)景不錯,欣賞一下風(fēng)景,下面開始步入正題。學(xué)完這篇,咱們再接著看風(fēng)景。


          兩個棧實(shí)現(xiàn)一個隊列

          思路:讓數(shù)據(jù)入stack1,然后棧stack1中的數(shù)據(jù)出棧并入到棧stack2,然后出stack2。

          代碼如下:

          type CQueue struct {
              stack1, stack2 *list.List
          }

          //構(gòu)造函數(shù)    
          func Constructor() CQueue {
               return CQueue{
                  stack1: list.New(),
                  stack2: list.New(),
              }
          }
              
          //尾部插入
          func (this *CQueue) AppendTail(value int)  {
              this.stack1.PushBack(value)
          }

          //頭部刪除,back函數(shù)返回其list最尾部的值
          func (this *CQueue) DeleteHead() int {
              //如果第二個棧為空
              if this.stack2.Len() == 0 {
                  for this.stack1.Len() > 0 {
                      this.stack2.PushBack(this.stack1.Remove(this.stack1.Back()))
                  }
              }
              if this.stack2.Len() != 0 {
                  e := this.stack2.Back()
                  this.stack2.Remove(e)
                  return e.Value.(int)
              }
              return -1
          }


          先調(diào)用 AppendTail 函數(shù)將所有元素插入 stack1,在調(diào)用 DeleteHead 函數(shù)將 stack1 中的元素轉(zhuǎn)移到 stack2 中,再將元素再出棧。

          再調(diào)用 DeleteHead 時,先判斷 statck2 是否為空,為空則將 stack1 元素移動到 stack2 中,然后將 stack2 中的棧頂元素保存,并彈棧。


          兩個隊列實(shí)現(xiàn)一個棧

          思路:兩個隊列實(shí)現(xiàn)一個棧,使用了隊列交換的思想。

          代碼如下:

          type MyStack struct {
              queue1, queue2 []int
          }

          //構(gòu)造函數(shù)
          func Constructor() (s MyStack) {
              
          return
          }

          func (s *MyStack) Push(x int) {
              s.queue2 = 
          append(s.queue2, x)
              
          for len(s.queue1) > 0 {
                  s.queue2 = 
          append(s.queue2, s.queue1[0])
                  s.queue1 = s.queue1[
          1:]
              }
              s.queue1, s.queue2 = s.queue2, s.queue1
          }

          func (s *MyStack) Pop() int {
              v := s.queue1[
          0]
              s.queue1 = s.queue1[
          1:]
              
          return v
          }

          func (s *MyStack) Top() int {
              
          return s.queue1[0]
          }

          func (s *MyStack) Empty() bool {
              
          return len(s.queue1) == 0
          }


          先將元素入對到 queue2,此時 queue1 為0,交換 queue2 和 queue1。此時 queue2 為0,queue1 中有1個元素。


          再執(zhí)行push操作時,len(queue1) > 0,此時再把 queue1 中的元素插入queue2 的尾部,然后將 queue2 和 queue1 進(jìn)行交換。

          此時相當(dāng)于,插入 queue2 的兩個元素的位置發(fā)生了交換并保存在 queue1中。最后將 queue1 中的元素出隊,這樣就可以保證后插入的元素先出。


          不斷執(zhí)行 push 操作就行。

            

          一個隊列實(shí)現(xiàn)一個棧

          思路:使用一個隊列時,將當(dāng)前插入元素前面的所有元素,先出隊再入隊即可。

          代碼如下:

          type MyStack struct {
              queue []int
          }

          func Constructor() (s MyStack) {
              return
          }

          func (s *MyStack) Push(x int) {
              n := len(s.queue)
              s.queue = append(s.queue, x)
              for ; n > 0; n-- {
                  s.queue = append(s.queue, s.queue[0])
                  s.queue = s.queue[1:]
              }
          }

          func (s *MyStack) Pop() int {
              v := s.queue[0]
              s.queue = s.queue[1:]
              return v
          }

          func (s *MyStack) Top() int {
              return s.queue[0]
          }

          func (s *MyStack) Empty() bool {
              return len(s.queue) == 0
          }


          每次執(zhí)行 push 操作,如果queue存在元素,則將新插入元素前的所有元素出隊,然后依次進(jìn)隊。這樣新插入的元素就在隊首了。


          絮叨

          棧和隊列作為基礎(chǔ)的數(shù)據(jù),大家務(wù)必掌握其性質(zhì)和功能,知道它們之間的某種依存關(guān)系,才能靈活運(yùn)用。

          上面的算法雖然很簡單,但是思路很巧妙,還有其他解法,大家也可仔細(xì)研究,必有收獲。有本數(shù)據(jù)結(jié)構(gòu)的書<<大話數(shù)據(jù)結(jié)構(gòu)>>推薦給大家。



          點(diǎn)擊關(guān)注公眾號,領(lǐng)取學(xué)習(xí)資料

          瀏覽 30
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黑逼操逼| 操北条麻妃| 91AV视频播放 | 人人看人人做 | 内射网|