单向不带头结点不带环的链表实现

本文详细介绍了单向不带头不带环链表的各种操作实现,包括初始化、打印、元素查找等基本功能,以及节点的插入、删除等高级操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表有很多种类,单向,双向,不带头,带头,不带环,带环,结合起来一共可以有八种链表形式;

今天我们来实现一种名字叫 单向不带头不带环的链表

下面就是每一部分的代码实现

首先我们要做的就是函数的声明,结构体的定义,头文件的引用

#pragma once
#define HEADER printf("\n----------%s------------\n",__FUNCTION__)
#include<stdio.h>
#include<stdlib.h>
#include<stddef.h>
typedef char linktype;
typedef struct linklist
{
    linktype data;
    struct linklist *next;
}linklist;
linklist *head;
void linklist_init(linklist **head);
linklist *creat(linktype value);
void linklist_print(linklist *head);
void linklist_pushback(linklist **head,linktype value);
void linklist_popback(linklist **head);
void linklist_pushfront(linklist **head,linktype value);
void linklist_popfront(linklist **head);
linklist *linklist_find(linklist *head,linktype value);
void linklist_pushhighleft(linklist **head,linklist *pos,linktype value);
void linklist_pushhighright(linklist **head,linklist *pos,linktype value);
void linklist_pop1(linklist **head,linklist *pos);
void linklist_pop2(linklist **head,linktype value);
void linklist_pop2plus(linklist **head,linktype value);
void linklist_nizhi(linklist *head);

接下来我们就要一步一步实现我们的功能
首先我们要初始化我们的链表;

链表的初始化
void linklist_init(linklist **head)
{
    if(head==NULL)
    {
        return;//非法输入
    }
    else
    {
        *head=NULL;
    }
}

链表打印代码的实现

void linklist_print(linklist *head)
{
    if(head==NULL)
    {
        return;//空链表
    }
    else
    {
        linklist *cur=head;
        while(cur)
        {
            printf("[%c|%p] ",cur->data,cur);
            cur=cur->next;
        }
        printf("\n");
    }
}

下来我们还要实现我们的创建函数的代码

linklist *creat(linktype value)
{
    linklist *newnode=(linklist *)malloc(sizeof(linklist));
    if(newnode==NULL)
    {
        return NULL;//申请失败
    }
    else
    {
        newnode->data=value;
        newnode->next=NULL;
        return newnode;
    }

}

好,我们准备工作都做好了,现在我们就要实现它的一些功能了

首先我们来实现链表的尾插

void linklist_pushback(linklist **head,linktype value)
{
    if(head==NULL)
    {
        return;//非法输入
    }
    if(*head==NULL)
    {
        *head=creat(value);
        return;
    }
    else
    {
        linklist *cur=*head;
        while(cur->next)
        {
            cur=cur->next;  
        }
        cur=creat(value);
    }
}

下面我们来实现尾删的功能

void linklist_popback(linklist **head)
{
    if(head==NULL)
    {
        return;//非法输入
    }
    if(*head==NULL)
    {
        return;//空链表    
    }
    else
    {
        linklist *cur=*head;
        while(cur->next->next)
        {
            cur=cur->next;
        }
        free(cur->next);
        cur->next=NULL;
    }


}

接着我们要来实现头插,头删的操作

void linklist_pushfront(linklist **head,linktype value)
{
    if(head==NULL)
    {
        return;//非法输入
    }
    if(*head==NULL)
    {
        *head=creat(value);
        return;
    }
    else
    {
        linklist *newnode=creat(value);
        newnode->next=*head;
        *head=newnode;
    }

}

头删

void linklist_popfront(linklist **head)
{
    if(head==NULL)
    {
        return;//非法输入
    }
    if(*head==NULL)
    {
        return;//空链表
    }
    eles
    {
        linklist *cur=*head;
        *head=(*head)->next;
        free(cur);
        cur=NULL;
    }
}

下面我们要实现的是给定元素,查找它的位置

linklist * linklist_find(linklist *head,linktype value)
{
    if(head==NULL)
    {
        return;//空链表
    }
    else
    {
        linklist *cur=head;
        while(cur!=NULL)
        {
            if(cur->data!=value)
            {
                cur=cur->next;
            }
            else
            {
                return cur;
            }
        }
        printf("没找到\n");
        return ;
    }
}

接下来我们要增加插入的难度,

首先我们就要进行,在指定位置之前插入元素value

void linklist_pushhighleft(linklist **head,linklist *pos,linktype value)
{
    if(head==NULL)
    {
        return;//非法输入
    }
    if(*head==NUll)
    {
        *head=creat(value);
        return;
    }
    else
    {
        linklist *cur=*head;
        while(cur->next!=pos)
        {
            cur=cur->next;
        }
        linklist *newnode=creat(value);
        newnode->next=pos;
        cur->next=newnode;
    }
}

在指定位置之后插入节点

void linklist_pushhighright(linklist **head,linklist *pos,linktype value)
{
    if(head==NULL)
    {
        return;//非法输入
    }
    if(*head==NULL)
    {
        *head=creat(value);
        return;
    }
    else
    {
        linklist *newnode=creat(value);
        newnode->next=pos->next;
        pos->next=newnode;
    }
}

下面我们要来实现删除的更高级版本

首先就是删除某一位置的节点

void linklist_pop1(linklist **head,linklist *pos)
{   
    if(head==NULL)
    {
        return;//非法输入
    }
    if(*head==NULL)
    {
        return;//空链表
    }
    if(*head==pos)
    {
        *head=pos->next;
        free(pos);
        pos=NULL;
    }
    else
    {
        linklist *cur=*head;
        while(cur->next!=pos)
        {
            cur=cur->next;
        }
        cur->next=pos->next;
        free(pos);
        pos=NULL;
    }

}

删除指定元素的节点

void linklist_pop2(linklist **head,linktype value)
{
    if(head==NULL)
    {
        return;//非法输入
    }
    if(*head==NULL)
    {
        return;//空链表
    }
    else
    {
        linklist *pos=linklist_find(*head,value);
        linklist_pop1(head,pos);
    }

}

删除指定元素的所有节点

void linklist_pop2plus(linklist **head,linktype value)
{
    if(head==NULL)
    {
        return;//非法输入
    }
    if(*head==NULL)
    {
        return;//空链表
    }
    else
    {
        linklist *cur=*head;
        while(cur!=NULL)
        {
            if(cur->data!=value)
            {
                cur=cur->next;
            }
            linklist *p=cur;
            cur=p->next;
            linklist_pop1(head,p);
        }

    }

}

最后我们来看下将链表逆序打印是如何操作的

void linklist_nizhi(linklist *head)
{
    if(head==NULL)
    {
        return;//空链表
    }
    else
    {
        linklist_nizhi(head->next);
        printf("[%c|%p] ",head->data,head);
    }
}

以上就是链表的一些功能的实现,相互学习,如果有错误,请指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值