zoukankan      html  css  js  c++  java
  • 第三十七课 队列的概念及实现(下)

     

    添加LinkQueue.h文件:

     1 #ifndef LINKQUEUE_H
     2 #define LINKQUEUE_H
     3 
     4 #include "Queue.h"
     5 #include "LinkList.h"
     6 #include "Exception.h"
     7 
     8 namespace DTLib
     9 {
    10 
    11 template < typename T >
    12 class LinkQueue : public Queue<T>
    13 {
    14 protected:
    15     LinkList<T> m_list;
    16 public:
    17     LinkQueue()
    18     {
    19 
    20     }
    21 
    22     void add(const T& e)  // O(n)
    23     {
    24        m_list.insert(e);
    25     }
    26 
    27     void remove()  // O(1)
    28     {
    29         if( m_list.length() > 0 )
    30         {
    31             m_list.remove(0);
    32         }
    33         else
    34         {
    35             THROW_EXCEPTION(InvalidOperationException, "No element in current queue...");
    36         }
    37     }
    38 
    39     T front() const  // O(1)
    40     {
    41         if( m_list.length() > 0 )
    42         {
    43             return m_list.get(0);
    44         }
    45         else
    46         {
    47             THROW_EXCEPTION(InvalidOperationException, "No element in current queue...");
    48         }
    49     }
    50 
    51     void clear()   // O(n)
    52     {
    53         m_list.clear();
    54     }
    55 
    56     int length() const   // O(1)
    57     {
    58         return m_list.length();
    59     }
    60 
    61     ~LinkQueue()
    62     {
    63         clear();
    64     }
    65 };
    66 
    67 }
    68 
    69 #endif // LINKQUEUE_H

    测试程序如下:

     1 #include <iostream>
     2 #include "LinkQueue.h"
     3 
     4 using namespace std;
     5 using namespace DTLib;
     6 
     7 
     8 int main()
     9 {
    10     LinkQueue<int> lq;
    11 
    12     for(int i = 0; i < 5; i++)
    13     {
    14         lq.add(i);
    15     }
    16 
    17     while( lq.length() > 0 )
    18     {
    19         cout << lq.front() << endl;
    20 
    21         lq.remove();
    22     }
    23 
    24     return 0;
    25 }

    结果如下:

     用LinkList实现链式队列时,插入操作的时间复杂度为O(n),这是很低效的。

     修改LinkQueue.h:

      1 #ifndef LINKQUEUE_H
      2 #define LINKQUEUE_H
      3 
      4 #include "Queue.h"
      5 #include "LinuxList.h"
      6 #include "Exception.h"
      7 
      8 namespace DTLib
      9 {
     10 
     11 template < typename T >
     12 class LinkQueue : public Queue<T>
     13 {
     14 protected:
     15     struct Node : public Object
     16     {
     17         list_head head;
     18         T value;
     19     };
     20 
     21     list_head m_header;
     22     int m_length;
     23 
     24 public:
     25     LinkQueue()   // O(1)
     26     {
     27         m_length = 0;
     28 
     29         INIT_LIST_HEAD(&m_header);
     30     }
     31 
     32     void add(const T& e)  // O(1)
     33     {
     34        Node* node = new Node();
     35 
     36        if( node != NULL )
     37        {
     38            node->value = e;
     39 
     40            list_add_tail(&node->head, &m_header); // O(1)
     41 
     42            m_length++;
     43        }
     44        else
     45        {
     46            THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create Node object...");
     47        }
     48     }
     49 
     50     void remove()  // O(1)
     51     {
     52         if( m_length > 0 )
     53         {
     54             list_head* toDel = m_header.next;
     55 
     56             list_del(toDel);  // O(1)
     57 
     58             m_length--;
     59 
     60             delete list_entry(toDel, Node, head);
     61         }
     62         else
     63         {
     64             THROW_EXCEPTION(InvalidOperationException, "No element in current queue...");
     65         }
     66     }
     67 
     68     T front() const  // O(1)
     69     {
     70         if( m_length > 0 )
     71         {
     72             return list_entry(m_header.next, Node, head)->value;
     73         }
     74         else
     75         {
     76             THROW_EXCEPTION(InvalidOperationException, "No element in current queue...");
     77         }
     78     }
     79 
     80     void clear()   // O(n)
     81     {
     82         while ( m_length > 0 )
     83         {
     84             remove();
     85         }
     86     }
     87 
     88     int length() const   // O(1)
     89     {
     90         return m_length;
     91     }
     92 
     93     ~LinkQueue()
     94     {
     95         clear();
     96     }
     97 };
     98 
     99 }
    100 
    101 #endif // LINKQUEUE_H

    如队列的操作的时间复杂度变成了O(1)。

    测试程序如下:

     1 #include <iostream>
     2 #include "LinkQueue.h"
     3 
     4 using namespace std;
     5 using namespace DTLib;
     6 
     7 
     8 int main()
     9 {
    10     LinkQueue<int> lq;
    11 
    12     for(int i = 0; i < 5; i++)
    13     {
    14         lq.add(i);
    15     }
    16 
    17     while( lq.length() > 0 )
    18     {
    19         cout << lq.front() << endl;
    20 
    21         lq.remove();
    22     }
    23 
    24     return 0;
    25 }

    结果如下:

    测试程序2:

     1 #include <iostream>
     2 #include "LinkQueue.h"
     3 #include "StaticQueue.h"
     4 
     5 using namespace std;
     6 using namespace DTLib;
     7 
     8 class Test : public Object
     9 {
    10 public:
    11     Test()
    12     {
    13         cout << "Test()" << endl;
    14     }
    15 
    16     ~Test()
    17     {
    18         cout << "~Test()" << endl;
    19     }
    20 };
    21 
    22 int main()
    23 {
    24     LinkQueue<Test> lq;
    25     StaticQueue<Test, 10> queue;
    26 
    27     for(int i = 0; i < 5; i++)
    28     {
    29         //lq.add(i);
    30     }
    31 
    32     while( lq.length() > 0 )
    33     {
    34         //cout << lq.front() << endl;
    35 
    36         lq.remove();
    37     }
    38 
    39     return 0;
    40 }

    结果如下:

    这体现了顺序队列的缺陷。而链式队列不存在这个问题。

    小结:

  • 相关阅读:
    Linux统计文件个数
    python string与list互转
    Python中请使用isinstance()判断变量类型
    xpath提取多个标签下的text
    内存盘
    Watchdog
    渗透测试
    GMT与UTC简介
    ASN.1(抽象语法标记)
    Linux nmap
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9657533.html
Copyright © 2011-2022 走看看