单链表的实现(cpp)

2023-11-03

单链表的实现(cpp版本)

链表节点的定义

template <class T>
struct LinkNode //节点类
{
    T Data;         //节点的数据
    LinkNode *Next; //指向该节点的下一个节点的指针
    LinkNode() : Next(NULL)
    {
        cout << "please enter data: ";
        cin >> Data;
    }
    LinkNode(const T &d, LinkNode *p = NULL) : Data(d), Next(p) {}
    ~LinkNode() {}
};

链表实例化

template <class T>
SingleLinkedList<T>::SingleLinkedList(int len)
{
    LinkNode<T> *Cur;
    for (size_t i = 0; i < len; i++)
    {
        Cur = new LinkNode<T>();
        if (i == 0)
        {
            Head = Cur;
            Tail = Cur;
        }
        else
        {
            Tail->Next = Cur;
            Tail = Tail->Next;
        }
        ListSize++;
    }
}

删除链表的某一节点

template <class T>
void SingleLinkedList<T>::Delete(const T &Data)
{
    LinkNode<T> *Prev = this->Head;
    LinkNode<T> *Temp = nullptr;
    if (this->Head->Data == Data)
    {
        this->Head = Prev->Next;
        Prev->Next = nullptr;
        free(Prev);
        ListSize--;
    }

    while (Prev->Next != nullptr && Prev->Next->Data != Data)
    {
        Prev = Prev->Next;
    }
    if (Prev->Next != nullptr && Prev->Next != this->Tail)
    {
        Temp = Prev;
        Temp->Next = Prev->Next->Next;
        free(Prev->Next);
        ListSize--;
    }
    else
    {
        this->Tail = Prev;
        this->Tail->Next = nullptr;
        free(Prev->Next);
        ListSize--;
    }
}

删除整个链表

template <class T>
void SingleLinkedList<T>::DeleteList()
{
    LinkNode<T> *Temp, *DeleteTemp;
    DeleteTemp = this->Head;
    while (DeleteTemp != nullptr)
    {
        Temp = DeleteTemp->Next;
        free(DeleteTemp);
        DeleteTemp = Temp;
        ListSize--;
    }
    Head = nullptr;
    Tail = nullptr;
}

插入头节点

template <class T>
void SingleLinkedList<T>::InsertHead(const T &data)
{
    LinkNode<T> *temp = new LinkNode<T>(data);
    if (Head == nullptr)
    {
        Head = temp;
        Tail = temp;
    }
    else
    {
        temp->Next = Head;
        Head = temp;
    }
    // 局部变量不需要free,除非使用malloc申请时
    ListSize++;
}

插入到尾节点

template <class T>
void SingleLinkedList<T>::InsertTail(const T &data)
{
    LinkNode<T> *temp = new LinkNode<T>(data);
    if (Head == nullptr)
    {
        Head = temp;
        Tail = temp;
    }
    else
    {
        Tail->Next = temp;
        Tail = Tail->Next;
    }
    ListSize++;
}

SingleLinkedList.h

#pragma once
#include <iostream>
using namespace std;

template <class T>
struct LinkNode //节点类
{
    T Data;         //节点的数据
    LinkNode *Next; //指向该节点的下一个节点的指针
    LinkNode() : Next(NULL)
    {
        cout << "please enter data: ";
        cin >> Data;
    }
    LinkNode(const T &d, LinkNode *p = NULL) : Data(d), Next(p) {}
    ~LinkNode() {}
};
template <class T>
class SingleLinkedList
{
    LinkNode<T> *Head = nullptr; //首尾指针
    LinkNode<T> *Tail = nullptr;
    int ListSize = 0; //链表长度
public:
    SingleLinkedList(int Len = 0); //构造函数(顺序插入)
    ~SingleLinkedList()            //析构函数
    {
        DeleteList(); //释放new出来的节点
    }
    void DeleteList();
    void Delete(const T &Data); //可以使用&也可以不用,删除指定的一个元素
    bool IsEmpty() const
    {
        return ListSize == 0;
    }
    bool IsLast(LinkNode<T> *Node)
    {
        return Node == Tail;
    }
    int GetLength() const //返回链表长度
    {
        return ListSize;
    }
    int Find(const T &Data) const;                       //寻找链表中是否存在该值,存在返回其位置,不存在则返回-1,如果有重复则返回第一个找到的元素
    LinkNode<T> *FindPosition(const int position) const; //查看positio位置链表的值,若该位置不在链表中,则返回nullptr(position从0开始计数)
    void InsertHead(const T &Data);
    void InsertTail(const T &Data);
    void Reverse();         //反转链表
    void PrintList() const; //打印链表数据
};

#include "SingleLinkedList.cpp" //模板实现文件,包含编译模型

SingleLinkedList.cpp

template <class T>
SingleLinkedList<T>::SingleLinkedList(int len)
{
    LinkNode<T> *Cur;
    for (size_t i = 0; i < len; i++)
    {
        Cur = new LinkNode<T>();
        if (i == 0)
        {
            Head = Cur;
            Tail = Cur;
        }
        else
        {
            Tail->Next = Cur;
            Tail = Tail->Next;
        }
        ListSize++;
    }
}

