循环链表的实现_建立双向循环链表

循环链表的实现_建立双向循环链表循环链表循环链表是一个收尾相接的链表,将单链表的最后一个指针域改由NULL改为指向表头结点这就是单链式的循环链表,并称为循环单链表带头结点的循环单链表的各种操作的算法实现与带头结点单链表的算法实现

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

循环链表

  循环链表是一个收尾相接的链表,将单链表的最后一个指针域改由NULL改为指向表头结点这就是单链式的循环链表,并称为循环单链表

  循环链表的实现_建立双向循环链表

  带头结点的循环单链表的各种操作的算法实现与带头结点单链表的算法实现类似,差别仅在于算法判别当前结点p是否为尾结点的条件不同。单链表中的判别条件为p!=NULL或p->next!=NULL,而单循环链表判别条件是p!=L或p->next!=L

  在循环单链表中附设尾指针有时候比附设头指针更简单。如:在用头指针的循环单链表中找a1的时间复杂度是O(1),找an需要从头找到尾,时间复杂度是O(n),如果用为指针rear,找开始结点和终端结点的存储位置分别是rear->next->next和rear

  建立循环单链表

void CreatCLLinkList(CLLinkList CL) 
{
    Node *rear,*s;
    rear=CL;//rear指针动态指向当前表尾,其初始值指向头结点 
    int flag=1;
    int x;
    printf("Please input data and enter 0 end:\n");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            rear->next=s;
            rear=s;
        }
        else
        {
            flag=0;
            rear->next=CL;//最后一个节点的next域指向头结点 
        }
    }
}

  循环单链表的插入

#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)

typedef struct Node
{
    int data;
    struct Node *next;    
}Node,*CLLinkList;

void InitCLLinkList(CLLinkList *CL)
{
    *CL=(CLLinkList)malloc(len);
    (*CL)->next=*CL;
}

void CreatCLLinkList(CLLinkList CL) 
{
    Node *rear,*s;
    rear=CL;//rear指针动态指向当前表尾,其初始值指向头结点 
    int flag=1;
    int x;
    printf("Please input data and enter 0 end:\n");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            rear->next=s;
            rear=s;
        }
        else
        {
            flag=0;
            rear->next=CL;//最后一个节点的next域指向头结点 
        }
    }
}

void PrintCLLinkList(CLLinkList CL)
{
    Node *p;
    p=CL->next;
    printf("You input data is:\n");
    for(;p!=CL;p=p->next)
    {
        printf("%-3d",p->data);
    }
    printf("\n");
}

void InCLLinkList(CLLinkList CL,int i,int x)
{
    Node *p,*s;
    int k=0;
    p=CL;
    if(i<=0)
    {
        printf("You enter location illegal:\n");
        return;
    }
    while(p->next!=CL&&k<i-1)
    {
        k++;
        p=p->next;
    }
    if(p==CL)
    {
        printf("The insert position is not reasonable:\n");
        return;
    }
    s=(Node *)malloc(len);
    s->data=x;
    s->next=p->next;
    p->next=s;
    printf("Insert successfully\n");
}

void Print_CLLinkList(CLLinkList CL)
{
    Node *p;
    p=CL->next;
    printf("Now you input data is:\n");
    for(;p!=CL;p=p->next)
        printf("%-3d",p->data);
}

int main()
{
    int i,x;
    CLLinkList CL;
    InitCLLinkList(&CL);
    CreatCLLinkList(CL);
    PrintCLLinkList(CL);
    
    printf("Please enter the location you want to insert:\n");
    scanf("%d",&i);
    printf("Please enter the values you want to insert:\n") ;
    scanf("%d",&x);

    InCLLinkList(CL,i,x);
    Print_CLLinkList(CL);
    free(CL);
    return 0;
}

  循环单链表的删除

#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)
typedef struct Node
{
    int data;
    struct Node *next;
}Node,*LinkList;

