第三十七课 队列的概念及实现(下)

 

添加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 }

结果如下:

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

小结:

猜你喜欢

转载自www.cnblogs.com/wanmeishenghuo/p/9657533.html