c++双链表【构造函数、运算符重载、析构函数、增删查改及逆置等】

2023-11-06

c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等)

建立头文件SList.h

#pragma once

typedef int DataType;
class ListNode
{
	friend class List;//友元函数
public:
	ListNode(const DataType x)
		:_data(x)
		, _prev(NULL)
		, _next(NULL)
	{}
private:
	DataType _data;
	ListNode* _prev;
	ListNode* _next;
};
class List
{
public:
	List()
		:_head(NULL)
		, _tail(NULL)
	{}
	//深拷贝
	List(const List& s)
		:_head(NULL)
		, _tail(NULL)
	{
		ListNode* tmp = s._head;
		while (tmp)
		{
			this->PushBack(tmp->_data);
			tmp = tmp->_next;
		}
	}
	//现代写法
	List& operator=(List& s)
	{
		swap(_head, s._head);
		swap(_tail, s._tail);
		return *this;
	}
public:
	void Clear();
	void PrintList();
	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();
	List Reverse();
private:
	ListNode* _head;
	ListNode* _tail;
};

各函数的实现

#include<iostream>
using namespace std;

#include"List.h"
#include<assert.h>

void List::Clear()//清除双链表
{
	ListNode* cur = _head;
	while (cur)
	{
		ListNode* del = cur;
		cur = cur->_next;
		delete del;
		del = NULL;
	}
}

void List::PrintList()//打印双链表
{
	ListNode* cur=_head;
	while (cur)
	{
		cout << cur->_data << "->";
		cur = cur->_next;
	}
	cout << "NULL" << endl;
}

void List::PushBack(DataType x)//尾插
{
	if (NULL == _head)
	{
		_head = new ListNode(x);
		_tail = _head;
	}
	else
	{
		ListNode* tmp = new ListNode(x); 
		_tail->_next = tmp;
		tmp->_prev = _tail;
		tmp->_next = NULL;
		_tail = tmp;
	}
}

void List::PopBack()//尾删
{
	if (NULL == _head)
	{
		cout << "List is empty!" << endl;
	}
	else if (_head == _tail)
	{
		delete _head;
		_head = _tail = NULL;
	}
	else
	{//相比单链表方便找到尾节点的前一个节点
		ListNode* cur = _tail;
		_tail = cur->_prev;
		_tail->_next = NULL;
		delete cur;
		cur = NULL;
	}
}

void List::PushFront(DataType x)//头插
{
	ListNode* tmp = _head;
	_head = new ListNode(x);
	_head->_prev = NULL;
	_head->_next = tmp;
}

void List::PopFront()//头删
{
	if (NULL == _head)
	{
		cout << "SList is empty!" << endl;
	}
	else if (NULL == _head->_next)
	{
		delete _head;
		_head = NULL;
	}
	else
	{
		ListNode* tmp = _head->_next;
		delete _head;
		_head = tmp;
		tmp->_prev = NULL;
	}
}

ListNode* List::Find(DataType x)//查找x
{
	ListNode* cur = _head;
	while (cur)
	{
		if (x == cur->_data)
			return cur;
		cur = cur->_next;
	}
	return NULL;
}

void List::Insert(ListNode* pos, DataType x)//指定位置处插入x
{
	assert(pos);
	if (NULL == pos->_next)
		List::PushBack(x);
	else if (_head == pos)
		List::PushFront(x);
	else
	{
		ListNode* cur = new ListNode(x);
		ListNode* prev = pos->_prev;
		prev->_next = cur;
		cur->_prev = prev;
		cur->_next = pos;
		pos->_prev = cur;
	}
}

void List::Erase(ListNode* pos)//删除结点pos
{
	assert(pos);
	if (NULL == pos->_next)
		List::PopBack();
	else if (_head == pos)
		List::PopFront();
	else
	{
		ListNode* prev = pos->_prev;
		ListNode* next = pos->_next;
		next->_prev = prev;
		prev->_next = next;
	    delete pos;
		pos = NULL;
	}
}
//逆置双链表
//通过两个指针,从两边向中间移动,交换所储蓄内容
//void List::Reverse()
//{
//	ListNode* begin = _head;
//	ListNode* end = _tail;
//	//奇数个节点时两个指针相等时结束循环;偶数个节点时两个指针发生交叉时结束循环
//	while (begin != end && begin->_prev != end)
//	{
//		swap(begin->_data, end->_data);
//		begin = begin->_next;
//		end = end->_prev;
//	}
//}