void InitCLLinkList(LinkList *CL)
{
    *CL=(LinkList)malloc(len);
    (*CL)->next=*CL;
}
void CreatCLLinkList(LinkList CL)
{
    int flag=1,x;
    Node *rear,*s;
    rear=CL;
    printf("Please input data and enter 0 end:\n");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            rear->next=s;
            rear=s;
        }
        else
        {
            rear->next=CL;
            flag=0;
        }
    }
}

void DeleCLLinkList(LinkList CL,int i)
{
    Node *p,*r;
    p=CL;
    int k=0;
    if(i<0)
    {
        printf("You enput i illegal!\n");
        return;
    }
    while(p->next!=CL&&k<i-1)
    {
        p=p->next;
        k++;
    }
    if(p->next==CL)
    {
        printf("Delete Node i illegal!\n");
        return;
    }
    r=p->next;
    p->next=r->next;
    free(r);
}

void PrintCLLinkList(LinkList CL)
{
    Node *p;
    for(p=CL->next;p!=CL;p=p->next)    
    {
        printf("%3d",p->data);
    }
}
int main()
{
    LinkList CL;
    int i;
    InitCLLinkList(&CL);
    CreatCLLinkList(CL);
    
    printf("Please enter the i node you want to delete:\n");
    scanf("%d",&i);
    DeleCLLinkList(CL,i);
    printf("The list after deleting is:\n");
    PrintCLLinkList(CL);
    free(CL);
    
    return 0;
}

  合并循环单链表

    方法一:先找到两个链表LA,LB的表尾,分别用p,q指向它,然后将第一个链表的表尾与第二个链表的第一个结点连起来,修改第二个表的尾q,使它的链域指向第一个表头

//头指针合并循环链表 
#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)

typedef struct Node
{
    int data;
    struct Node *next;
}Node,*CLLinkList;

void InitCL_aLinkList(CLLinkList *CL_a)
{
    *CL_a=(CLLinkList)malloc(len);
    (*CL_a)->next=*CL_a;
}

void InitCL_bLinkList(CLLinkList *CL_b)
{
    *CL_b=(CLLinkList)malloc(len);
    (*CL_b)->next=*CL_b;
}

void CreatCL_aLinkList(CLLinkList CL_a)
{
    Node *p,*s;
    int x,flag=1;
    p=CL_a;
    printf("Please input A data and enter 0 end:\n");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            p=s;
        }
        else
        {
            p->next=CL_a;
            flag=0;
        }
    }
}

void CreatCL_bLinkList(CLLinkList CL_b)
{
    Node *p,*s;
    int x,flag=1;
    p=CL_b;
    printf("Please input B data and enter 0 end:\n");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            p=s;
        }
        else
        {
            p->next=CL_b;
            flag=0;
        }
    }
}

CLLinkList MergeCLLinkList(CLLinkList CL_a,CLLinkList CL_b)
{
    Node *p,*q;
    p=CL_a;
    q=CL_b;
    while(p->next!=CL_a)//找到LA的表尾,用p指向它 
        p=p->next;
    while(q->next!=CL_b)//找到LB的表尾,用q指向它
        q=q->next;
    q->next=CL_a;//修改LB的表尾指针,使之指向表LA的头结点 
    p->next=CL_b->next;    //修改LA的表尾指针,CL_b->next的意思是跳过CL_b头结点
    free(CL_b);
    return CL_a;
}

void PrintCLLinkList(CLLinkList CL)
{
    printf("CL list is:\n");
    for(Node *p=CL->next;p!=CL;p=p->next)
        printf("%-3d",p->data);
    printf("\n");
}

int main()
{
    CLLinkList CL_a,CL_b,CL;
    InitCL_aLinkList(&CL_a);
    InitCL_bLinkList(&CL_b);
    
    CreatCL_aLinkList(CL_a);
    CreatCL_aLinkList(CL_b);
    
    CL=MergeCLLinkList(CL_a,CL_b);
    PrintCLLinkList(CL_a);
    free(CL_a);
    return 0;
}

    方法二:若采用尾指针设置,无需遍历找到尾结点,只需修改尾指针的指示域即可

