【C++】模版实现双向链表的各种操作(如:逆置、去重Unique、分类(冒泡)、合并)
来源:互联网 发布:哈布斯堡 知乎 编辑:程序博客网 时间:2024/05/16 04:43
在cplusplus.com里,我们可以搜索list来查看库是如何实现双向链表的。当然,我们也可以在平时使用时包上头文件list来调用C++里的list库。在这里,我今天就不再赘述用C语言或者C++未引入模版这两种场景来向大家分享双向链表了,而是注重多类型都可以使用双向链表。也就是我们今天的主题:模版实现双向链表。
我主要实现了尾插、尾删、打印、去重、逆置等等一系列操作,而关于像Insert()、Erase()之类的操作我并没有在这里全部实现,一方面是因为之前我们反复实现过,如果你感兴趣的话,可以查看我之前的博客。另一方面,我出于较为低效不常见的原因。希望大家理解。
另外,需要说明的一点是,今天我使用的均是类内声明,类外定义的方式。
代码如下:
#include<iostream>using namespace std;template<class T>struct ListNode{ ListNode(const T& x) :_next(NULL) , _prev(NULL) , _data(x) {} ListNode<T>* _next; ListNode<T>* _prev; T _data;}; template<class T>class List{public: List() :_head(NULL) , _tail(NULL) {} List(const List<T>& l) { ListNode<T>* cur = l._head; while (cur) { this->PushBack(cur->_data); cur = cur->_next; } } List<T>& operator=(const List<T>& l) { //先删除节点,再插入节点 if (&s != this) { ListNode<T>* pcur = _head; while (pcur) { ListNode<T>* del = pcur; pcur = pcur->_next; delete del; del = NULL; } ListNode<T>* cur = _head; while (cur) { this->PushBack(cur->_data); cur = cur->_next; } } return *this; } ~List()//一个节点一个节点的删除 { ListNode<T>* cur = _head; while (cur) { ListNode<T>* del = cur; cur = cur->_next; delete del; del = NULL; } } void PushBack(const T& x); void PopBack(); void Unique(); void PrintList(); void Reverse(); int Length(); void Sort(); void Merge(List<T>& l2);protected: ListNode<T>* _head; ListNode<T>* _tail;};//尾插template<class T>void List<T>::PushBack(const T& x){ //分析:分为两种情况:无节点、有节点 if (_head == NULL) { _head = _tail = new ListNode<T>(x); } else { ListNode<T>* cur = new ListNode<T>(x); _tail->_next = cur; cur->_prev = _tail; _tail = cur; _tail->_next = NULL; }}//尾删template<class T>void List<T>::PopBack(){ //分析:分为三种情况:无节点、一个节点、多个节点 if (_head == _tail) { if (_head == NULL) { return; } else { delete _head; _head = _tail = NULL; } } else { ListNode<T>* prev = _tail->_prev; delete _tail; _tail = NULL; _tail = prev; _tail->_next = NULL; }}//去重:前提是针对已排序的有重复数据的链表//template<class T>//void List<T>::Unique()//{// //分析:分为三种情况:无节点一个节点(无需删除节点)、两个节点、两个以上节点// if (_head == _tail)// {// return; // }// else// {// ListNode<T>* pcur = _head;// ListNode<T>* pnext = _head->_next;// if (pnext->_next == NULL) //两个节点// {// if (pcur->_data == pnext->_data)// {// delete pnext;// pnext = NULL;// _tail = _head = pcur;// return;// }// else// {// return;// } // }// else// {// //两个以上节点// ListNode<T>* cur = _head;// while (cur->_next)// {// ListNode<T>* next = cur->_next;// ListNode<T>* nextnext = next->_next;// if (cur->_data == next->_data)// {// cur->_next = nextnext;// nextnext->_prev = cur;// delete next;// next = NULL;// }// cur = cur->_next;// }// } // } //}//逆置template<class T>void List<T>::Reverse(){ //分析:从两头开始走,交换数据(分奇数个数据和偶数个数据) ListNode<T>* begin = _head; ListNode<T>* end = _tail; while (!((begin == end) || end->_next == begin)) { swap(begin->_data, end->_data); begin = begin->_next; end = end->_prev; }}//长度template<class T>int List<T>::Length(){ ListNode<T>* cur = _head; int count = 0; while (cur) { count++; cur = cur->_next; } return count;}//分类template<class T>void List<T>::Sort(){ //使用冒泡排序,实现升序或者降序 ListNode<T>* i = _head; while (i != _tail) { ListNode<T>* j = _head; ListNode<T>* end = _tail; while (j != end) { if (j->_data >(j->_next)->_data) { swap(j->_data, (j->_next)->_data); } j = j->_next; } end = end->_prev; i = i->_next; }}//合并template<class T>void List<T>::Merge(List<T>& l2){ ListNode<T>* cur1 = _head; ListNode<T>* cur2 = l2._head; if (cur1->_data > cur2->_data) { swap(cur1->_data, cur2->_data); } while (cur1 && cur2) { if (cur1->_data <= cur2->_data) { cur1 = cur1->_next; } else { ListNode<T>* tmp = cur2; cur2 = cur2->_next; ListNode<T>* prev = cur1->_prev; cur1->_prev = tmp; tmp->_next = cur1; prev->_next = tmp; tmp->_prev = prev; } } if (cur1 == NULL) { _tail->_next = cur2; cur2->_prev = _tail; _tail = l2._tail; }}//打印template<class T>void List<T>::PrintList(){ ListNode<T>* cur = _head; while (cur) { cout << cur->_data << "->"; cur = cur->_next; } cout << "NULL" << endl;}void Test(){ List<int> l1; l1.PushBack(1); l1.PushBack(3); l1.PushBack(5); l1.PushBack(7); l1.PrintList(); l1.PopBack(); l1.PrintList(); /*l1.Unique(); l1.PrintList();*/ List<int> l2; l2.PushBack(2); l2.PushBack(4); l2.PushBack(6); l1.Merge(l2); l1.PrintList(); l1.Reverse(); l1.PrintList(); l1.Sort(); l1.PrintList();}int main(){ Test(); system("pause"); return 0;}
本文出自 “Han Jing's Blog” 博客,请务必保留此出处http://10740184.blog.51cto.com/10730184/1750695
0 0
- 【C++】模版实现双向链表的各种操作(如:逆置、去重Unique、分类(冒泡)、合并)
- 【代码】模板实现双向链表的去重、拼接、合并、排序
- 链表的基本操作(创建,查找指定位置元素,删除指定元素,插入,倒置,去重,求集合的差,分别交换结点与交换结点值实现的冒泡排序,将两个有序链表合并成一个有序链表)c语言实现
- 链表的简单操作(插入,删除,置反,输出,合并,去重)
- 双向链表操作(逆置三种实现以及 冒泡排序 )
- 双向链表的操作实现(c语言)
- 链表常见操作:有序链表合并去重
- LinuxC双向链表的各种操作
- 双向链表的实现与操作(C语言实现)
- 字符的去重操作~合并同类项操作
- unique()去重函数
- std::unique (去重)
- unique()去重函数
- C语言实现双向链表的基本操作
- C语言实现双向链表的基本操作
- 双向链表的相关操作--C语言实现
- c语言实现双向链表的基本操作
- 对链表各种操作的实现(C语言)
- 【C++】实现双向链表的所有操作,包括逆置双链表(三种方法)
- 【C语言】单链表的所有操作的实现(包括PopBack、PushBack、PopFront、PushFront、Insert)
- 【继承与多态】C++:继承中的赋值兼容规则,子类的成员函数,虚函数(重写),多态
- 【C++】模版类实现普通类静态顺序表
- 【C++】认识模版函数
- 【C++】模版实现双向链表的各种操作(如:逆置、去重Unique、分类(冒泡)、合并)
- 【C++】容器适配器实现栈Stack的各种功能(入栈、出栈、判空、大小、访问所有元素等)
- 【C++】容器适配器实现队列Queue的各种功能(入队、出队、判空、大小、访问所有元素等)
- 论IT就业发展趋势
- 【C++】类型萃取技术实现静态顺序表
- 【C++】智能指针的作用,模拟实现auto_ptr,scoped_ptr,shared_ptr,scoped_array,shared_array
- 【C语言】求斐波那契(Fibonacci)数列通项(递归法、非递归法)
- 【数据结构】使用栈Stack解决迷宫问题
- 【数据结构】(面试题)使用两个栈实现一个队列(详细介绍)