c++实现循环链表(增、删、插入、遍历)

循环链表是另一种形式的链式存储结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

结点类:

class Node
{
public:
    int data;	//数据域
    Node *next; //指针域
};

结尾增加:

void append(Node **head, int data)
{
    if(*head == nullptr)
    {
        *head = new Node;
        (*head)->data = data;
        (*head)->next = *head;
    }
    else
    {
        Node *tail;
        //寻找尾节点
        for(tail = *head; tail->next != *head; tail = tail->next);

        Node *newNode;
        newNode = new Node;
        newNode->data = data;
        newNode->next = *head; //新节点指向头节点
        tail->next = newNode;  //尾节点指向新节点
    }
}

按下标插入:

// **head-头结点, index-将要插入的下标位置, data-数据域
void insert(Node **head, int index, int data)
{
    //创建新结点
    Node *newNode = new Node;
    newNode->data = data;
    //插入在头结点位置
    if(index == 0)
    {
        //记录头结点
        Node *tail = *head;
        //循环到尾部, 如果位置超出链表的长度, 将插入队尾。
        for(tail = *head; tail->next != *head; tail = tail->next);
        //新头结点的指针域指向原头结点
        newNode->next = *head;
        //尾结点指针域与新头结点衔接
        tail->next = newNode;
        //*head要从函数中带出新头结点的位置
        *head = newNode;
    }
    else
    {
        Node *pre = *head;
        //找到前驱结点,要插入在当前index的下标,所以要index-1
        for(int i = 0; i < index - 1; i++)
        {
            pre = pre->next;
        }
        newNode->next = pre->next;
        pre->next = newNode;
    }
}

按下标删除:

void remove(Node **head, int index)
{
    if(*head == nullptr)
    {
        return;
    }

    if(index == 0)
    {
        Node *tail = *head;
        //找到尾结点
        for(tail = *head; tail->next != *head; tail = tail->next);
        Node *del = *head;
        *head = (*head)->next;
        tail->next = *head;
        delete del;
    }
    else
    {
        Node *pre = *head;
        //找到前驱结点,要删除当前index的下标,所以要index-1
        for(int i = 0; i < index - 1; i++)
        {
            if(pre->next == *head)
            {
                //前驱结点的下一个结点为head且仍进入了for循环,
                //说明index大于链表长度,下标越界
                cout << "index of range!" << endl;
                return;
            }
            pre = pre->next;
        }

        //前驱结点指向要删除结点的后继结点,此时pre->next是要删除的结点
        Node *del = pre->next;
        pre->next = pre->next->next;
        delete del;
    }
}

遍历链表:

Node *mark = head;
while(head)
    {
    cout << head->data;
    head = head->next;
    if(mark == head)
    {
        break;
    }
    this_thread::sleep_for(chrono::milliseconds(100)); //休眠100毫秒,不需要可删除
}

相关链接:c++实现单链表头插、尾插、删除、遍历

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

为啥不吃肉捏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值