CLLinkList MergeCLLinkList(CLLinkList RA,CLLinkList RB)
{
    Node *p=RA->next;//保存RA的头结点地址 
    RA->next=RB->next->next;//RB的头结点练到RA的终端结点之后
    RB->next=p;//将RA的头结点链到RB的终端结点之后
    free(RB->next);//释放RB的头结点 
    return RB;//返回新的链表的尾指针 
}

  循环链表求长度

#include<stdio.h>
#define len sizeof(Node)
#include<stdlib.h>
typedef struct Node
{
    int data;
    struct Node* next;
}Node,*LinkList;

void InitCLLinkList(LinkList *CL)
{
    *CL=(LinkList)malloc(len);
    (*CL)->next=*CL;
}

//尾插法创建循环链表 
void CreatCLLinkList(LinkList CL)
{
    Node *s,*rear;
    int flag=1;
    rear=CL;
    printf("please input datas and input 0 over:\n");
    int x;    
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
           s=(Node *)malloc(len);
        s->data=x;
        rear->next=s;
        rear=s;
        }
        else
        {
            flag=0;
            rear->next=CL;
        }
    }
}

int LengthCLLinkList(LinkList CL)
{
    int i=0;
    Node *p;
    p=CL->next;
    while(p!=CL)
    {
        i++;
        p=p->next;
    }
    return i;
}

int main()
{
    LinkList CL;
    int length;
    InitCLLinkList(&CL);
    CreatCLLinkList(CL);
    length=LengthCLLinkList(CL);
    printf("The length of the circular list is:%d\n",length);
    free(CL) ;
    return 0;
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/167334.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 汉字输入法演变

    汉字输入法演变摘自百度知道:https://zhidao.baidu.com/question/371212542972360284.html由于汉字有数以万计,电脑键盘不可能为每一个汉字而造一个按键。因此,人们需要替汉字编码(检索出汉字的代码),用数个键来输入一个汉字。中文输入法的发展过程,是“万码奔腾”的过程,在30年间出现了上千种编码方法。最早的汉字输入法,一般认为是从70年代末期或者8…

    2022年7月26日
    4
  • 在Linux安装Jenkins

    在Linux安装Jenkins自动更新发布必备神器,装起来

    2025年8月4日
    3
  • 模电–运算放大器工作原理

    模电–运算放大器工作原理模电领悟1(关于正负反馈是通过瞬时极性法判断净输入量的增减,与净输入量的正负号无关,与他的量有关,增了就是正反馈;所谓的同相反相输入端是指相位,反相与同相相位差为180°,所以如果同相和反相加的是同一个电压,…

    2022年6月3日
    29
  • 手把手学习的DSP

    手把手学习的DSPss

    2022年4月28日
    43
  • STM32开发项目:ADS1115的驱动与使用

    STM32开发项目:ADS1115的驱动与使用日期作者版本说明2020.09.24TaoV0.0完成主体内容的撰写目录ADS1115介绍驱动源码头文件源文件使用指南基本步骤注意事项ADS1115介绍ADS1115是具有PGA、振荡器、电压基准、比较器的16位、860SPS、4通道Δ-ΣADC,数据通过一个I2C兼容型串行接口进行传输。有关它的详细说明可以参考官方数据手册。驱动源码头文件#ifndef__ADS1115_H__#define__ADS1115_H__#include…

    2025年7月3日
    3
  • Excel 8000401a 错误 及解决办法[通俗易懂]

    Excel 8000401a 错误 及解决办法[通俗易懂]“/”应用程序中的服务器错误。——————————————————————————–检索COM类工厂中CLSID为{00024500-0000-0000-C000-000000000046}的组件时失败,原因是出现以下错误:8000401a。说明:执行当前Web请求期…

    2022年7月25日
    12

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号