C++实现简单的双向链表
2015-12-14 23:19
627 查看
vs2013下编译运行,实现了双向链表类List 的 构造函数,拷贝构造、析构函数、赋值运算符重载、清空、头插、头删、尾插、尾删、插入、删除、逆序和删除链表中重复的数据值函数等。
直接贴代码:
DuList.h 类声明、定义、成员函数定义。
Main.cpp 测试用例
直接贴代码:
DuList.h 类声明、定义、成员函数定义。
#pragma once //双向链表 #include<assert.h> #include<iostream> using namespace std; typedef int DataType; struct ListNode { ListNode(DataType& x) :_data(x) ,_prev(NULL) , _next(NULL) {} DataType _data; ListNode * _prev; ListNode * _next; }; class List { public: List() :_head(NULL) , _tail(NULL) {} List(const List & l) { ListNode * end = l._tail; while (end) { PushFront(end->_data); end = end->_prev; } } ~List() { ListNode * begin = _head; while (begin) { ListNode * tmp = begin; begin = begin->_next; delete tmp; } } void Clear() //清空链表 { ListNode * begin = _head; while (begin) { ListNode * tmp = begin; begin = begin->_next; delete tmp; } _head=_tail = NULL; //最终结果 } List& operator=(List &l) { List tmp(l); swap(_head, l._head); swap(_tail, l._tail); return *this; //tmp被析构 } void PushBack(DataType &x) { ListNode * tmp = new ListNode(x); if (_tail == NULL) { tmp->_next = _tail; _head =_tail= tmp; } else { _tail->_next = tmp; tmp->_prev = _tail; _tail = tmp; } } void PopBack() { if (_head == _tail) { delete _head; //NULL也可以 _head = _tail = NULL; } else { ListNode * prev = _tail->_prev; delete(_tail); _tail = prev; } } void PushFront(DataType & x) { ListNode * tmp = new ListNode(x); if (_head == NULL) { _head = tmp; _tail = tmp; } else { tmp->_next = _head; tmp->_prev = NULL; _head->_prev = tmp; _head = tmp; } //可能没完 } void Reverse() { assert(_head&&_tail); //逻辑短路 ListNode * left = _head; ListNode * right = _tail; while (left!=right && left->_prev!=right) //限定条件很重要 { swap(left->_data, right->_data); left = left->_next; right = right->_prev; } } void PopFront() { assert(_head); if (_head == _tail) { delete _head; _head = _tail = NULL; //防止野指针 } else { ListNode *tmp = _head; _head = _head->_next; delete tmp; } } ListNode * Find(DataType & x) { ListNode * begin = _head; while (begin) { if (begin->_data == x) //x的类型必须重载了== 运算符 { return begin; } begin = begin->_next; } return NULL; //调用者需要检查结果是否合法 } void Insert(ListNode * pos, DataType x) { //在结点之后插入 assert(pos); ListNode * tmp = new ListNode(x); if (_tail == pos) { //需要考虑_tail _tail->_next = tmp; tmp->_prev = _tail; _tail = tmp; } else { tmp->_next = pos->_next; tmp->_prev = pos; tmp->_next->_prev = tmp; pos->_next = tmp; } } void Erase(ListNode* pos) { if (_head == _tail) { assert(_head == pos); delete _head; _head = _tail = NULL; return; } if (pos == _head) { _head = _head->_next; _head->_prev = NULL; //防止野指针 } else if (pos == _tail) { _tail = _tail->_prev; _tail->_next = NULL; //防止野指针 } else { ListNode * prev = pos->_prev; ListNode * next = pos->_next; prev->_next = next; next->_prev = prev; } delete pos; } void Print() { ListNode * begin=_head; while (begin) { cout << begin->_data<<"->"; begin = begin->_next; } cout << "NULL"<<endl; } void Unique() { size_t size = 0; ListNode * begin = _head; while (begin) { ListNode *it = _head->_next; while (it!=begin&&it!=NULL) { if (begin->_data == it->_data) { Erase(it); //删除it保证指针不失效 break; } it = it->_next; } begin = begin->_next; } } private: ListNode * _head; ListNode * _tail; };
Main.cpp 测试用例
#include"DuList.h" void Test1() { List l; int a = 1; l.PushFront(a); l.PushFront(++a); l.PushFront(++a); l.Print(); List l2(l); l2.Print(); } void Test2() { List L; int a = 1; int b = 3; L.PushFront(a); L.Insert(L.Find(a), (DataType)6); L.Insert(L.Find(a), (DataType)5); L.Insert(L.Find(a), (DataType)4); L.Insert(L.Find(a), (DataType)3); L.Insert(L.Find(a), (DataType)2); L.Print(); L.Reverse(); L.Print(); DataType i = 16; L.PushBack(i); L.PushBack(i); L.Print(); L.Unique(); L.Print(); //List l3; //l3.PushBack(i); //l3.Print(); //L = l3; //L.Print(); //l3.Clear(); //l3.Print(); //L.Erase(L.Find(b)); //L.Erase(L.Find(a)); //int c = 5; //L.Erase(L.Find(c)); //c = 2; //L.Erase(L.Find(c)); //c = 4; //L.Erase(L.Find(c)); //L.Print(); } void Test3() //Unique { //List L2; //DataType a = 9; //L2.PushBack(a); //L2.PushBack(a); //L2.PushBack(++a); //L2.PushBack(++a); //L2.PushBack(++a); //L2.PushBack(a); //L2.PushBack(a); //L2.Print(); //L2.Unique(); //L2.Print(); List L3; DataType b = 100; L3.PushFront(b); L3.Print(); L3.Unique(); L3.Print(); } int main() { //Test1(); //Test2(); Test3(); system("pause"); return 0; }
相关文章推荐
- 单链表的操作_二分查找
- 哈夫曼(Huffman)编码问题(C++实现)
- CPP-operator==, <overloading
- c++11 之初
- C++左值和右值
- 小项目集锦博客目录(不断更新,总结)
- C++学习笔记(三)enum
- C++之可变参数的实现简介
- C++中的struct和class的区别
- c++设计模式总结
- c++设计模式总结 好久没写博客了 实在是忙
- C++primer--拷贝控制__构造函数和析构函数的执行时期
- 无法查找或打开 PDB 文件。
- C语言冒泡排序及选择排序优化<代码>
- 实战c++中的string系列--不要使用memset初始化string(一定别这么干)
- 实战c++中的string系列--不要使用memset初始化string(一定别这么干)
- C/C++学习(六)线性表的插入、删除和查找
- Nias and Tug-of-War 拔河比赛
- C++11之美
- C++ Primer 学习笔记——类(一)