C语言-单向循环链表的实现(增,删,插,改)

#include "myhead.h"

/*
    学习任何链表的操作,你只需要验证三个位置对不对即可
          头结点
          中间位置
          末尾位置
*/
//自定义一个结构体来表示单向链表
typedef struct singlelist
{
    //数据域--》存整数
    int data;
    //指针域--》存下一个数据在内存中的首地址
    struct singlelist *next;
}lb;

struct singlelist *myhead;//全局作用域

//初始化单向循环链表
int list_init()
{
    //定义指针
    myhead=malloc(sizeof(lb));
    //指针指向自己
    myhead->next=myhead;

 //往单向循环链表中尾插数据
//把newdata存放到myhead代表的链表的尾部
int list_add_tail(int newdata)
{
    //给新的数据(新的节点/结点)分配堆空间
    struct singlelist *newnode=malloc(sizeof(struct singlelist));
    //把newdata存放起来
    newnode->data=newdata;
    //指针指向哪里呢?
    newnode->next=NULL; 
    //找到链表的尾部
    struct singlelist *p=myhead;
    while(p->next!=myhead)
        p=p->next; //循环结束p就到了尾部
    
    //把刚才的新节点存放到链表的尾部(p的后面)
    p->next=newnode; //赋值翻译成指向
    newnode->next=myhead; 
    return 0;
}

插入数据图  

 

 //单向循环链表的中间插入--》把newdata插入olddata代表节点后面
/*
    情况1:如果olddata有多个,要求每个olddata的后面都插入newdata
    情况2:olddata不存在
*/
int list_add(int newdata,int olddata)
{
    //定义指针p找到olddata
    lb *p=myhead;  //指向头节点
    //定义标志位标记olddata是否存在
    int flag=0;
    while(p->next!=myhead)
    {
        if(p->data==olddata)
        {
            //把newdata插入到olddata的后面
            //准备新的节点
            struct singlelist *newnode=malloc(sizeof(struct singlelist));
            //把newdata存放起来
            newnode->data=newdata;
            //指针指向哪里呢?
            newnode->next=NULL; 
            
           
            newnode->next=p->next;
            p->next=newnode;
            //更新标志位
            flag=1;
            p=newnode->next;
        }
        else
        {
            p=p->next;
        }
        
    }
    if(p->data==olddata)
    {
        flag=1;
        //把newdata插入到olddata的后面
        //准备新的节点
        lb *newnode=malloc(sizeof(lb));
        //把newdata存放起来
        newnode->data=newdata;
        //指针指向哪里呢?
        newnode->next=NULL; 
        //尾插到p的后面
        p->next=newnode; //赋值翻译成指向
        newnode->next=myhead; 
    }
    //判断标志位
    if(flag==0)
    {
        printf("%d根本不存在!\n",olddata);
        return -1;
    }
    return 0;

删除链表 表尾图 

 

 //删除单链表中的节点
/*
    情况1:如果deldata有多个,要求每个deldata都删除
    情况2:deldata不存在
*/
int list_delete(int deldata)
{
    //定义两个指针,一前一后来编译链表
    lb *p=myhead->next;
    lb *q=myhead;
    //定义变量标记deldata是否存在
    int flag=0;
    while(p!=myhead)
    {
        if(p->data==deldata)
        {
            flag=1;
            //删除p指向的节点
            q->next=p->next;
            p->next=NULL;
            free(p);  //p变成了野指针了
            p=q->next; //很重要
        }    
        else //关键点2
        {
            p=p->next;
            q=q->next;
        }
    }
    if(flag==0)
    {
        printf("%d是不存在的!\n",deldata);
        return -1;
    }
    return 0;
}

 

 

 

 

 //修改链表中的数据
int list_update(int newdata,int olddata)
{
    lb *p=myhead;
    int flag=0;
    while(p->next!=myhead)
    {
        flag=1;
        if(p->data==olddata)
            p->data=newdata;
        p=p->next;
    }
    //把最后一个位置的节点判断
    if(p->data==olddata)
    {
        flag=1;
        p->data=newdata;
    }
    return 0;
}

//打印遍历单链表
int list_show()
{
    lb *p=myhead;
    while(p->next!=myhead)
    {
        p=p->next; //循环结束p就到了尾部
        //打印当前p指向的那个节点里面的内容
        printf("目前遍历的数据是: %d\n",p->data);
    }
    
    return 0;    

主函数传参 

int main()
{
    //初始化单向循环链表
    list_init();
    
    //尾插两个数据
    list_add_tail(10);
    list_add_tail(11);
    list_add_tail(12);
    list_add_tail(11);
    list_add_tail(13);
    list_show();
    //中间插入数据
    //list_add(14,10); //14插入到11的后面
    //打印结果
    //printf("=============中间插入之后=============!\n");
    // list_show();
    
    //删除数据--》故意删除头节点
    //list_delete(12);
    //删除数据--》故意删除中间位置
    //list_delete(11); 
    //删除数据--》故意删除末尾位置
    //list_delete(13);
    //printf("=============删除之后=============!\n");
    //list_show();
    
    //修改数据
    list_update(8,10);
    printf("=============修改之后=============!\n");
    //打印结果
    list_show();
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值