单向链表(以加入数字为例)

单向链表(以加入数字为例)

链表是由一系列节点构成,每个节点包含两个部分,数据和指针。可以把链表看成是不是连续存放的数组

创建链表

class Node{//节点
public:
    string name;
    int num;//要储存的数据
    Node *next;//指针,指向下一个数据,如果没有就是空指针
    Node() :next(nullptr) {}//一些必要的构造函数
    Node(int num) :num(num), next(nullptr) {}
    Node(Node& n) :num(n.num), next(nullptr) {}
    void display()//输出数据
	{
		cout<<num;
	}
};

有了节点还需要一条链子将这些节点连起来,还需要Link类

class Link{
private:
    Node*head;//头指针,指向第一个数据
public:
    Link()//构造函数,定义头指针的值。
    {
        head = new Node();
    }
    ~Link()//析构函数,使用完后删除创建的链表
    {
        while (head != nullptr)//如果头指针不是指向空指针的话,说明还有节点没有删除
        {
            Node* p = head->next;//新创建一个p指针指向透支真的下一个
            delete(head);//删除现在的头指针
            head = p;//头指针指向p(也就是之前头指针的下一个)
        }
    }

};

插入节点

头插

void headInsert(int n)//头部插入
    {
        Node* newNode = new Node(n);//建立一个新节点存放数字n
        newNode->next = head->next;//新节点的next指针指向头指针的next
        head->next = newNode;//头指针的next 指向新创建的节点
    }

函数里面的第二行和第三行是有顺序关系,如果先做第三行,头指针原来指向的数据就会丢失,导致整个链表只剩新插入的指针,所以是先把指针传到新创建的节点,在把指针指向新创建的节点。

尾插

void tailInsert(int n)
    {
        Node* p = head;//创建一个新节点
        while (p->next != nullptr)//先找到原来链表的最后一个,上文说过如果没有一下个数据就是空指针,所以如果不是空指针,说明这个节点就不是链表的最后一个,p一直往下找。
            p = p->next;
        Node* newNode = new Node(n);//建立一个新节点
        p->next = newNode;//将找到的原来的链表的最后一个的next指向新节点的地址,使新节点成为链表的最后一个
    }

同样,顺序是不能变的。

按照数据的一定顺序插入

void insertByNum(int n)//按照数字的顺序从小到大排序
    {
        Node* p = head;//从头指针开始查找
        while (p->next != nullptr && p->next->num < n)//如果不是该节点不是最后一个节点并且下一个数据比n小,就继续查找下去
            p=p->next;
        Node* newNode = new Node(n);//建立一个新节点
        newNode->next = p->next;//新节点的指针指向p(查找到的p的下一个比n大或者已经查找到最后一个节点)
        p->next = newNode;//现在的p的下一个指向新节点
    }

while里面的顺序是不能变的,否则可能导致越界,第四行和第五行也不能改变顺序,如果交换会导致节点丢失。

删除节点

void deleteByNum(int n)//按照输入的n删除带有n的数据的节点
    {
        Node* p = head->next;//新建一个p指向头指针的下一个
        Node* q = head;//新建一个q指向头指针
        while (p != nullptr)//找到最后一个节点为止
        {
            if (p->num == n)//如果找到了
            {
                q->next = p->next;//上一个的next直接指向找到这个节点的next
                delete(p);//删除节点
                break;//退出循环
            }
            else//如果没找到
            {
                p = p->next;//p继续指向下一个
                q = q->next;//q继续指向下一个
            }
        }
    }

查询节点

遍历节点并输出

void traverse()
    {
        bool k = 0;//按照格式输出
        Node* p = head->next;//新建节点p指向第一个数据
        while (p != nullptr)//遍历到最后一个
        {
            if (k)
                cout << " ";
            else
                k = 1;
            p->display();//输出数据
            p = p->next;//继续输出下一个数据
        }
        cout << endl;
    }

根据某个特定的值查找数据

void displayByName(string s)//根据输入的名字查找
	{
		Pony* p = head;//从头指针开始
		while (p->pNext != nullptr && p->name != s)//根据&&的短路性先判断该节点是不是最后一个节点,再判断如果名字不匹配
			p = p->pNext;//就寻找下一个
		p->display();//找到了就输出
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值