//交换头尾指针,交换每个结点的前驱和后继
//void List::Reverse()
//{
//	swap(_head, _tail);
//	ListNode* cur = _head;
//	while (cur)
//	{
//		swap(cur->_prev,cur->_next);
//		cur = cur->_next;
//	}
//}

//建立新链表,通过头插法实现
List List::Reverse()
{
	if (NULL == _head)
	{
		cout << "SList is empty!" << endl;
	}
	else if(NULL != _head->_next)
	{
		List NewList;
		ListNode* cur = _head->_next;
		ListNode* tmp = _head;//保存头指针,头插完后使其_next指针指向空
		while (cur)
		{
			this->PushFront(cur->_data);
			cur = cur->_next;
		}
		tmp->_next = NULL;
		return NewList;
	}
	return *this;
}

转载于:https://blog.51cto.com/luoyafei/1748592

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++双链表【构造函数、运算符重载、析构函数、增删查改及逆置等】 的相关文章

  • C++中的RTTI

    文章目录 dynamic cast运算符 指针类型的dynamic cast 引用类型的dynamic cast typeid运算符 使用RTTI type info类 参考资料 RTTI Runtime Type Information
  • 数理统计知识整理——回归分析与方差分析

    题记 时值我的北科研究生第一年下 选学 统计优化 课程 备考促学 成此笔记 以谨记 1 线性回归 1 1 原理分析 要研究最大积雪深度x与灌溉面积y之间的关系 测试得到近10年的数据如下表 使用线性回归的方法可以估计x与y之间的线性关系 线
  • dev-c++官网位置和源码/库位置

    1 http devpaks org 2 http www bloodshed net 3 http www bloodshed net dev 转载于 https www cnblogs com vilyLei articles 1812
  • Linux 内核中的 Device Mapper 机制

    Linux 内核中的 Device Mapper 机制 尹 洋 在读博士生 尹洋 中科院计算所国家高性能计算机工程技术研究中心的在读博士生 主要从事服务部署和存储资源管理以及Linux块设备一级的开发和研究工作 简介 本文结合具体代码对 L
  • 时间复杂度+常见复杂度解释

    前言 算法的效率 虽然计算机能快速的完成运算处理 但实际上 它也需要根据输入数据的大小和算法效率来消耗一定的处理器资源 要想编写出能高效运行的程序 我们就需要考虑到算法的效率 算法的效率主要由以下两个复杂度来评估 时间复杂度 评估执行程序所
  • Linux下进程退出的几种形式

    进程退出 Linux 下进程的退出分为正常退出和异常退出两种 1 正常退出 a 在main 函数中执行return b 调用exit 函数 c 调用 exit 函数 2 异常退出 a 调用about函数 b 进程收到某个信号 而该信号使程序
  • floor(),ceil()函数

    地板 天花板函数 均包含在math h中 意思分别为 返回不大于形参的最小整数和不小于形参的最大整数 include
  • R----dplyr包介绍学习

    dplyr包 plyr包的替代者 专门面对数据框 将ddplyr转变为更易用的接口 gt 来自dplyr包的管道函数 其作用是将前一步的结果直接传参给下一步的函数 从而省略了中间的赋值步骤 可以大量减少内存中的对象 节省内存 可惜的是应用范
  • 模板的完全特例化和部分特例化

    介绍 完全特例化就是类型完全明确的版本 而部分特例化指的是 只知道是几个参数的函数而不知道参数的类型 或者是只知道是引用或者是指针类型 而不知道具体是char 还是 int 模板特例化实例1 template
  • 在聚会中常玩数七的游戏,七的倍数和带有七的数字都不能说,比如14,27,28。请找出1~100的不能说的数字。...

    利用ES5的filter高阶函数来实现 var arr 1 2 3 4 5 6 7 17 27 21 22 28 100 r arr filter function x return x 10 7 x 7 0 alert r 7 14 17
  • 查找数组中第二大的数

    快速找出一个数组中的最大数 第二大数 思路 如果当 前元素大于最大数 max 则让第二大数等于原来的最大数 max 再把当前元素的值赋给 max 如果当前的元素大于等于第二大数secondMax的值而小于最大数max的值 则要把当前元素的值
  • visual studio 一直显示正在准备解决方案

    首先重启电脑 无法解决的情况下执行以下步骤 Kill Visual Studio Open Visual Studio without loading a solution Disable AnkhSvn as Source Control
  • 数组实现循环队列(增设队列大小size)

    目录 一 前言 1 如何实现循环 2 如何判断队列为空 3 如何判断队列为满 二 循环队列的结构定义 三 循环队列的创建及其初始化 四 入队 五 出队 六 取队头元素 七 取队尾元素 八 循环队列判空 九 循环队列判满 十 循环队列销毁 一
  • 【数据结构入门精讲 | 第二篇】一文讲清算法复杂度

    上篇文章中我们引入了算法 数据结构 数据类型等概念 而要想衡量一个算法与数据结构是否为优质的 就需要一个衡量标准 这个衡量标准也是在我们实现一个好的算法时要遵循的原则 目录 基本概念 渐进性态 渐进性态数学表征 算法复杂度的运算 顺序搜索算
  • C 语言教程:数据类型和格式说明符

    C 语言中的数据类型 C 中的变量必须是指定的 数据类型 并且您必须在 printf 函数中使用 格式说明符 来显示它 创建变量 int myNum 5 整数 没有小数点 float myFloatNum 5 99 浮点数 char myL
  • 【数据结构】单链表的定义和操作

    目录 1 单链表的定义 2 单链表的创建和初始化 3 单链表的插入节点操作 4 单链表的删除节点操作 5 单链表的查找节点操作 6 单链表的更新节点操作 7 完整代码 嗨 我是 Filotimo 很高兴与大家相识 希望我的博客能对你有所帮助
  • C++ AVL树(四种旋转,插入)

    C AVL树 四种旋转 插入 一 AVL树的概念及性质 二 我们要实现的大致框架 1 AVL树的节点定义 2 AVL树的大致框架 三 插入 1 插入逻辑跟BST相同的那一部分 2 修改平衡因子
  • 按照层次遍历结果打印完全二叉树

    按照层次遍历结果打印完全二叉树 按照推论结果 l 层首个节点位置 2 h l 1 l 层节点间距 2 h l 1 1 编码实现 public static
  • C++ 中 const 和 constexpr 关键字解析:常量、函数和指针

    很多 C 的初学者看到 const 这个关键字的第一反应都是一头雾水 主要是因为 const 可 以出现在很多的位置 以及后面加入的 constexpr 更是常常感到困惑 今天就为大家一一解释出现它们的含义和以及作用 const 关键字 c
  • C++实现函数重载的原理

    一 函数重载的概念 C 中允许存在同名函数 但要求函数参数的类型 个数不同 这些同名函数就称为函数的重载 void func int a int b cout lt lt func int a int b lt lt endl void f

