循环链表-Circular_Linked_List

循环链表-Circular_Linked_List

对于单链表而言,最后一个结点的指针时域时空指针。如果将最后一个结点的指针域指向头结点,则使得链表头结点和为节点相连,就构成了循环单链表。

v2lCqJ.png

循环单链表的声明

//
// Created by HANWENKE on 2022/8/25.
//

#ifndef CIRCULAR_LINKED_LIST_CIRCULAR_LINKED_LIST_H
#define CIRCULAR_LINKED_LIST_CIRCULAR_LINKED_LIST_H

#endif //CIRCULAR_LINKED_LIST_CIRCULAR_LINKED_LIST_H
#include <iostream>
using namespace  std;
class Node{
public:
    int  data;
    Node *next;
    Node ():data(0),next(nullptr){};
    Node (const int &val):data(val),next(nullptr){};
};
class Circular_Linked_list {
public:
    Node  *head;
    void InitList();//链表的初始话
    Circular_Linked_list(){head= nullptr;}//构造函数
    ~Circular_Linked_list(){//析构函数
        DeleteAll();
    }
    void DeleteAll();//删除所有结点
    void HearCreate(const int &val);//头插法建立单链表
    void TailCreate(const int &val);//尾插法建立单链表
    int  length();//求单链表的长度
    Node  *Findval(const int &val);//查找值为val的元素并返回其结点
    Node * Get(const int &i);//获取第i个位置的结点
    bool Insert(const int &val,int i);//在第i个位置前插入x
    void Delete(const int &i);//删除第i个位置的结点
    void Print();//打印链表
};


循环单链表的实现

//
// Created by HANWENKE on 2022/8/25.
//
#include "Circular_Linked_List.h"

//初始化单链表
void Circular_Linked_list::InitList() {
    DeleteAll();
    head= nullptr;
    //创建一个虚拟的头结点
    head=new Node();
}
//清除单链表
void Circular_Linked_list::DeleteAll() {
    Node *p=head;
    Node *q=head;
    while(p){
        q=p->next;
        delete p;
        p=q;
    }
    head= nullptr;
}
void Circular_Linked_list::HearCreate(const int &val) {
    //头插法建立单链表
    Node * s=new Node(val);
    Node *pre= nullptr;
    //头插法--第一个插入的结点的next=head
    //之后插入的时候-就需要让head->next=s;
    //而让新结点的next指向  head->next  所以要保存新结点的next
    if(head->next!= nullptr){
        pre=head->next;
        head->next=s;
        s->next=pre;
    }else{
        s->next=head;
        head->next=s;
    }
}
void Circular_Linked_list::TailCreate(const int &val) {
   Node *p=head->next;
   if(p){
       Node *temp=Get(length());
       Node *s=new Node(val);
       //之前的最后一个结点的next指向新的结点
       temp->next=s;
       //新结点的next指向head;
       s->next=head;
   }else{
       Node *s=new Node(val);
       head->next=s;
       s->next=head;
   }
}

int Circular_Linked_list::length() {
    Node *p=head->next;
    int count=0;
    //因为时循环单链表--尾结点的next指向头结点--所以时p!=head;
    while(p!=head){
        count++;
        p=p->next;
    }
    return count;
}

Node  *Circular_Linked_list::Findval(const int &val) {
    Node *p=head->next;
    if(p== nullptr){
        return nullptr;
    }
    //并且要判断p是否是回到了头节点--如果回到头节点说明没有找到
    while(p->data!=val&&p!=head){
        p=p->next;
    }
    //如果p等于head说明没找到返回null,否则返回具体的结点
    return p==head? nullptr:p;

}

Node* Circular_Linked_list::Get(const int &i) {
    Node *p=head->next;
    int temp=i;
    while(--temp&&p!=head){
        p=p->next;
    }
    return p;
}
//在第i个位置后插入值为val 的元素-首先判断其位置是否合法
bool Circular_Linked_list::Insert(const int &val, int i) {
    if(i<0||i>length()+1){
        cout<<"插入位置不合法"<<endl;
        return false;
    }
    //如果第0个位置就是头插,直接调用头插方法
    if(i==0){
        HearCreate(val);
        return true;
        //如果等于length就是尾插
    }else if(i==length()){
        TailCreate(val);
        return true;
    }else{
        Node *temp= Get(i);
        Node *s=new Node(val);
        s->next=temp->next;
        temp->next=s;
        return true;
    }
    return false;
}

void Circular_Linked_list::Print() {
    Node *p=head->next;
    while(p!=head){
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}
//删除第i个位置的结点
void Circular_Linked_list::Delete(const int &i) {
    if(i<0||i>length()){
        cout<<"删除位置不合法"<<endl;
        return ;
    }
    //获取第i个位置的前一个结点
    Node *temp= Get(i-1);
    //要删除的结点
    Node *p=temp->next;
    //前一个结点的next指向当前结点的next
    temp->next=p->next;
    delete p;
    p= nullptr;
}

int main(){
    Circular_Linked_list l;
    l.InitList();
    for(int i=10;i>0;i--){
        //l.HearCreate(i+100);
        l.TailCreate(i+10);
    }
    l.Print();
    cout<<l.length()<<endl;
    Node *temp=l.Get(l.length());
    cout<<"最后一个元素的值为:"<<temp->data<<endl;
    temp=l.Findval(18);
    if(temp==nullptr){
        cout<<"没有对应的值"<<endl;
    }else{
        cout<<temp->data<<endl;
    }
    //将22插入0号位置
    l.Insert(22,0);
    l.Print();
    //将44插入到最后一个位置
    l.Insert(44,l.length());
    l.Print();
    //将33插入到第3个位置后面
    l.Insert(33,3);
    l.Print();
    //删除第一个位置的结点
    l.Delete(1);
    l.Print();
    //删除最后一个位置的结点
    l.Delete(l.length());
    l.Print();
    //删除第3个位置的结点
    l.Delete(3);
    l.Print();
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HANWEN KE

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

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

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

打赏作者

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

抵扣说明:

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

余额充值