自己实现c++ list模板类,亲测可用

2023-11-08

双向链表模板类

dlist.h

#ifndef DLIST_H
#define DLIST_H
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;

template<typename T> 
class DList
{
	struct node{
    T data;
    node* next;
    node* prev;
    };
    node *head = NULL;
    node *tail = NULL;
    int len;
public:
	
	//缺省构造函数 
    DList(){
    	len = 0;
    }
    
    //拷贝构造函数 
    DList(const DList &l){  
	    len = 0; 	
        if(l.head!=NULL){        	
            node *pHc = l.head;      //链表l节点指针 
            head = new node();       //为新链表头节点申请空间
            head->data = pHc->data;  //新链表头结点赋值 
            node *pH = head;         //新链表节点指针 
            len++;
            while(pHc!=l.tail){
            	pHc = pHc->next;
                pH->next = new node(); //为新节点分配内存,当前节点的next指针指向新节点
                pH->next->prev = pH; //新节点的prev指针指向当前节点 
                pH = pH->next;                
				pH->data = pHc->data;  
				len++;              
            }            
        }
        else{
            head=tail=NULL;
        }
    }
    
    //赋值运算符重载函数 
    DList& operator = (const DList &l){
    	len = 0;
        if (this == &l){
            return *this;
        }
        len = 0; 	
        if(l.head!=NULL){        	
            node *pHc = l.head;      //链表l节点指针 
            head = new node();       //为新链表头节点申请空间
            head->data = pHc->data;  //新链表头结点赋值 
            node *pH = head;         //新链表节点指针 
            len++;
            while(pHc!=l.tail){
            	pHc = pHc->next;
                pH->next = new node(); //为新节点分配内存,当前节点的next指针指向新节点
                pH->next->prev = pH; //新节点的prev指针指向当前节点 
                pH = pH->next;                
				pH->data = pHc->data;  
				len++;              
            }            
        }
        else{
            head=tail=NULL;
        }
        return *this;
    }
    
    //析构函数 
    ~DList(){
        node *bgn = head;
        while(head!=tail)
        {
            head = head->next;
            delete bgn;//释放内存
            bgn = head;
        }
        len = 0;
    }
    
    int size(){
    	return len;
	}
	void print(){
		for(int i=0;i<len;i++){
	        cout<<at(i)<<" ";  	
		} 
		cout<<endl;
	}
    
    //在尾部添加节点 
    void push_back(T data){
        if(head==NULL){
                head = new node();
                head->data = data;
                len++;
                tail = head;
        }
        else{
            tail->next = new node();
            tail->next->data = data;
            len++;
            tail->next->prev = tail;
            tail = tail -> next;
        }
        return;
    }
    
    //取出节点(按下标) 
    T at(int index){
        node *p;
        p = head;
        if(index>=len)
            throw out_of_range("in at(int index) index out of range");
        else{
            for(int i=0;i<index;i++)
                p = p->next;
        }
        return p->data;
    }
    
    //查找节点 
    int indexOf(T _data){
    	int index = 0;
	    node *p = head;
		while(p->data != _data){ 
			p = p->next;
			index++;
		} 
		if(index >= len) 
		    return -1;
		else
		    return index;
	} 
	//删除节点 
    void removeAt(int index){
    	node *p;
        p = head;
        if(index >= len)
            throw out_of_range("in removeAt(int index) index out of range");             
        else{
        	//移动到要删除的节点处 
            for(int i=0;i<index;i++){
            	p = p->next;
			}               
            p->prev->next = p->next;
            p->next->prev = p->prev;
            delete p;
            p = NULL;
            len--; 
        }  
		return;     
	}
    void clear(){
    	node *bgn = head;
        while(head!=tail)
        {
            head = head->next;
            delete bgn;//释放内存
            bgn = head;
        }
        len = 0;
	}
	
	//交换两节点(交换值) 
	void swap(int i, int j){
		T vi = at(i);
		T vj = at(j);		
		node *p;
        p = head;
		for(int k=0;k<i;k++)
            p = p->next;
        p->data = vj;
        p = head;
		for(int k=0;k<j;k++)
            p = p->next;
        p->data = vi;
	} 
	
