C++ 手动实现双向链表(作业版)
创始人
2024-02-08 14:05:22

双向链表,并实现增删查改等功能

首先定义节点类,类成员包含当前节点的值, 指向下一个节点的指针和指向上一个节点的指针

//节点定义
template 
class Node {
public:Node* prior;T value;Node* next;Node():value(0),prior(nullptr),next(nullptr) {}Node(T n):prior(nullptr),value(n),next(nullptr) {}
};

然后是链表类的定义,主要包含了增删查改等功能

//双向链表定义
template 
class LinkList_doubly {
public:Node* firstNode;Node* lastNode;LinkList_doubly();LinkList_doubly(int n, const T* arr);LinkList_doubly(const LinkList_doubly& link);~LinkList_doubly();LinkList_doubly& push_back(T n);LinkList_doubly& push_front(T n);LinkList_doubly& insert(int pos, int n, T* arr);LinkList_doubly& pop_front();LinkList_doubly& pop_back();LinkList_doubly& remove(int pos, int num);LinkList_doubly& reverse();T& operator[](int n);T& at(int n);LinkList_doubly& replace(int pos, int n, T* arr);int getLen() {return len;}void clear() {this->~LinkList_doubly();}void display();
private:int len = 0;Node* getNode_next(int n);};

各个函数解释:

LinkList_doubly();      默认构造函数

LinkList_doubly(const T* arr, int len);      一般构造函数

LinkList_doubly(const LinkList& link)           拷贝构造函数

~LinkList_doubly();     析构函数

LinkList_doubly& push_back(T n);    在尾部添加一个元素

LinkList_doubly& push_front(T n);     在头部添加一个元素

LinkList_doubly& insert(int pos, int n, T* arr);   在pos处插入n个元素

LinkList_doubly& pop_front();    删除第一个节点

LinkList_doubly& pop_back();    删除最后一个节点

LinkList_doubly& remove(int pos, int num);     删除pos开始的num个元素

LinkList_doubly& reverse();     反转链表

T& operator[](int n);     重载[ ]运算符,返回第n个节点的值

T& at(int n);                 与[ ]一样,只不过会检查索引是否越界

LinkList_doubly& replace(int pos, int n, T* arr);    替换n个节点

int getLen() {return len;}     返回长度,因为len是private

void clear() {this->~LinkList();}    清除链表

void display();    显示链表所有元素

Node* getNode_next(int n);     返回第n个节点的next指针

