【C++】单链表——单链表的基本操作

这篇具有很好参考价值的文章主要介绍了【C++】单链表——单链表的基本操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、单链表的定义

 由于顺序表的插入删除操作需要移动大量的元素,影响了运行效率,因此引入了线性表的链式存储——单链表。单链表通过一组任意的存储单元来存储线性表中的数据元素,不需要使用地址连续的存储单元,因此它不要求在逻辑上相邻的两个元素在物理位置上也相邻。

单链表的特点:

  • 单链表不要求逻辑上相邻的两个元素在物理位置上也相邻,因此不需要连续的存储空间
  • 单链表是非随机的存储结构,即不能直接找到表中某个特定的结点。查找某个特定的结点时,需要从表头开始遍历,依次查找。

优点:

  • 支持动态内存分配。由于单链表不需要预先分配一段连续的空间,因此可以根据实际需求动态地申请、释放节点空间,避免浪费内存。
  • 支持高效的插入、删除操作。由于单链表中的节点是通过指针相连的,因此在插入、删除一个节点时,只需要修改其前驱节点或后继节点的指针即可,时间复杂度为O ( 1 ) 。
     

 缺点:

  • 不支持随机访问。由于单链表中的节点不是连续存储的,因此不能像数组一样通过下标来直接访问一个元素,需要从头节点开始遍历整个链表才能访问任意位置的元素。

 创建一个类

template <class T>								// T为单链表存储的元素类型
class linkList
{
private:
    struct Node
    {
    public:
        T  data;								  // 结点的数据域 
        Node* next;								  // 结点的指针域,指向后继结点 
        Node(const T value, Node* p = NULL)       // 具有两个参数的Node构造函数 
        {	
            data = value;
            next = p;
        }
        Node(Node* p = NULL)                      // 具有一个参数的Node构造函数  
        { 						
            next = p;
        }
    };


    Node* head;								// 单链表的头指针 
    Node* tail;    							// 单链表的尾
    int curLength;							// 单链表的当前长度
    Node* getPosition(int i)const;			// 返回指向单链表中第i个元素的指针     

public:
    linkList();								    // 构造函数 
    ~linkList();								// 析构函数  
    void clear(); 								// 将单链表清空,使之成为空表
    bool empty()const;                          // 判空
    int size();                                 // 返回单链表的当前实际长度  						 
    void insert(int i, const T& value);	        // 在位置i上插入一个元素value,表的长度增1
    void remove(int i);							// 删除位置i上的元素value,若删除位置合法,表的长度减1 
    int search(const T& value)const;		    // 查找值为value的元素第一次出现的位序
    T visit(int i)const;					    // 访问位序为i的元素值,“位序”0表示第一个元素,类似于数组下标
    void traverse()const;						// 遍历单链表	
    void headCreate();							// “头插法”
    void tailCreate();							// “尾插法”
    void inverse();								// 逆置单链表
    int prior(const T& value)const;		        // 查找值为value的元素的前驱

};

 2、单链表的初始化

  • 通常会用头指针来标识一个单链表,头指针为nullptr时表示一个空表。
  • 但是,为了操作方便,会在单链表的第一个结点之前附加一个结点,称为头结点
  • 头结点的数据域可以不设任何信息,也可以记录表长等信息。

定义单链表类的成员函数,该函数的声明语句为“void inverse();”,实现就地逆置该,【C++】,算法,数据结构 

代码实现: 

template <class T>
linkList<T>::linkList()
{
    head = tail = new Node();				    // 创建带有头结点的空表
    curLength = 0;
}

 3、单链表的建立

3.1、头插法建立单链表

头插法建立单链表是说将新结点插入到当前链表的表头,即头结点之后。

思路:输入一个结束标志flag,使用一个while循环,判断条件是 value != flag

代码实现:

template <class T>  						// 头插法创建 
void linkList<T>::headCreate()
{
    Node* p;
    T value, flag;
    cin >> flag;									// 输入结束标志

    cin >> value;
    while (value != flag)
    {
        p = new Node(value);
        p->next = head->next;
        head->next = p;
        curLength++;
        cin >> value;
    }
}

3.2、尾插法建立单链表

尾插法建立单链表,就是将新结点插入到当前链表的表尾。

代码实现:

