数据结构(04)——循环链表

11 篇文章 0 订阅

循环链表概念

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


完整代码实现

#include<iostream>
#include<string>
#include<stdlib.h>

using namespace std;

typedef struct _LinkNode {
    int data; //结点的数据域
    struct _LinkNode *next; //结点的指针域
}LinkNode, LinkList; //LinkList 为指向结构体 LNode 的指针类型

void LinkPrint(LinkList *L);

bool InitList(LinkList* &L)//构造一个空的循环链表 L
{
    L=new LinkNode; //生成新结点作为头结点,用头指针 L 指向头结点
    if(!L)return false; //生成结点失败
    L->next=L; //头结点的指针域指向自己
    L->data = -1;
    return true;
}

//尾插法
bool ListInsert_back(LinkList* &L, LinkNode * node){
    LinkNode *last = NULL;
    if(!L || !node ) return false;

    //找到最后一个节点
    last = L;
    while(last->next!=L) last=last->next;
    //新的节点链接到最尾部
    node->next = L;
    last->next = node;
    return true;
}

bool TestOut(LinkList* &L, int interval)
{
    //在带头结点的循环链表 L 中,每个 interval 个间隔循环删除节点
    LinkList *p, *q;
    int j = 0, i = 0;
    int times = 0, num = 0;
    p=L;
    if(!L || p->next == L) {
        cout<<"链表为空!"<<endl;
        return false;
    }

    if(interval<1){
        cout<<"报数淘汰口令不能小于 1!"<<endl;
        return false;
    }

    do{
        i += interval;
        while((p->next)) //查找第 i 个结点,p 指向该结点的上一个节点
        {
            if(p->next!=L) j++;
            if(j>=i) break;
            p=p->next;
        }
        times++;

        q=p->next; //临时保存被删结点的地址以备释放空间
        num = q->data;
        if(times==5) cout<<"第 5 个出圈的编号是:"<<num<<endl;
        printf("cur: %d last: %d next:%d\n",q->data, p->data,q->next->data);
        p->next=q->next; //改变删除结点前驱结点的指针域
        delete q; //释放被删除结点的空间
        LinkPrint(L);
    }while(L->next!=L);//链表不为空,继续报数
    cout<<"最后一个出圈的编号是:"<<num<<endl;
    return true;
}

void LinkPrint(LinkList *L) //循环链表的输出
{
    LinkList *p;
    if(!L || L==L->next){
        cout<<"链表为空!"<<endl;
        return ;
    }

    p=L->next;
    while (p!=L)
    {
        cout <<p->data <<"\t";
        p=p->next;
    }
    cout<<endl;
}

int main(){
    int i, x;
    LinkList *L;
    LinkNode *s;

    //1. 初始化一个空的循环链表
    if (InitList(L)){
        cout << "初始化一个空的循环链表!\n";
    }

    //2. 创建循环链表(尾插法)
    std::cout <<"尾插法创建循环链表, 插入 10 个元素..." <<endl;
    i = 0;
    while((++i)<=10)
    {
        s=new LinkNode;//生成新结点
        s->data=i; //输入元素值赋给新结点的数据域
        s->next=NULL;
        if(ListInsert_back(L, s)){
            cout<<"插入成功!"<<endl;
        }else {
            cout<<"插入失败!"<<endl;
        }
    }
    cout << "尾插法创建循环链表输出结果:\n";
    LinkPrint(L);

    TestOut(L, 9);
    system("pause");
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Radish(萝卜)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值