	//子表划分函数,返回枢轴值 
	int Partition(int low, int high){
		T pivotkey;
		pivotkey = at(low); //用子表的第一个记录作为枢轴记录 
		while(low < high){
			while(low < high && at(high) >= pivotkey)
			    high--;
			swap(low, high);
			while(low < high && at(low) <= pivotkey)
			    low++;
			swap(low, high);  
		}
		return low;
	}
    
    //快速排序递归函数 
    void QSort(int low, int high){
    	int pivot;
    	if(low < high){
    		pivot = Partition(low,high);
    		QSort(low,pivot-1);
    		QSort(pivot+1,high);
		}
	}
	//快速排序
    void QuickSort(){
        QSort(0,len-1);	
	}

};

#endif // DLIST_H

测试类型为 DList< std::string >

main.cpp

#include <iostream>
#include "dlist.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char** argv) {	 
    try { 
    DList<string> list; 
    list.push_back("a");
    list.push_back("b");
    list.push_back("c");
    list.push_back("d");
    list.push_back("e");
    list.push_back("f");
    list.push_back("g");
    list.push_back("h"); 
	cout<<"【测试 push_back】 ";   
	list.print();
	 
	DList<string> list2(list); 	
	cout<<"【测试 拷贝构造函数】 "; 
    list2.print(); 
    
    DList<string> list3 = list; 
    cout<<"【测试 运算符重载函数】 ";
    list3.print(); 
	  
	cout<<"【测试 indexOf()】 ";  
    cout<<list3.indexOf("c")<<endl;
    
    cout<<"【测试 swap(0,1)】 ";  
    list3.swap(0,1);
    list3.print();
    
    cout<<"【测试 QuickSort】 "; 
	list3.QuickSort(); 
    list3.print(); 
    
    cout<<"【测试 removeAt(4)】 ";  
	list3.removeAt(4);
    list3.print();
    
    cout<<"【测试 clear】 ";  
    list3.clear();
	list3.print(); 
    }
    catch (exception const& ex) {
        cerr << "Exception: " << ex.what() <<endl;
        return -1;
    }
   
    return 0;
}

运行结果

在这里插入图片描述

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

自己实现c++ list模板类,亲测可用 的相关文章

