c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)相关的知识,希望对你有一定的参考价值。
c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)
本文主要内容
1)介绍c++中双向链表的写法。
2)实现双向链表中数据的增、删、查、改、链表逆置、链表输出
3)介绍类中构造函数、析构函数、运算符重载函数的写法
接下来介绍双向链表的成员函数:这写函数放在头文件中,方便编写
#pragma once #include<iostream> using namespace std; #include<assert.h> typedef int DataType; class ListNode //节点 { public: ListNode(DataType x) :_data(x), _next(NULL), _prev(NULL) {} ListNode*_next; ListNode*_prev; DataType _data; }; class List //双向链表 { public: List(); List(List&s); List&operator=(const List&s); ~List(); void PushBack(DataType x); void PopBack(); void PushFront(DataType x); void PopFront(); void Insert(ListNode *pos, DataType x); void Erase(ListNode*pos); ListNode* Find(DataType x); void Reverse(); void PrintList(); void Clear(); void PrintReverseList(); private: ListNode*_head; ListNode* _tail; };
接下来介绍各个函数,
1)构造函数(此处写了一种,因为只用到了这一种)
List::List() :_head(NULL), _tail(NULL) {}
2)构造函数中的拷贝构造
List::List(List&s) :_head(NULL), _tail(NULL) { ListNode*cur = s._head; while (cur) { PushBack(cur->_data); cur = cur->_next; } }
3)赋值运算符重载
List& List::operator=(const List&s) { _head = NULL; _tail = NULL; ListNode*cur = s._head; while (cur) { PushBack(cur->_data); cur = cur->_next; } return *this; }
4)析构函数
List::~List() { Clear(); } void List::Clear() { cout << "~Clear() "; ListNode*cur = _head; while (cur) { ListNode*del = cur; cur = cur->_next; delete del; } cout << " clear is NULL" << endl; }
5)增加节点的函数(三种,前增、后增、给定节点后插入)
void List::PushFront(DataType x) { if (_head == NULL) { _head = new ListNode(x); _tail = _head; } else { ListNode*temp = new ListNode(x); _head->_prev = temp; temp->_next = _head; _head = temp; } } void List::PushBack(DataType x)//后增 { if (_head == NULL) { _head = new ListNode(x); _tail = _head; } else { ListNode*temp = new ListNode(x); _tail->_next = temp; temp->_prev = _tail; _tail = temp; } } void List::Insert(ListNode *pos, DataType x) { assert(pos); if (pos == _tail) { PushBack(x); } else { ListNode*cur = pos->_next; ListNode*temp = new ListNode(x); temp->_next = cur; temp->_prev = pos; pos->_next = temp; cur->_prev = temp; } }
6)删除节点(三种,前删、后删、删除给定节点)
void List::PopFront() { if (_head == NULL) { cout << "空链表!" << endl; return; } else { if (_head->_next) { ListNode *temp = _head; _head = _head->_next; _head->_prev = NULL; delete temp; } else { delete _head; _head = _tail = NULL; } } } void List::PopBack() { if (_head == NULL) { cout << "空链表!" << endl; return; } else { if (_tail->_prev) { ListNode *temp = _tail; _tail = _tail->_prev; _tail->_next = NULL; delete temp; } else { delete _tail; _head = _tail = NULL; } } } void List::Erase(ListNode*pos) { assert(pos); if (pos == _head) { PopFront(); } else if (pos == _tail) { PopBack(); } else { ListNode*temp = pos->_prev; ListNode*next = pos->_next; temp->_next = next; next->_prev = temp; delete pos; } }
7)寻找节点
ListNode* List::Find(DataType x) { if (_head == NULL) { cout << "空链表!" << endl; return NULL; } ListNode*cur = _head; while (cur) { if (cur->_data == x) return cur; cur = cur->_next; } }
8)双向链表逆置(两种方法)
方法一:交换每个节点的前驱和后继。
方法二:创建新的链表,从远链表上摘节点然后补到新链表上
//void List::Reverse() //方法 一 //{ // if (_head == NULL) // { // cout << "空链表!" << endl; // return; // } // else if (_head == _tail) // return; // else // { // swap(_tail,_head); // ListNode *cur = _head; // while (cur) // { // swap(cur->_prev, cur->_next); // cur = cur->_next; // } // } //} void List::Reverse()//方法二 { if (_head == NULL) { cout << "空链表!" << endl; return; } else if (_head == _tail) return; else { ListNode*cur = _tail; ListNode *newhead = NULL; while (cur) { if (newhead == NULL) { newhead = new ListNode(cur->_data); _head = newhead; } else { ListNode*temp = new ListNode(cur->_data); newhead->_next = temp; temp->_prev = newhead; newhead = temp; _tail = temp; } ListNode* del = cur; cur = cur->_prev; delete del; } } }
9)打印链表(两种,顺序打印、逆序打印)
void List::PrintList()//顺序打印 { ListNode*cur = _head; while (cur) { cout << cur->_data << "->"; cur = cur->_next; } cout << "NULL" << endl; } void List::PrintReverseList()//逆序打印 { cout << "从后向前:"; ListNode*cur = _tail; while (cur) { cout << cur->_data << "->"; cur = cur->_prev; } cout << "NULL" << endl; }
当然还有主函数(测试用例)
#include"List.h" void Test3() { cout << endl; List l1; l1.PushFront(1); l1.PushBack(2); l1.PushBack(3); l1.PushBack(4); l1.PushBack(5); l1.PushBack(6); //l1.PushFront(4); //l1.PopFront();//前删 //l1.PopBack();//后删 //ListNode *pos = l1.Find(3); //l1.Insert(pos, 5); //l1.Erase(pos); cout << "l1 :"; l1.PrintList(); l1.PrintReverseList(); cout << "逆置l1 :"; l1.Reverse(); l1.PrintList(); l1.PrintReverseList(); cout << "拷贝构造-》 l2 :"; List l2(l1); l2.PrintList(); cout << "赋值运算符重载 -》 l3 :"; List l3; l3 = l2; l3.PrintList(); } int main() { Test3(); system("pause"); return 0; }
以上函数均是在学习的过程中总结写出的,肯定会有一些疏漏或者错误之处,所以敬请各位大神的批评指正,谢谢
本文出自 “分享中进步” 博客,请务必保留此出处http://xmwen1.blog.51cto.com/10730069/1748216
以上是关于c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)的主要内容,如果未能解决你的问题,请参考以下文章
数据结构学习笔记(单链表单循环链表带头双向循环链表)的增删查改排序等)
数据结构学习笔记(单链表单循环链表带头双向循环链表)的增删查改排序等)