template <class T>  						// 尾插法创建链表
void linkList<T> ::tailCreate()
{
    Node* p;
    T value, flag;
    cin >> flag;									// 输入结束标志

    cin >> value;
    while (value != flag)
    {
        p = new Node(value);
        tail->next = p;
        tail = p;
        curLength++;
        cin >> value;
    }

}

4、单链表的遍历 

代码实现:

template <class T>
void  linkList<T> ::traverse()const
{
    Node* p = head->next;
    while (p != nullptr)
    {
        cout << p->data << "  ";
        p = p->next;
    }
    cout << endl;
 
}

5、单链表的长度

代码实现:

template <class T>
int linkList<T>::size()
{ 
    return curLength; 
}

6、单链表的查找

6.1、按值查找

代码实现:

template <class T>
int linkList<T> ::search(const T& value)const
{
    Node* current = head->next;
    int i = 0;
    while (current != nullptr)
    {
        if (current->data == value)
        {
            break;
        }
        else
        {
            current = current->next;
            i++;
        }
    }
    if (current != nullptr)
    {
        return i;
    }
    return -1;


}

6.2、按位查找

代码实现:

template <class T>  						// 访问位序为i的元素返回其数据域
T linkList<T> ::visit(int i)const 
{

    if (i < 0 || i>(curLength - 1))
    {
        T a = 0;
        return a;
    }
    Node* current = head->next;
    while (i--)
    {
        current = current->next;
    }

    return current->data;
 
}

7、单链表的插入

返回指向单链表中第i个元素的指针

template <class T>
typename linkList<T> ::Node* linkList<T> ::getPosition(int i)const
{
    Node* ptemp = head;
    int k = 0;
    while (k < i)
    {
        ptemp = ptemp->next;
        k++;
    }
    return ptemp;
}

代码实现:

template  <class T>
void linkList<T> ::insert(int i, const T& value)
{
    Node* current = getPosition(i);
    Node* newNode = new Node(value);
    newNode->next = current->next;
    current->next = newNode;
    curLength++;

}

8、单链表的删除

代码实现:

template  <class T>
void  linkList<T>::remove(int i)
{

    Node* current = getPosition(i);
    Node* del = current->next;
    current->next = del->next;
    delete del;
    curLength--;
 
}

9、单链表的判空

代码实现:

template <class T>
bool linkList<T>::empty()const
{
    return head->next == nullptr;
}

总代码实现:

#include<stack>


template <class T>								// T为单链表存储的元素类型
class linkList
{
private:
    struct Node
    {
    public:
        T  data;								  // 结点的数据域 
        Node* next;								  // 结点的指针域,指向后继结点 
        Node(const T value, Node* p = NULL)       // 具有两个参数的Node构造函数 
        {	
            data = value;
            next = p;
        }
        Node(Node* p = NULL)                      // 具有一个参数的Node构造函数  
        { 						
            next = p;
        }
    };


    Node* head;								// 单链表的头指针 
    Node* tail;    							// 单链表的尾
    int curLength;							// 单链表的当前长度
    Node* getPosition(int i)const;			// 返回指向单链表中第i个元素的指针     

public:
    linkList();								    // 构造函数 
    ~linkList();								// 析构函数  
    void clear(); 								// 将单链表清空,使之成为空表
    bool empty()const;                          // 判空
    int size();                                 // 返回单链表的当前实际长度  						 
    void insert(int i, const T& value);	        // 在位置i上插入一个元素value,表的长度增1
    void remove(int i);							// 删除位置i上的元素value,若删除位置合法,表的长度减1 
    int search(const T& value)const;		    // 查找值为value的元素第一次出现的位序
    T visit(int i)const;					    // 访问位序为i的元素值,“位序”0表示第一个元素,类似于数组下标
    void traverse()const;						// 遍历单链表	
    void headCreate();							// “头插法”
    void tailCreate();							// “尾插法”
    void inverse();								// 逆置单链表
    int prior(const T& value)const;		        // 查找值为value的元素的前驱

};

template <class T>
linkList<T>::linkList()
{
    head = tail = new Node();				    // 创建带有头结点的空表
    curLength = 0;
}

template <class T>
linkList<T>::~linkList()
{
    clear();
    delete head;								// 删除头结点
}

template <class T>
bool linkList<T>::empty()const
{
    return head->next == nullptr;
}

