模板(双向链表与队列)
2016-03-20 20:48
447 查看
”双向链表与队列“
“双向链表”是包含两个指针域,一个数据域,既有指向前驱的指针,还有指向后继的指针,同时可以从两个方向对链表进行遍历,访问各个节点。“双向链表”较”单链表“在插入和删除节点方面更为简单,但是所占的空间比“单链表”大。“队列”的实现之所以选择使用双向链表,是因为队列的特点是“先进先出”,如若使用顺序表则很大程度上的浪费空间。在这样的情境下,链表较顺序表更为合适。
根据“模板”的概念,设计并实现双向链表,进而实现队列的基本功能。下面是利用模板来实现双向链表的具体代码:
对于”队列“能够利用上述双向链表的功能来实现,下面就是基本的程序代码:
“双向链表”是包含两个指针域,一个数据域,既有指向前驱的指针,还有指向后继的指针,同时可以从两个方向对链表进行遍历,访问各个节点。“双向链表”较”单链表“在插入和删除节点方面更为简单,但是所占的空间比“单链表”大。“队列”的实现之所以选择使用双向链表,是因为队列的特点是“先进先出”,如若使用顺序表则很大程度上的浪费空间。在这样的情境下,链表较顺序表更为合适。
根据“模板”的概念,设计并实现双向链表,进而实现队列的基本功能。下面是利用模板来实现双向链表的具体代码:
#pragma once #include <assert.h> //双向链表 template <class T> struct ListNode { T _data; ListNode<T> * _next; ListNode<T> * _prev; ListNode(const T& x) :_data(x) , _next(NULL) , _prev(NULL) { } }; template <class T> class List { public: List() //构造函数 :_head(NULL) , _tail(NULL) { } ~List() //析构函数 { Clear(); } public: void pushBack(const T & x) //尾插 { if (_head == NULL) { _head = _tail = new ListNode<T>(x); } else { ListNode<T> * tmp = new ListNode<T>(x); _tail->_next = tmp; tmp->_prev = _tail; _tail = tmp; tmp->_next = NULL; } } void popBack() //尾删 { if (_head == NULL) { return; } else if (_head == _tail) { delete _tail; _head = _tail = NULL; } else { ListNode<T> * tmp = _tail->_prev; delete _tail; tmp->_next = NULL; _tail = tmp; } } void pushFront(const T & x) //头插 { ListNode<T> * tmp = new ListNode<T>(x); if (_head == NULL) { _head = _tail = tmp; } else { tmp->_next = _head; tmp->_prev = NULL; _head = tmp; } } void popFront() //头删 { if (_head == _tail) { if (_head) { delete _head; _head = _tail = NULL; } } else { ListNode<T> * tmp = _head->_next; delete _head; _head = tmp; tmp->_prev = NULL; } } void Insert(ListNode<T> * pos,const T& x) //在pos位置上插入数据x { assert(pos); ListNode<T> * tmp = new ListNode<T>(x); ListNode<T> * cur = pos->_next; tmp->_next = cur; cur->_prev = tmp; tmp->_prev = pos; pos->_next = tmp; } void Erase(ListNode<T> * pos) //删除pos位置上的数据 { assert(pos); if (_head == NULL) { return; } else if (_head == _tail) { delete _head; } else { ListNode<T> * cur = pos->_next; ListNode<T> * tmp = pos->_prev; tmp->_next = cur; cur->_prev = tmp; delete pos; } } ListNode<T> * Find(const T & x) //查找 { ListNode<T> * tmp = _head; while (tmp) { if (tmp->_data == x) { return tmp; } tmp = tmp->_next; } if (tmp->_next) { return NULL; } } T & Top() //读取队头元素 { return _head->_data; } T & Back() //读取队尾元素 { assert(size > 0); return _tail->_data; } void Reverse() //逆置 { swap(_head, _tail); ListNode<T>* tmp = _head; while (tmp) { swap(tmp->_prev, tmp->_next); tmp = tmp->_next; } } void Sort() //冒泡排序 { ListNode<T> * cur = _head; ListNode<T> * tmp = _head->_next; while (tmp) { if (cur->_data > tmp->_data) { T ptr = cur->_data; cur->_data = tmp->_data; tmp->_data = ptr; } cur = cur->_next; tmp = tmp->_next; } } void Unique() //在有序链表中,去掉重复的数据 { ListNode<T> * cur = _head; ListNode<T> * tmp = _head->_next; while (tmp) { while (cur->_data == tmp->_data) { ListNode<T>* str = tmp; tmp = tmp->_next; Erase(str); } cur = cur->_next; tmp = tmp->_next; } } void Merge(List<T> & s) //将某一个链表连接到这个链表后面 { _tail->_next = s._head; s._head->_prev = _tail; } void Splice(ListNode<T> * pos, List<T> & s) //将一个链表连接到pos位置后面 { assert(pos); if (pos == _tail) { Merge(s); } else { ListNode<T> * cur = pos; ListNode<T> * tmp = pos->_next; ListNode<T> * str = s._tail; cur->_next = s._head; s._head->_prev = cur; str->_next = tmp; tmp->_prev = str; } } size_t Size() //计算链表中的元素个数 { ListNode<T> * tmp = _head; int count = 0; while (tmp) { count++; tmp = tmp->_next; } return count; } void print() //格式输出 { ListNode<T> * tmp = _head; while (tmp) { cout << tmp->_data << " "; tmp = tmp->_next; } cout << endl; } void Clear() { ListNode<T> * tmp = _head; while (tmp) { ListNode<T> * str = tmp; tmp = tmp->_next; delete str; } } private: ListNode<T> * _head; ListNode<T> * _tail; };
对于”队列“能够利用上述双向链表的功能来实现,下面就是基本的程序代码:
#pragma once #include <string> //队列 #include <assert.h> #include "ListNode.h" template <class T , template<class> class container = List> class Queue { public: void push(const T & x) //进入队列 { _con.pushBack(x); } void pop() //出队列 { _con.popFront(); } bool Empty() //判断队列是否为空 { return _con.Size() == 0; } size_t size() //计算队列中的元素个数 { return _con.size(); } T & top() //队头节点 { return _con.Top(); } T & Back() //队尾节点 { return _con.Back(); } void print() //格式输出 { _con.print(); } private: container<T> _con; };
相关文章推荐
- 设计模式之行为型模式 - 调用行为的传递问题
- [div+css]晒晒最新制作专题推广页模板
- 2008大学生入党申请书 模板
- IMAIL多语言模板两套Outlook&Gmail模板下载
- 在PHP中使用模板的方法
- 深入解析php模板技术原理【一】
- Json2Template.js 基于jquery的插件 绑定JavaScript对象到Html模板中
- 在ASP中不用模板生成HTML静态页直接生成.html页面
- C#模板方法模式(Template Method Pattern)实例教程
- javascript文本模板用法实例
- 关于Asp代码与页面的分离模板技术第1/3页
- php模板原理讲解
- 需要使用php模板的朋友必看的很多个顶级PHP模板引擎比较分析
- DataGrid 动态添加模板列 实现代码
- java数据结构之实现双向链表的示例
- 详解java模板和回调机制
- C++模板之特化与偏特化详解
- C++将二叉树转为双向链表及判断两个链表是否相交
- vs.net2008添加模板方法
- ThinkPHP模板判断输出Empty标签用法详解