C++单链表

在单链表中保存一些整数ID,列表的每个结点包含ID及指向下一个结点的指向。
单链表中最后一个结点的指针域为null(0)。一个null指针不是有效的指针,不能反引用,但可以检查它是否为0(例如:p==0)

List.h单链表类

//链接(结点)
class Link
{
public:
    Link(Link* pNext, int id) : _pNext(pNext), _id(id){}
    Link* Next()const{  return _pNext;}
    int Id()const{  return _id;}
private:
    Link* _pNext;
    int _id;
};
//链表
class List
{
public:
    //初始化时头指针指向NULL
    List() :_pHead(0){}
    ~List();
    //在第一个元素前插入
    void Add(int id);
    Link const *GetHead()const{ return _pHead;}
private:
    //头指针
    Link* _pHead;
};

List.cpp

#include"List.h"
void List::Add(int id)
{
    //新的结点,新结点的指针域指向头结点指向的结点
    Link* pLink = new Link(_pHead, id);
    //头指针指向新的结点
    _pHead = pLink;
}
//释放链表内存
List::~List()
{
    while (_pHead != 0)
    {
        Link* pLinkTmp = _pHead;
        _pHead = _pHead->Next();
        delete pLinkTmp;
    }
}

main.cpp

#include"List.h"
#include<iostream>
int main()
{
    List myList;
    for (int i = 0; i < 10; i++)
    {
        myList.Add(i);
    }
    //寻找id等于给定值的结点
    for (Link const* pLink = myList.GetHead();
        pLink != 0;
        pLink = pLink->Next())
    {
        if (pLink->Id() == 5)
        {
            std::cout << "Find " << 5 << std::endl;
            break;
        }
        std::cout << "Current id is" << pLink->Id() << std::endl;
    }
}

额外
指针常量与常量指针
(1)指针常量
指针本身是一个常量,不能修改指针本身,但可以修改指针指向的内容。因此是常量,所以必须初始化。

int a=10;
int b=20;
int * const p=&a;
*p=20;
//p=&b;(错误,不可以修改指针本身)

(2)常量指针
指向常量的指针,称为常量指针。指针本身可以修改,但指针指向的内容不可以修改。

int a=10;
int b=20;
int * const p=&a;
//*p=20;(错误,指针指向的内容不可修改)
p=&b;

(3)指向常量的指针常量
指向常量的指针常量,指针本身,指针指向内容,都不可以修改。初始化后,就是一个固定的值。

int a=10;
int const * const p=&a;
int a=10;
int b=20;
int const *p1=&a;
int * const p2=&b;
p1=&b;
*p2=a;
std::cout<<*p1<<std::endl;//输出10
std::cout<<*p2<<std::endl;//输出10

从右至左读变量声明
(1)int const * p;
p是一个指针,指向常量int。
(2)int * const p;
p是一个指针常量,指向int。
(3)int const * const p;
p是一个指针常量,指向常量int。
可以把* const看作一个内容,读作指针常量。
一种理解有关指针的变量声明的方法
int *p
将其看成 int(*p),p是一个指针,*p是一个int,所以p是一个指向int的指针。
int *const p
看成 int (*const p),p是一个指针常量,*p是一个int,所以p是一个指向int的指针常量。
int(*p)fun()
p是一个指针,*p是一个int fun(),p是一个指向函数的指针。
int *p[4]
看成 int (*p[4]),p是一个指针数组,*p是一个int,所以p是int类型的指针数组。
int(*p)[4]
p是一个指针,*p是int[4],所以p是一个指针数组的指针。
PS:常量指针外文为 pointer to const指针常量外文为 const pointer,感觉还是翻译后更难懂。

单链表是一种线性数据结构,其元素不是连续存储在内存中的。相反,每个元素由一个节点表示,该节点包含两部分信息:一部分用于存放实际的数据;另一部分是一个指针(也称为链接),指向下一个节点的位置。最后一个节点的指针通常为空(NULL),表明这是列表的最后一项。 ### C++ 单链表的基本操作 1. **创建结点** - 每个结点一般包括两个成员变量,一个是保存数据值的数据域(`data`),另一个是指向下一结点地址的指针域(`next`). ```cpp struct Node { int data; // 数据域 Node* next = nullptr; // 初始化为NULL, 指针域,默认情况代表没有后续节点 }; ``` 2. **插入新结点** 插入可以发生在头部、尾部或是指定位置之前/之后。最常见的是头插法和尾插法: * 头插法(Insert at Head)就是在链表的第一个位置添加新的节点; * 尾插法则是在已存在的链表末尾追加一个新的节点。 3. **遍历链表** 遍历意味着从第一个到最后一共访问所有的节点,并对它们执行某些特定的任务如打印出来。 使用while循环直到遇到null停止。 4. **删除结点** 删除某个给定值得所有实例或者是仅移除第一次出现的那个匹配项。 5. **查找结点** 查找是否含有某特定数值或者定位到第几个位置上存在这样的数等。 下面给出简单的例子演示如何实现上述功能之一—将数字加入到单链表中: ```cpp #include <iostream> using namespace std; struct Node { int value; Node *next; }; class LinkedList{ private: Node *head,*tail; public: LinkedList() : head(nullptr), tail(nullptr){ } void add(int val){ Node *newNode=new Node{val,nullptr}; if(!head){// If list is empty. head=tail=newNode; }else{// Add to the end of existing nodes. tail->next=newNode; tail=newNode; } } ~LinkedList(){ while(head != NULL){ Node* temp=head; head=head->next; delete temp; } } }; int main(){ LinkedList mylist; for (size_t i = 0; i <= 9 ; ++i) mylist.add(i); } ``` 上面的例子展示了怎样定义了一个名为 `Node` 的结构体以及基于此构建了基本版的单项链表类 (`LinkedList`). 此外还实现了构造函数初始化空列表,析构函数安全地释放分配的空间,并提供了一种简单的方式通过`add()`方法来增加整型元素至链尾。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值