#include 
using namespace std;template 
class Node {
public:Node* prior;T value;Node* next;Node():value(0),prior(nullptr),next(nullptr) {}Node(T n):prior(nullptr),value(n),next(nullptr) {}
};template 
class LinkList_doubly {
public:Node* firstNode;Node* lastNode;LinkList_doubly();LinkList_doubly(int n, const T* arr);LinkList_doubly(const LinkList_doubly& link);~LinkList_doubly();LinkList_doubly& push_back(T n);LinkList_doubly& push_front(T n);LinkList_doubly& insert(int pos, int n, T* arr);LinkList_doubly& pop_front();LinkList_doubly& pop_back();LinkList_doubly& remove(int pos, int num);LinkList_doubly& reverse();T& operator[](int n);T& at(int n);LinkList_doubly& replace(int pos, int n, T* arr);int getLen() {return len;}void clear() {this->~LinkList_doubly();}void display();
private:int len = 0;Node* getNode_next(int n);};//默认构造函数
template 
LinkList_doubly::LinkList_doubly() {firstNode = nullptr;lastNode = nullptr;len = 0;
}//一般构造函数,用数组进行初始化
template 
LinkList_doubly::LinkList_doubly(int n, const T* arr) {Node* temp1 = nullptr;Node* temp2 = nullptr;for (int i = 0; i < n; i++) {temp1 = new Node (arr[i]);if ( i == 0 )firstNode = temp1;if ( i == n-1 )lastNode = temp1;temp1->prior = temp2;if ( i > 0 )temp2->next  = temp1;temp2 = temp1;}this->len = n;
}//拷贝构造函数
template 
LinkList_doubly::LinkList_doubly(const LinkList_doubly& link) {this->firstNode = link.firstNode;this->lastNode  = link.lastNode;this->len = link.getLen();
}//析构函数
template 
LinkList_doubly::~LinkList_doubly() {this->len = 0;Node* temp = firstNode;lastNode = nullptr;while ( firstNode ) {temp = firstNode;firstNode = firstNode->next;delete temp;temp = nullptr;}
}//在尾部添加一个元素
template 
LinkList_doubly& LinkList_doubly::push_back(T n) {Node* newNode = new Node (n);newNode->prior = lastNode;lastNode->next = newNode;lastNode = newNode;len++;return *this;
}//在头部添加一个元素
template 
LinkList_doubly& LinkList_doubly::push_front(T n) {Node* newNode = new Node (n);newNode->next = firstNode;firstNode->prior = newNode;firstNode = newNode;len++;return *this;
}//在position位置插入n个元素
template 
LinkList_doubly& LinkList_doubly::insert(int pos, int n, T* arr) {Node* temp_end = getNode_next(pos);Node* temp_front = getNode_next(pos-1);Node* temp_new = nullptr;for ( int i = 0; i < n; i++ ) {temp_new = new Node (arr[i]);temp_front->next = temp_new;temp_new->prior = temp_front;temp_front = temp_front->next;}temp_front->next = temp_end;temp_end->prior = temp_front;len += n;return *this;
}//删除第一个元素
template 
LinkList_doubly& LinkList_doubly::pop_front() {firstNode = firstNode->next;firstNode->prior = nullptr;len--;return *this;
}//删除最后一个元素
template 
LinkList_doubly& LinkList_doubly::pop_back() {lastNode = lastNode->prior;lastNode->next = nullptr;len--;return *this;
}//删除position开始的num个元素
template 
LinkList_doubly& LinkList_doubly::remove(int pos, int num) {Node* temp_front = getNode_next(pos-1);Node* temp_end = getNode_next(pos+num);temp_front->next = temp_end;temp_end->prior = temp_front;len -= num;return *this;
}//替换元素
template 
LinkList_doubly& LinkList_doubly::replace(int pos, int n, T* arr) {Node* temp = getNode_next(pos);for ( int i = 0; i < n; i++ ) {temp->value = arr[i];temp = temp->next;}return *this;
}//反转链表,终极偷懒写法,实在不想动脑子了
template 
LinkList_doubly& LinkList_doubly::reverse() {const int num = len;T arr[num];Node* temp = firstNode;for ( int i = 0; i < this->len; i++ ) {arr[i] = temp->value;temp = temp->next;}temp = lastNode;for ( int i = 0; i < this->len; i++ ) {temp->value = arr[i];temp = temp->prior;}return *this;
}//访问第n个元素
template 
T& LinkList_doubly::operator[](int n){Node* temp = nullptr;if ( n <= len/2 ) {temp = firstNode;for ( int i = 0; i < n; i++ ) {temp = temp->next;}} else {temp = lastNode;for ( int i = 0; i < len-1-n; i++ ) {temp = temp->prior;}}return temp->value;}//访问第n个元素,增加索引检查template 
T& LinkList_doubly::at(int n){if ( n < 0 || n > len-1 ) {cout << "[error]:index out of range" << endl;exit(0);}return (*this)[n];
}
//获取第n个Node的next指针
template 
Node* LinkList_doubly::getNode_next(int n) {if ( n > len-1 ) {cout << "[error]: illegal index" << endl;}Node* temp = firstNode;for ( int i = 0; i < n; i++ ) {temp = temp->next;}return temp;
}//显示链表所有元素,会对链表正反向一致性进行检查
template 
void LinkList_doubly::display() {const int num = len;T arr1[num];T arr2[num];Node* temp = firstNode;for ( int i = 0; i < this->len; i++ ) {arr1[i] = temp->value;temp = temp->next;}temp = lastNode;for ( int i = 0; i < this->len; i++ ) {arr2[i] = temp->value;temp = temp->prior;}for ( int i = 0; i < this->len; i++ ) {if ( arr1[i] != arr2[len-1-i] ) {cout << "第"<len; i++ ) {cout << temp->value << " ";temp = temp->next;}cout << endl;
}int main() {int arr[] = {1,5,7,3,5,3,1};LinkList_doubly link(sizeof(arr)/sizeof(int), arr);link.display();link.push_back(25);link.display();link.push_front(10);link.display();int arr2[] = {1,0,0,4};link.insert(2,sizeof(arr2)/sizeof(int), arr2);link.display();link.pop_front();link.display();link.pop_back();link.display();link.remove(2,2);link.display();int arr3[] = {2,3,5};link.replace(4, sizeof(arr3)/sizeof(int), arr3);link.display();link.reverse();link.display();cout << link[8] << " " << link.at(3) << endl;cout << link.getLen() << endl;link.~LinkList_doubly();cout << link.getLen() << endl;}

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...