template <class T>
void SingleLinkedList<T>::DeleteList()
{
    LinkNode<T> *Temp, *DeleteTemp;
    DeleteTemp = this->Head;
    while (DeleteTemp != nullptr)
    {
        Temp = DeleteTemp->Next;
        free(DeleteTemp);
        DeleteTemp = Temp;
        ListSize--;
    }
    Head = nullptr;
    Tail = nullptr;
}
template <class T>
void SingleLinkedList<T>::Delete(const T &Data)
{
    LinkNode<T> *Prev = this->Head;
    LinkNode<T> *Temp = nullptr;
    if (this->Head->Data == Data)
    {
        this->Head = Prev->Next;
        Prev->Next = nullptr;
        free(Prev);
        ListSize--;
    }

    while (Prev->Next != nullptr && Prev->Next->Data != Data)
    {
        Prev = Prev->Next;
    }
    if (Prev->Next != nullptr && Prev->Next != this->Tail)
    {
        Temp = Prev;
        Temp->Next = Prev->Next->Next;
        free(Prev->Next);
        ListSize--;
    }
    else
    {
        this->Tail = Prev;
        this->Tail->Next = nullptr;
        free(Prev->Next);
        ListSize--;
    }
}
template <class T>
int SingleLinkedList<T>::Find(const T &Data) const
{
    LinkNode<T> *Temp = this->Head;
    int position = 0;
    while (Temp != nullptr && Temp->Data != Data)
    {
        Temp = Temp->Next;
        position++;
    }
    if (Temp == nullptr)
        return -1;
    else
        return position;
}
template <class T>
LinkNode<T> *SingleLinkedList<T>::FindPosition(const int position) const
{
    if (position > ListSize)
        return nullptr;
    LinkNode<T> *Temp = this->Head;
    for (int i = 0; i < position; i++)
    {
        Temp = Temp->Next;
    }
    return Temp;
}
template <class T>
void SingleLinkedList<T>::InsertHead(const T &data)
{
    LinkNode<T> *temp = new LinkNode<T>(data);
    if (Head == nullptr)
    {
        Head = temp;
        Tail = temp;
    }
    else
    {
        temp->Next = Head;
        Head = temp;
    }
    // 局部变量不需要free,除非使用malloc申请时
    ListSize++;
}
template <class T>
void SingleLinkedList<T>::InsertTail(const T &data)
{
    LinkNode<T> *temp = new LinkNode<T>(data);
    if (Head == nullptr)
    {
        Head = temp;
        Tail = temp;
    }
    else
    {
        Tail->Next = temp;
        Tail = Tail->Next;
    }
    ListSize++;
}
template <class T>
void SingleLinkedList<T>::Reverse()
{
    if (this->Head == this->Tail)
        return;
    this->Tail = this->Head;
    LinkNode<T> *Prev = this->Head;
    LinkNode<T> *Cur = Prev->Next;
    while (Cur != nullptr)
    {
        LinkNode<T> *Temp = Cur->Next;
        Cur->Next = Prev;
        Prev = Cur;
        Cur = Temp;
    }
    this->Head = Prev;
    this->Tail->Next = nullptr;
}
template <class T>
void SingleLinkedList<T>::PrintList() const
{
    int n = 0;
    LinkNode<T> *temp = this->Head;
    while (temp != nullptr)
    {
        cout << "第" << n++ << "个:" << temp->Data << endl;
        temp = temp->Next;
    }
}

test.cpp

#include "SingleLinkedList.h"
#include <iostream>
#include <string>

int main()
{
    system("chcp 65001");
    SingleLinkedList<int> intList(3);
    intList.PrintList();
    cout << "链表的长度是:" << intList.GetLength() << endl;
    intList.InsertHead(3);
    intList.PrintList();
    cout << "链表的长度是:" << intList.GetLength() << endl;
    intList.InsertTail(300);
    intList.PrintList();
    cout << "链表的长度是:" << intList.GetLength() << endl;
    cout << "元素2在位置" << intList.Find(2) << endl;
    cout << "第3个位置是元素" << intList.FindPosition(3)->Data << endl;
    intList.Delete(300);
    intList.PrintList();
    intList.DeleteList();
    intList.PrintList();
    cout << "链表的长度是:" << intList.GetLength() << endl;
    SingleLinkedList<string> stringList(2);
    stringList.PrintList();
    cout << "链表的长度是:" << stringList.GetLength() << endl;
    cout << "元素abc在位置" << stringList.Find("abc") << endl;
    cout << "第1个位置是元素" << stringList.FindPosition(1)->Data << endl; //-1代表不存在该元素
    stringList.InsertHead("a");
    stringList.PrintList();
    cout << "链表的长度是:" << stringList.GetLength() << endl;
    stringList.InsertTail("abc");
    stringList.PrintList();
    cout << "元素abc在位置" << stringList.Find("abc") << endl;
    stringList.Reverse();
    stringList.PrintList();
    cout << "链表的长度是:" << stringList.GetLength() << endl;
    return 0;
}

测试后
在这里插入图片描述

参考:
https://michael.blog.csdn.net/article/details/88370698
https://blog.csdn.net/weixin_42136837/article/details/113411695
https://zhuanlan.zhihu.com/p/51855842

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

单链表的实现(cpp) 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 在一个数据访问层中处理多个连接字符串

    我有一个有趣的困境 我目前有一个数据访问层 它必须与多个域一起使用 并且每个域都有多个数据库存储库 具体取决于所调用的存储过程 目前 我只需使用 SWITCH 语句来确定应用程序正在运行的计算机 并从 Web config 返回适当的连接字
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置

随机推荐