template <class T>
int linkList<T>::size()
{ 
    return curLength; 
}

template <class T>
void linkList<T>::clear()
{

    Node* p = head->next;
    while (p)
    {
        head = head->next;
        delete p;
        p = head;
    }

}

template <class T>
typename linkList<T> ::Node* linkList<T> ::getPosition(int i)const
{
    Node* ptemp = head;
    int k = 0;
    while (k < i)
    {
        ptemp = ptemp->next;
        k++;
    }
    return ptemp;
}


template  <class T>
void linkList<T> ::insert(int i, const T& value)
{
    Node* current = getPosition(i);
    Node* newNode = new Node(value);
    newNode->next = current->next;
    current->next = newNode;
    curLength++;

}

template  <class T>
void  linkList<T>::remove(int i)
{

    Node* current = getPosition(i);
    Node* del = current->next;
    current->next = del->next;
    delete del;
    curLength--;
  

}

template <class T>
void  linkList<T> ::traverse()const
{
    Node* p = head->next;
    while (p != nullptr)
    {
        cout << p->data << "  ";
        p = p->next;
    }
    cout << endl;
 
}

template <class T>
int linkList<T> ::search(const T& value)const
{


    Node* current = head->next;
    int i = 0;
    while (current != nullptr)
    {
        if (current->data == value)
        {
            break;
        }
        else
        {
            current = current->next;
            i++;
        }
    }
    if (current != nullptr)
    {
        return i;
    }
    return -1;


}

template <class T>  						// 访问位序为i的元素返回其数据域
T linkList<T> ::visit(int i)const 
{

    if (i < 0 || i>(curLength - 1))
    {
        T a = 0;
        return a;
    }
    Node* current = head->next;
    while (i--)
    {
        current = current->next;
    }

    return current->data;
 
}

template <class T>  						// 头插法创建 
void linkList<T>::headCreate()
{
    Node* p;
    T value, flag;
    cin >> flag;									// 输入结束标志

    cin >> value;
    while (value != flag)
    {
        p = new Node(value);
        p->next = head->next;
        head->next = p;
        curLength++;
        cin >> value;
    }
}

 

template <class T>  						// 尾插法创建链表
void linkList<T> ::tailCreate()
{
    Node* p;
    T value, flag;
    cin >> flag;									// 输入结束标志

    cin >> value;
    while (value != flag)
    {
        p = new Node(value);
        tail->next = p;
        tail = p;
        curLength++;
        cin >> value;
    }

}
template <class T>  						// 头插法逆置   
void linkList<T> ::inverse()
{

    Node* temp = nullptr;
    Node* p = head->next;
    head->next = nullptr;
    while (p != nullptr)
    {
        temp = p;
        p = p->next;
        temp->next = head->next;
        head->next = temp;
    }

}

template <class T>
int linkList<T> ::prior(const T& value)const
{
    Node* current = head->next;
    int a = 0;
    Node* p = nullptr;
    while (current != nullptr)
    {
        if (current->data == value)
        {
            break;
        }
        else
        {
            current = current->next;
            a++;
        }
    }
    if (current != nullptr)
    {
        return a - 1;
    }
    return -1;

}

执行

#include<iostream>
using namespace std;


#include"SList.h"



int main()
{
	linkList<int>* lk1, * lk2;
	lk1 = new linkList<int>();
	lk2 = new linkList<int>();
	int i;
	int val;
	lk1->headCreate();          // 测试头插法创建单链表
	lk2->tailCreate();          // 测试尾插法创建单链表 
	lk1->traverse();           // 测试遍历
	lk2->traverse();           // 测试遍历
	
	cout << "查找值为2的位序:" << lk1->search(2) << endl;
	cout << "查找位序为2的值" << lk1->visit(2) << endl;
	cout << "长度:" << lk1->size();
	return 0;
}

执行结果

定义单链表类的成员函数,该函数的声明语句为“void inverse();”,实现就地逆置该,【C++】,算法,数据结构文章来源地址https://www.toymoban.com/news/detail-768368.html

