单向链表常见操作

.h文件 

#ifndef _LINKLIST_H_
#define _LINKLIST_H_
#include <stdio.h>
#include <stdlib.h>
typedef int datatype;//方便后期更改数据类型
typedef struct node_t
{
	datatype data;//数据域
	struct node_t *next;//指针域,指向自身结构体的指针
}link_node_t,*link_list_t;//*link_list_t就相当于link_node_t *
//1.创建一个空的单向链表(有头单向链表)
link_node_t *CreateEpLinkList();
//2.向单向链表的指定位置插入数据
//p保存链表的头指针 post 插入的位置 data插入的数据
int InsertIntoPostLinkList(link_node_t *p,int post, datatype data);
//3.遍历单向链表
void ShowLinkList(link_node_t *p);
//4.求单向链表长度的函数
int LengthLinkList(link_node_t *p);
//5.删除单向链表中指定位置的数据 post 代表的是删除的位置
int DeletePostLinkList(link_node_t *p, int post);
//6.判断单向链表是否为空 1代表空 0代表非空
int IsEpLinkList(link_node_t *p);
//7.修改指定位置的数据 post 被修改的位置 data修改成的数据
int ChangePostLinkList(link_node_t *p, int post, datatype data);
//8.查找指定数据出现的位置 data被查找的数据 //search 查找
int SearchDataLinkList(link_node_t *p, datatype data);
//9.删除单向链表中出现的指定数据,data代表将单向链表中出现的所有data数据删除
int DeleteDataLinkList(link_node_t *p, datatype data);
//10.转置链表
void ReverseLinkList(link_node_t *p);
//11.清空单向链表
void ClearLinkList(link_node_t *p);
#endif

.c文件 

#include <stdio.h>
#include<stdlib.h>
#include "linklist.h"
//1.创建一个空的单向列表
link_node_t *CreateEpLinkList()
{
    //创建一个头节点
    link_list_t p = (link_list_t)malloc(sizeof(link_node_t));
    if (NULL == p)
    {
        perror("p malloc err");
        return NULL;
    }
    p->next = NULL;
    return p;
}
//遍历单向列表
void ShowLinkList(link_node_t *p)
{
    while(p->next!=NULL)
    {
        p=p->next;
        printf("%d ",p->data);
    }
    printf("\n");
}

//求单向链表长度
int LengthLinkList(link_node_t *p)
{
    int len=0;
    while(p->next!=NULL)
    {
        p=p->next;
        len++;
    }
    return len;
}
//2.向单向列表指定位置插入数据
int InsertIntoPostLinkList(link_node_t *p,int post,datatype data)
{
    int i;
    link_list_t pnew = NULL;
    //容错处理
    if(post<0||post>LengthLinkList(p))
    {
        printf("InsertIntoPostLinkList err\n");
        return -1;
    }
    //将头指针移动到插入位置的前一个节点
    for (i = 0; i < post; i++)
        p = p->next;
    //创建一个新节点,用来保存插入的数据
    pnew=(link_list_t)malloc(sizeof(link_node_t));
    if(NULL==p)
    {
        perror("pnew malloc err");
        return -1;
    }
    pnew->data=data;
    pnew->next=NULL;//分别赋值
    //将新节点插入链表,先连后面,再连前面
    pnew->next=p->next;//连后面
    p->next=pnew;//连前面
    return 0;
}
//判空函数,只有头的时候为空,p->next=NULL
int IsEpLinkList(link_node_t *p)
{
return p->next==NULL;
}

//删除
int DeletePostLinkList(link_node_t *p,int post)
{
    int i;
    link_list_t pdel=NULL;
    //容错处理
    if(post<0||post>=LengthLinkList(p)||IsEpLinkList(p))//插入可以等于长度,但是删除不行
    {
        printf("DeletePostLinkList err\n");
        return -1;
    }
    //将头节点指向被删除节点的前一个位置
    for(i=0;i<post;i++)
    p=p->next;
    //进行删除操作
    //定义pdel指针指向被删除的节点
    pdel=p->next;
    //跨过被删除节点
    p->next=pdel->next;
    //释放被删除的节点
    free(pdel);
    pdel=NULL;
    return 0;
}
//7.修改指定位置的数据 post 被修改的位置 data修改成的数据
int ChangePostLinkList(link_node_t *p, int post, datatype data)
{
    int i;
    //容错处理
    if(post<0||post>=LengthLinkList(p))//插入可以等于长度,但是删除不行
    {
        printf("ChangePostLinkList err\n");
        return -1;
    }
    //头指针移动到被修改的节点位置
    for(i=0;i<=post;i++)
    {
        p=p->next;
    }
    //修改数据
    p->data=data;
    return 0;
}
//8.查找指定数据出现的位置 data被查找的数据 //search 查找
//循环着找
int SearchDataLinkList(link_node_t *p, datatype data)
{
    int post=0;
    while(p->next!=NULL)
    {
        p=p->next;//先向后走,再判断此时data域的内容
        if(p->data=data)
        return post;
        post++;//不相等的时候就++处理,是data的话就直接返回
    }
    return -1;//都不是的话就return-1.无这个数据
}
//9.删除单向链表中出现的指定数据,data代表将单向链表中出现的所有data数据删除
int DeleteDataLinkList(link_node_t *p, datatype data)
{
    link_list_t pdel=NULL;
    //定义一个指针指向p的下一个节点
    link_list_t q=p->next;//q代替p探路
    //用p遍历无头单向列表
    while (q!=NULL)
    {
        if(q->data==data)
        {
            //定义pdel指向删除节点
            pdel=q;
            //跨过被删除节点
            p->next=pdel->next;
            //释放删除节点
            free(pdel);
            pdel=NULL;
            //将q重新指向p下一个节点
            q=p->next;
        }
        else
        {
          p=p->next;
          q=p->next;
        }
    }
    return 0;
}
//10.转置链表
//先断开,重新排队
void ReverseLinkList(link_node_t *p)
{
    link_list_t temp=NULL;//暂时保存q的下一个节点
    //断头操作,先定义一个q,断头前保存头节点的下一个节点地址
    link_list_t q=p->next;//相对于指向无头单向链表的头指针
    //断开列表
    p->next=NULL;
    //遍历无头单向链表
    while(q!=NULL)
    {
        temp=q->next;//提前将q的下一个节点保存一下,别丢了
        //开始链接,先连后,再连前
        q->next=p->next;//q已经无法找到之前的下一个节点
        p->next=q;
        q=temp;//让q去移动,指向无头单向链表的下一个节点
    }

}
//11.清空单向链表
void ClearLinkList(link_node_t *p)
{
    link_list_t pdel=NULL;
    while(p->next!=NULL)
    {
        //将pdel指向被删除的节点,也就是头节点的下一个节点
        pdel=p->next;
        //跨过被删除节点
        p->next=pdel->next;
        //释放节点
        free(pdel);
        pdel=NULL;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值