双向链表的c++实现
2017-04-21 10:33
281 查看
list.h
////////////////////////////////////////////////////////////////////////////////////// /////// 这里建立两个类,一个节点类和一个List类,与单链表不同的是双向链表的节点要多一 ////// 个前驱指针,相应的,双向链表函数实现要与单链表实现有所差异 typedef int DataType; //struct LinkNode //节点类(复合形态) //{ // friend class SList; //将SList设为友元,便于SList类可以访问节点类的私有成员 //public: // LinkNode(const DataType x); //private: // DataType _data; //节点的数据 // LinkNode* _next; //指向该节点的下一个节点 // LinkNode* _prev; //指向该节点的前一个节点 //}; //直接用struct定义LinkNode类,因为struct的成员默认为公有数据成员,所以可直接访问 struct LinkNode //节点类(建议写法) { LinkNode(const DataType x); DataType _data; //节点的数据 LinkNode* _next; //后继指针 LinkNode* _prev; //前驱指针 }; class List //链表类 { public: List(); //构造函数 List(const List& s); //拷贝构造 List &operator=(List& s); //赋值运算符的重载 ~List(); public: void Reverse(); void Swap(List& s); void PrintSList(); //打印链表 void PushBack(const DataType& x); //在尾部插入一个节点 void Clear(); //链表置空 void PopBack(); void PushFront(DataType x); //头插 void PopFront(); //删除首节点 void Insert(LinkNode* pos, DataType x);//固定位置插入一个节点 void Erase(LinkNode* pos); //删除某一节点 LinkNode* Find(DataType x); //查找节点并返回这个节点的地址 int Amount(); //计算链表节点的数目 void Remove(DataType x); //查找某节点并删除 private: LinkNode* _head; //指向头结点 LinkNode* _tail; //指向尾节点 }; List.h
list.cpp
hljs php"> using namespace std; #include<assert.h> #include"List.h" //节点类构造函数* LinkNode::LinkNode(const DataType x) :_data(x) , _next(NULL) , _prev(NULL) {} //链表类* List::List() //构造函数 : _head(NULL) , _tail(NULL) {} List::List(const List& s) //拷贝构造 : _head(NULL) , _tail(NULL) { if (s._head == NULL) { return; } LinkNode* tmp = s._head; while (tmp) { PushBack(tmp->_data); tmp = tmp->_next; } } //赋值运算符的重载(传统方法) //SList & SList::operator=(const SList& s) //{ // if (this != &s) // { // _head = NULL; // _tail = NULL; // LinkNode* tmp = s._head; // do{ // PushBack(tmp->_data); // tmp = tmp->_next; // } while (tmp != s._head); // } // return *this; //} //赋值运算符的重载(高效写法)* /*void SList::Swap(SList& s) { swap(_head, s._head); swap(_tail, s._tail); } SList& SList::operator=(SList &s) { if (this != &s) { SList tmp(s); Swap(tmp); } return *this; }*/ List& List::operator=(List &s) //赋值运算符的重载再优化(推荐写法) { if (this != &s) { swap(_head, s._head); swap(_tail, s._tail); } return *this; } List::~List() //析构 { Clear(); } void List::Reverse() //链表逆置(利用头插新节点的方法) { if (_head == NULL || _head== _tail) { return; } int ret = Amount(); /* // 方法一(相当于用头插的方式重新建立链表) _tail = new LinkNode(_head->_data); LinkNode* begin = NULL; LinkNode* tmp = _tail; while (--ret) { LinkNode* del = _head; _head = _head->_next; delete del; begin = new LinkNode(_head->_data); begin->_next = tmp; tmp->_prev = begin; tmp = begin; } _head = begin;*/ ////// 方法二(只是交换对称位置节点的数据)**(高效) LinkNode* begin = _head; LinkNode* end = _tail; while (ret) { if (end->_next == begin) break; ret /= 2; swap(begin->_data, end->_data); begin = begin->_next; end = end->_prev; } /*// 方法三 交换前驱和后继指针 swap(_head, _tail); LinkNode* cur = _head; while (cur) { swap(cur->_prev,cur->_next); cur = cur->_next; } */ } //打印链表* void List::PrintSList() { //头结点为空时,无需打印链表 if (_head == NULL) { cout << "This SList is Empty !" << endl; return; } else { LinkNode* tmp = _head; while (tmp) { cout << tmp->_data << "-->"; tmp = tmp->_next; } cout <<"NULL"<< endl; } } void List::PushBack(const DataType& x) //在尾部插入一个节点* { //如果链表为空,插入节点后只有一个节点,此时_head=_tail if (_head == NULL) { _head = new LinkNode(x); _tail = _head; } else { _tail->_next = new LinkNode(x); _tail->_next->_prev=_tail; _tail = _tail->_next; } } void List::Clear() //链表置空* { LinkNode* begin = _head; while (begin != _tail) { _head = _head->_next; delete begin; begin = _head; } _head = NULL; _tail = NULL; } void List::PopBack() //尾删 { if (_head == NULL) { cout << "This SList is empty !" << endl; } else if (_head == _tail) { delete _head; _head = NULL; _tail = NULL; } else { LinkNode* cur = _head; while (cur->_next != _tail) { cur = cur->_next; } delete _tail; _tail = cur; _tail->_prev = cur->_prev; _tail->_next = NULL; } } void List::PushFront(DataType x) //头插* { if (_head == NULL) { PushBack(x); } else { LinkNode* tmp = _head; _head = new LinkNode(x); _head->_next = tmp; tmp->_prev = _head; } } void List::PopFront() //删除首节点 { if (_head == NULL) { cout << "This SList is empty !" << endl; return; } LinkNode* tmp = _head; _head = _head->_next; _head->_prev = NULL; delete tmp; } //固定位置插入一个节点(这个函数需和Find函数搭配使用) //先用Find函数找到新节点需要插入的位置 //(将Find函数的返回值传给Insert函数的参数pos),再在pos节点后面插入新节点x void List::Insert(LinkNode* pos, DataType x) //* { assert(pos); if (pos == _tail) { PushBack(x); } else { LinkNode* tmp = new LinkNode(x); tmp->_next = pos->_next; pos->_next = tmp; tmp->_next->_prev = tmp; tmp->_prev = pos; } } //删除某一节点,同样,要先找到该节点并传参给Erase函数 void List::Erase(LinkNode* pos) { assert(pos); if (pos == _tail) { PopBack(); } else if (pos == _head) { PopFront(); } else { pos->_prev->_next = pos->_next; pos->_next->_prev = pos->_prev; delete pos; } } //查找节点并返回这个节点的地址 LinkNode* List::Find(DataType x) { if (_head == NULL) { cout << "This SList is empty !" << endl; return NULL; } else { LinkNode* tmp = _head; while (tmp != NULL) { if (tmp->_data == x) { return tmp; } tmp = tmp->_next; } return NULL; } } int List::Amount() //计算链表节点的数目 { if (_head == NULL) { return 0; } else { int count = 0; LinkNode* cur = _head; while (cur != _tail) { count++; cur = cur->_next; } return ++count; } } void List::Remove(DataType x) //查找某节点并删除 { if (_head == NULL) { cout << "This SList is empty !" << endl; } else { LinkNode* tmp = Find(x); if (tmp != NULL) { Erase(tmp); } } } List.cpp
test.cpp
#include<stdlib.h> #include<iostream> using namespace std; void Test1() { List list1; list1.PushBack(1); list1.PushBack(2); list1.PushBack(3); list1.PushBack(4); list1.PushBack(5); list1.PushBack(6); list1.PrintSList(); /* List list2(list1); list2.PrintSList();*/ List list2=list1; list2.PrintSList(); //list2.PopBack(); //list2.Clear(); //list2.PushFront(0); //list2.PopFront(); //////检验Find函数 ////LinkNode* ret=list2.Find(4); ////if (ret != NULL) ////{ //// cout << "ret:" << ret << " " << ret->_data << endl; ////} ////else ////{ //// cout << "Not exit !" << endl; ////} /* int ret=list2.Amount(); cout << ret << endl;*/ //list2.Erase(list2.Find(5)); //list2.Insert(list2.Find(2), 0); //list2.Remove(3); list2.Reverse(); list2.PrintSList(); } int main() { Test1(); system("pause"); }
相关文章推荐