到了这里,关于【C++】单链表——单链表的基本操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【头歌】单链表的基本操作

    任务描述 本关任务:编写单链表的初始化、插入、遍历三个操作函数。 相关知识 链表 是线性表的链式存储结构的别称,特点是以“指针”指示后继元素,因此线性表的元素可以存储在存储器中任意一组存储单元中。 每个结点只有一个指针域的链表称为 单链表 。 因此单链

    2024年03月26日
    浏览(34)
  • 【数据结构】——单链表的基本操作(带头结点)

            单链表解决了顺序表需要大量连续存储单元的缺点,但单链表附加指针域, 存储密度较顺序表低(考点!!) 。由于单链表的元素离散地分布在存储空间中,所以单链表是 非随机存取 的存储结构,即不能直接找到表中某个特定的结点。当查找某个特定结点时,需要

    2024年02月05日
    浏览(34)
  • 单链表的基本操作代码实现(C语言版)

    目录 前言: 单链表的基本操作 准备工作(头文件、各种宏定义以及结构体定义) 一.较简单操作 1.单链表的初始化 2.判断单链表是否为空表 3.单链表的销毁 4.单链表的清空 5.求单链表的表长 二.较重要操作 1.单链表的取值 2.单链表元素的查找 3.单链表的结点插入 4.单链表的结

    2024年04月11日
    浏览(31)
  • 【数据结构】单链表的基本操作 (C语言版)

    目录 一、单链表 1、单链表的定义: 2、单链表的优缺点: 二、单链表的基本操作算法(C语言) 1、宏定义 2、创建结构体 3、初始化 4、插入 4、求长度 5、清空 6、销毁  7、取值 8、查找 9、删除 10、头插法创建单链表 11、尾插法创建单链表 三、单链表的全部代码(C语言)

    2024年01月22日
    浏览(37)
  • 【数据结构】C语言实现单链表的基本操作

    大家好,很高兴又和大家见面啦!!! 在上一篇中,我们详细介绍了单链表的两种创建方式——头插法与尾插法,相信大家现在对这两种方式都已经掌握了。今天咱们将继续介绍单链表的基本操作——查找、插入与删除。在开始今天的内容之前,我们先通过尾插法创建一个单

    2024年02月03日
    浏览(40)
  • 【数据结构】 循环单链表的基本操作 (C语言版)

    目录 一、循环单链表 1、循环单链表的定义: 2、循环单链表的优缺点: 二、循环单链表的基本操作算法(C语言)    1、宏定义  2、创建结构体 3、循环单链表的初始化  4、循环单链表的插入 5、求单链表长度 6、循环单链表的清空 7、循环单链表的销毁 8、循环单链表的取

    2024年01月22日
    浏览(41)
  • 线性表的定义和基本操作

    一、线性表的定义 线性表(Linear List)是具有相同数据类型的n(n=0)个数据元素的有限序列,其中n为表长,当n=0时线性表是一个空表。若用L命名线性表,则其一般表示为 ai 是线性表中的“第i个”元素线性表中的 位序 a1是表头元素;an是表尾元素。 除第一个元素外,每个元素

    2024年02月06日
    浏览(42)
  • 数据结构——单链表基本操作实现 (c++)

    单链表链式存储结构的特点是:用一组任意的存储单元存储线性表的数据元素(这里存储单元可以是连续的,也可以是不连续的),为了表示每个数据元素a与其直接后继数据元素之间的逻辑关系,除了存储信息本身外还要存储一个指示其直接后继的信息(地址). 这两部分信

    2024年02月03日
    浏览(42)
  • 数据结构 2.1 线性表的定义和基本操作

    数据结构三要素——逻辑结构、数据的运算、存储结构(物理结构) 线性表是具有 相同数据类型 的n(n=0)个数据元素的 有限序列 ,其中n为表长,当n=0时,线性表是一个空表。 每个数据元素所占空间一样大,有次序。 几个概念 1.ai是线性表中的第i个 i表示元素线性表中的

    2024年02月07日
    浏览(32)
  • 数据结构 线性表的定义和基本操作(以顺序表为例)

    名人说:一花独放不是春,百花齐放花满园。——《增广贤文》 作者:Code_流苏(CSDN) (一个喜欢古诗词和编程的Coder😊) 以下代码个人分享出来,仅供学习交流,且仅在CSDN平台发布,未经授权禁止二次转发。 〇、线性表是什么? 1、定义 线性表 是具有 相同数据类型 的 n(

    2024年02月12日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包