随机推荐

  • angularJS懒加载实现

    angularJS懒加载 主要是分担首页文件加载效率提高渲染性能 实现要点 1 项目模块化 使用import export 进行模块化 2 路由 使用ui router进行路由切换 3 模块异步加载 1 使用import 实现文件动态加载
  • ​LeetCode刷题实战479:最大回文数乘积

    算法的重要性 我就不多说了吧 想去大厂 就必须要经过基础知识和业务逻辑面试 算法面试 所以 为了提高大家的算法能力 这个公众号后续每天带大家做一道算法题 题目就从LeetCode上面选 今天和大家聊的问题叫做 最大回文数乘积 我们先来看题面
  • 批处理获取管理员权限

    废话少说 先上代码 echo off BatchGotAdmin REM gt Check for permissions IF PROCESSOR ARCHITECTURE EQU amd64 gt nul 2 gt 1 SYSTEMRO
  • TCP/IP体系结构简介

    一 网络体系的构成 访问方式 数据帧格式 布线类型 布线规则 二 网络体系的类型 IEEE 802 3 以太网 在大多数办公室和家庭中使用的基于线缆的网络 就是常见的有线局域网 IEEE 802 11 无线网络 在办公室 家庭和咖啡厅使用的
  • 如何下载和安装 Visual C++6.0(解决未响应版)

    下载链接一 https pan baidu com s 1VEggDaoKgt0ZW8Q5wSu zQ 提取码 4chy 下载链接二 https dl pconline com cn download 413670 html
  • 行列式&矩阵_MD&Latex

    行列式 left begin array cccc 1 6 9 7 90 f x 9 psi x g x end array right left begin array cccc 1 6 9 7 90 f x 9 psi x g x en
  • 使用mklink突破百度网盘等软件的自动备份文件夹数量限制

    百度网盘 夸克等各种网盘都提供了自动备份文件夹的功能 但一般都有文件夹数量的限制 比如百度网盘就限制了最多只能同时备份5个文件夹 想整盘备份的话显然是不够的 当然 你可以把所有的文件夹都转移到一个母文件夹下 但这样明显不太方便 操作起来还涉
  • 解决idea中maven的javaweb项目,输出在控制台上的中文乱码问题

    在idea中创建一个maven的javaweb项目 当有中文输出到控制台的时候 就会出现乱码 下图 第一张图是我们要输出的中文 但是我们通过servlet访问之后 控制台打印出来的都是乱码 而且我们使用的是maven自带的tomcat 所以
  • 6.6 Hessenberg法求特征值

    文章目录 1 Gram Schmidt正交化的缺点 2 Hessenberg矩阵 3 海森堡化简 Hessenberg reduction 4 Givens rotation 5 多次Givens rotation QR 6 循环QR直至收
  • Java并发编程学习11-任务执行演示

    Java并发编程学习系列 任务执行演示 引言 1 串行的页面渲染器 2 携带结果的任务 3 使用 Future 实现页面渲染器 4 使用 CompletionService 实现页面渲染器 5 为任务设置时限 5 1 限时获取广告信息示例
  • Qt线程基础使用指南

    Qt的线程一共3种使用方式 继承QThread 继承QRunnable 调用moveToThread 方法 本文旨在系统的记录这3种方法的使用过程 以及解决使用这些方法中遇到的bug 一 继承QThread 1 创建线程文件 继承基类QTh
  • day02 - Java基础语法

    day02 Java基础语法 0 类型转换问题 类型转换 理解 在Java中 会存在不同类型的数据需要一起参与运算 所以这些数据类型之间是需要相互转换的 分为两种情况 自动类型转换和强制类型转换 自动类型转换 类型范围小的变量 可以直接赋值
  • 手机探测帧频率的测试

    手机的探测帧的频率在802 11协议里面并没有一个详细的要求 并且各个厂家从省电等方面考虑设置的探测帧频率也各不相同 并且在wifi界面下 锁屏状态下 忽略掉wifi再锁屏的状态下探测帧的频率都不同 所以wifi探针并不是一个可靠的用户感知
  • FPGA实战小项目

    1 基于fpga俄罗斯方块的实现 基于fpga俄罗斯方块的实现 2 基于fpga白平衡的实现 基于fpga白平衡的实现 3 基于fpga的目标跟踪 树叶 基于fpga的目标跟踪 树叶 4 基于fpga数字0 9识别的实现 基于fpga数字0
  • HCNP——水平分割、毒性逆转、触发更新、毒性路由

    一 水平分割 原理是 RIP路由器从某个接口收到的路由不会再从该接口通告回去 这个机制很大程度上消除了RIP路由的环路隐患 二 毒性逆转 毒性逆转是另一种防止路由环路的有效机制 其原理是 RIP从某个接口学到路由后 当他从该接口发送Resp
  • linux的mtime的用法,Find–atime –ctime –mtime的用法与区别总结

    周五有同事问起find命令中 mtime n mtime n以及 mtime n的用法区别 当时虽然记得这里n是n个24个小时的意思 也是对所有这几个属性详细的用法却一知半解 索性周末仔细google并且实践了一番 终于理清楚了个中乾坤 f
  • SpringBoot分布式任务调度,可支持rabbitmq与kafka两种消息中间件的可回滚微服务实现。

    分布式任务调度管理 Distribution task center 支持Rabbit与kafka两种消息队列 实现立即执行与根据CronExpress表达式的执行及更加复杂的复合执行策略 在任务执行过程中可完成回滚操作 在微服务中我们经常
  • MyBatis-动态SQL

    实体类Car package com bjpowernode domain public class Car private Integer id private String carNum private String brand pri
  • qt 一个线程接收数据 主线程更新界面 会造成界面退出 怎么解决_打造一个好产品

    原标题 打造一个好产品 让产品自己说话 编辑导语 一个好的产品 关键在于产品经理和团队 产品经理对于产品如何理解以及产品更新迭代时的需求变化 产品如何实现更好的体验等等 本文作者分享了关于产品经理经常犯的七个问题 我们一起来看一下 不管怎么
  • c++双链表【构造函数、运算符重载、析构函数、增删查改及逆置等】

    c 中的双向链表写法 主要实现 增删查改 链表逆置 构造函数 运算符重载 等 建立头文件SList h pragma once typedef int DataType class ListNode friend class List 友元