随机推荐

  • Vite 配置 cdn 加载资源

    一 介绍 上篇文章我们从零配置 Vite Vue3 0 开发环境 生产环境 本篇文章我们配置 CDN 加载 因为 Vite 不会重写从外部文件导入的内容 我们需要使用支持 ESM 编译的 CDN 这里我们使用 https esm sh 来引
  • GDCM:GDCM::DataSet的测试程序 C/C++

    GDCM GDCM DataSet的测试程序 C C GDCM Grassroots DICOM 是一个用于处理医学影像和通信的开源软件库 它提供了各种功能 包括读取 写入 转换和处理DICOM 数字影像和通信医学 文件 GDCM库是用C
  • DGL-KE:亚马逊开源知识图谱嵌入库

    这个库的开源已经是去年 2020 的事情了 突然感觉时间好快 当时并没有在意 最近关注到这个库是因为自己在训练知识图谱 Embedding 的时候做的一些调研 考虑到后续大规模知识图谱的训练 需要更快的开源库 于是DGL KE 重新回到我的
  • Spring(二):更简单的存储与读取 Bean

    通过上一章的Spring 我们基本实现了Spring 的读取与存储 但是在操作过程中 读取与存储并没有那么得 简单 一套流程还是很复杂 所以 本章来介绍更加简单得读取与存储 在 Spring 中想要更简单的存储和读取对象的核 是使 注解 也
  • Zabbix 5.0 媒体介质 邮箱配置例子

    QQ企业邮箱 参考 zabbix 腾讯企业邮箱配置图 harveymomo的博客 CSDN博客
  • 程序和功能 没有hyper v_Win10系统hyper-v虚拟机如何关闭?这三种方法麻烦收好

    hyper v很多用户不清楚这是什么 用官方说法是微软的一款虚拟化产品 简单来说就是虚拟机 可以用来安装其他系统 这个功能在Win10和Win8 1中是预设的 对于Win10用户而言此项功能没有多少必要性 那么要如何关闭呢 下面小编就跟大家
  • 求二叉树中最大和的路径(C语言实现)

    目录 1 题目概述 2 题目解析 3 题目代码 4 样例展示 5 题目总结 1 题目概述 假设二叉树中的所有节点值为int类型 采用二叉链表存储 设计递归算法求二叉树bt中从根结点到叶子结点路径和最大的一条路径 例如 对于下图所示的二叉树
  • 成为大厂offer收割机是怎样一种体验?

    一 现状 市场红利正盛 人才短板暴露 计算机的发展历程已经走过了大半个世纪 在当前的互联网 时代下 中国开发者市场正在迎来三大红利 全民编程 行业升级 技术大生态 人人都会编程 家家都是技术公司 全行业数字化升级 面对大量的需求 目前IT人
  • 用户画像常见应用场景+技术实现

    导读 今天和大家分享的主题是用户画像的场景与技术实现方案 主要分三大部分 用户画像常见应用场景 画像产品功能 技术实现方案 01 常见应用场景 1 画像常见的应用场景 不同行业业务属性不同 能采集到的数据源也不同 对画像的应用场景有不同的需
  • 代码随想录算法训练营第一天

    文章目录 数组704 二分查找 题目 难度 示例 算法 二分查找法 循环不变量 两种写法 疑难点分析 算法复杂度分析 数组27 移除元素 题目 难度 示例 算法 暴力 双指针 数组704 二分查找 梦开始的地方 day1 2023 4 19
  • 基于MATLAB的图片中字符的分割与识别

    基于MATLAB的字符的分割与识别 摘 要 本文主要介绍字符识别的基本原理 并且利用MATLAB工具软件实现图片中字符的分割和识别 对于满足一定要求的图片可以实现字符的分割与识别 通过图像读取 图像预处理 图像投影 字符分割 字符识别五个步
  • 一维数组部分实验

    学习目标 1 理解数组的概念 掌握数组的定义及其存储结构 2 掌握一维数组的输入 输出及初始化的方法 3 掌握一维数组的使用 4 掌握与数组有关的算法 学习内容 1 编写程序 将10个整型数2 4 6 18 20赋予一个数组 然后输出该数组
  • 【C语言】初识指针

    C语言 初识指针 一 指针是什么 二 指针和指针类型 1 指针 整数 2 指针的解引用 三 野指针 1 野指针成因 2 如何规避野指针 四 指针运算 五 二级指针 七 指针数组 个人主页 库库的里昂 CSDN新晋作者 欢迎 点赞 评论 收藏
  • c的按位取反运算符(~) 与逻辑逻辑(!)

    位运算 位运算的运算分量只能是整型或字符型数据 位运算把运算对象看作是由二进位组成的位串信息 按位完成指定的运算 得到位串信息的结果 位运算符有 按位与 按位或 按位异或 按位取反 其中 按位取反运算符是单目运算符 其余均为双目运算符 位运
  • ffmpeg 采集音频数据

    音视频数据采集的步骤 设备注册 设置对应的采集方式 avfoundation dshow alas 打开设备 具体的例子 include
  • 什么是导航与位置服务器,GPS导航和GPS定位仪与GPS定位器的区别在哪?

    也许很多人时常都能听到GPS定位器 GPS导航 GPS定位仪这三个词 但都不是很了解GPS定位器 GPS导航和GPS定位仪这三者间的区别 往往都很模糊 那么 这三者到底分别是什么设备 又有哪些我们不知道的区别呢 一 GPS导航 但凡是自己有
  • 学成在线笔记+踩坑(2)——【内容模块】课程基础查询,swagger+数据库字典+Httpclient+跨域

    导航 黑马Java笔记 踩坑汇总 JavaSE JavaWeb SSM SpringBoot 瑞吉外卖 SpringCloud 黑马旅游 谷粒商城 学成在线 牛客面试题 java黑马笔记 目录 1 内容模块 需求分析 2 内容模块 模块工程
  • jdbc链接mysql8的url

    jdbc链接mysql8的url 使用jar或者maven依赖不同 java与mysql8 0连接Jdbc驱动的配置参数 驱动 driver com mysql cj jdbc Driver 字符串 jdbc url jdbc mysql
  • redis 缓存击穿 看一篇成高手系列3

    什么是缓存击穿 在谈论缓存击穿之前 我们先来回忆下从缓存中加载数据的逻辑 如下图所示 因此 如果黑客每次故意查询一个在缓存内必然不存在的数据 导致每次请求都要去存储层去查询 这样缓存就失去了意义 如果在大流量下数据库可能挂掉 这就是缓存击穿
  • 自己实现c++ list模板类,亲测可用

    双向链表模板类 dlist h ifndef DLIST H define DLIST H include