linux内核队列数据结构,【数据结构】37_队列的概念及实现 (下)

顺序队列的问题

当数据元素为类类型,StaticQueue 的对象在创建时会多次调用元素类型的构造函数,影响效率!

文件:main.cpp

#include

#include "StaticQueue.h"

using namespace std;

using namespace DTLib;

class Test : public Object

{

public:

Test()

{

cout << "Test()" << endl;

}

~Test()

{

cout << "~Test()" << endl;

}

};

int main()

{

StaticQueue queue;

cout << "queue.length() = " << queue.length() << endl;

return 0;

}

输出:

Test()

Test()

Test()

Test()

Test()

queue.length() = 0

~Test()

~Test()

~Test()

~Test()

~Test()

队列的链式存储实现

bVbCRhx

链式队列的设计要点

类模板,抽象父类 Queue 的直接子类

在内部使用链式结构实现元素的存储

只在链表的头部和尾部进行操作

bVbCRhP

编程实验:基于 LinkList 的队列

文件:LinkQueue.h

#ifndef LINKQUEUE_H

#define LINKQUEUE_H

#include "Queue.h"

#include "LinkList.h"

#include "Exception.h"

namespace DTLib

{

template

class LinkQueue : public Queue

{

public:

LinkQueue() = default;

void add(const T &e) override // O(n)

{

m_list.insert(e);

}

void remove() override // O(1)

{

if (m_list.length() > 0)

{

m_list.remove(0);

}

else

{

THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current StaticQueue ...");

}

}

T front() const override // O(1)

{

if (m_list.length() > 0)

{

return m_list.get(0);

}

else

{

THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current StaticQueue ...");

}

}

void clear() override // O(n)

{

m_list.clear();

}

int length() const override // O(1)

{

return m_list.length();

}

~LinkQueue() // O(n)

{

clear();

}

protected:

LinkList m_list;

};

}

#endif // LINKQUEUE_H

文件:main.cpp

#include

#include "LinkQueue.h"

using namespace std;

using namespace DTLib;

class Test : public Object

{

public:

Test()

{

cout << "Test()" << endl;

}

~Test()

{

cout << "~Test()" << endl;

}

};

int main()

{

LinkQueue queue_t;

cout << "-----" << endl;

LinkQueue queue;

for (int i=0; i<5; ++i)

{

queue.add(i);

}

while (queue.length() > 0)

{

cout << queue.front() << endl;

queue.remove();

}

return 0;

}

输出:

-----

0

1

2

3

4

问题:使用 LinkList 类实现链表式队列是否合适?是否有更好的方案?

void add(const T &e) override // O(n)

{

m_list.insert(e);

}

每次插入新元素,都需要遍历整个链表到尾部!!

链式存储实现的优化

bVbCRiK

bVbCRiL

编程实验:基于 Linux 内核链表的队列

文件:LinkQueue.h

#ifndef LINKQUEUE_H

#define LINKQUEUE_H

#include "Queue.h"

#include "LinuxList.h"

#include "Exception.h"

namespace DTLib

{

template

class LinkQueue : public Queue

{

public:

LinkQueue()

{

m_length = 0;

INIT_LIST_HEAD(&m_header);

}

void add(const T &e) override // O(1)

{

Node *node = new Node;

if (node != nullptr)

{

node->value = e;

list_add_tail(&node->head, &m_header);

++m_length;

}

else

{

THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory to add element ...");

}

}

void remove() override // O(1)

{

if (m_length > 0)

{

list_head *toDel = m_header.next;

list_del(toDel);

--m_length;

delete list_entry(toDel, Node, head);

}

else

{

THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current LinkQueue ...");

}

}

T front() const override // O(1)

{

if (m_length > 0)

{

return list_entry(m_header.next, Node, head)->value;

}

else

{

THROW_EXCEPTION(InvalidOpertionExcetion, "No element in current LinkQueue ...");

}

}

void clear() override // O(n)

{

while (m_length > 0)

{

remove();

}

}

int length() const override // O(1)

{

return m_length;

}

~LinkQueue() // O(n)

{

clear();

}

protected:

struct Node : public Object

{

list_head head;

T value;

};

list_head m_header;

int m_length;

};

}

#endif // LINKQUEUE_H

文件:main.cpp

#include

#include "LinkQueue.h"

using namespace std;

using namespace DTLib;

class Test : public Object

{

public:

Test()

{

cout << "Test()" << endl;

}

~Test()

{

cout << "~Test()" << endl;

}

};

int main()

{

LinkQueue queue_t;

cout << "-----" << endl;

LinkQueue queue;

for (int i=0; i<5; ++i)

{

queue.add(i);

}

while (queue.length() > 0)

{

cout << queue.front() << endl;

queue.remove();

}

return 0;

}

输出:

-----

0

1

2

3

4

小结

SaticQueue 在初始化时可能多次调用元素类型的构造函数

LinkList 的组合使用实现了队列的功能,但是不够高效

LinkQueue 的最终实现组合使用了 Linux 内核链表

LinkQueue 中入队和出队操作可以在常量时间内完成

以上内容整理于狄泰软件学院系列课程,请大家保护原创!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值