用C语言完成单向链表

有头单向链表操作思想

1、链表插入:

解题思想:

1、先遍历找到要插入节点的前一个节点,假设这个节点为A;A的下一个节点为B;

将C插入A与B之间;

2、先让C的指针域指向B;

3、再让A的指针域指向C;

注意:顺序不可以调换

2、链表删除:

解题思想:

1、先遍历找到要删除节点的前一个节点,假设为A;

2、找一个临时指针指向要删除的节点;

3、将A的指针域指向删除节点的下一个节点;

3、转置链表:

解题思想:

1、将头节点与当前链表断开,断开前保存头节点的下一个节点,保证后面链表能找得到,定义一个q保存头节点的下一个节点,断开后前面相当于一个有头的空链表,后面是一个无头的单向链表

2、遍历无头链表的所有节点,将每一个节点当做新节点头插到有头空链表中(每次插入到头节点的下一个节点位置)

void ReverseLinkList(link_node_t *p)

4、链表清空:

.h文件

#ifndef __LIANBIAO_H__
#define __LIANBIAO_H__
#include <stdio.h>//在自己的.h文件中包含表准头文件
#include <stdlib.h>//需要用到malloc函数
#define bian int//将整形定义成宏
typedef struct lianbiao
{
    bian data;//存放数据
    struct lianbiao* next;//存放下一位的地址
}lianshu,*lianzhi;
//创建一个空表
lianshu *kongbiao();
//插入一个链式数据
int chalu(lianshu *p,int post,bian data);
//便利单项链表
void zhanshi(lianshu *p);
//求单项链表的长度
int qiuchang(lianshu *p);
//删除单项链表
int shanchu(lianshu *p,int post);
//转至链表
int zhuanzhi(lianshu *p);
//修改指定位置的数据
int xiugai(lianzhi p,int post,bian data);
//找到数据出现的位置
int zhao(lianzhi p, bian data);
//删除指定的数据
int shanzhi(lianzhi p,bian data);
//判断是否为空
int pankong(lianzhi p);
//清空数据链表
void qingkong(lianzhi p);


#endif

. c文件

#include "lianbiao.h"
//创建一个空表
lianshu *kongbiao()
{
    lianshu *h = (lianzhi)malloc(sizeof(lianshu));//定义一个结构体指针,开辟一个堆区空间,做为表头
    if(NULL == h)//如果指针指向空
    {
        printf("malloc head node filed\n");
        return NULL;//开辟空间失败,返回空
    }
    h->next = NULL;//开辟成功,将结构体指针中的成员next指针指向空
    return h;//返回h的地址,传值
}
//插入一个链式数据
int chalu(lianshu *p,int post,bian data)//传值:指向链表的指针,要插入的位置,要插入的数据
{
    if(post < 0 || post > qiuchang(p))//如果位置小于0,或者位置大于次函数返回的值,函数判断链表的大小
    {
        printf("输入的位置有问题\n");
        return -1;//返回-1
    }
    lianshu *pnew = (lianzhi)malloc(sizeof(lianshu));//定义一个结构体指针变量pnew,开僻一个新的堆区空间
    if(NULL == pnew)//判断是否开辟成功
    {
        printf("malloc pnew node filed\n");
        return -1;
    }
    //开辟成功初始化结构体的成员变量
    pnew->data=data;//data变量赋值为data
    pnew->next=NULL;//结构体指针pnew变量的成员next结构体指针指向空
    int i;
    for(i=0;i<post;i++)//从零开始,到达要插入对象的前一位(<)
    {
        p = p->next;//将指针p的值改为链表的下一为(指针p往后移动)
    }
    pnew->next = p->next;//将指针p中的指针变量next里存的地址付给pnew指针的next的指针变量
    p->next = pnew;//将指针pnew指向的地址赋值给p指针的next指针成员
    return 0;
}
//便利单项链表
void zhanshi(lianshu *p)
{
    while(p->next != NULL)//当指针p指向的结构体成员next指针的指向不是空时
    {
        p = p->next;
        printf("%d ",p->data);
    }
    printf("\n");
}
//删除单项链表
int shanchu(lianshu *p,int post)//传值:指向链表的指针,要删除的位置
{
    if(post < 0 || post >= qiuchang(p))//判断位置输入的是否合理
    {
        printf("输入的位置有问题\n");
        return -1;
    }
    int i;
    for(i=0;i<post;i++)//找到要删除的前一位
    {
        p = p->next;
    }
    lianzhi pdel = p->next;//定义一个新的结构体指针,指向要删除的节点
    p->next = pdel->next;//将指针p指向的结构体中next指针指向指针pdel指向的结构体中next中存的地址(pdel->next中存的是下一位的首地址)
    free(pdel);//放空没用的指针
    pdel = NULL;//将没用的指针指向空
    return 0;
}
//求单项链表的长度
int qiuchang(lianshu *p)
{
    int len = 0;
    while(p->next != NULL)
    {
        p = p->next;
        len++;
    }
    return len;
}
//转至链表
int zhuanzhi(lianshu *p)
{
        lianzhi q = p->next;
        lianzhi temp = NULL;//用来存放q的下一位地址
        //将头文件和后面的链表断开
        p->next = NULL;
        //便利无头单项链表
        while(q != NULL)//当p不指向空时:如果是最后一位,p->next是空,会把空置传给temp,循环完成后结束
        {              //但不可以直接p->next != NULL 这样判断不会执行最后一位
            //用temp临时记录一下q的下一个节点
            temp = q->next;
            //插入动作
            q->next = p->next;
            p->next = q;
            q = temp;//将下一个节点的位置付给q,开始下一轮循环
        }
        return 0;
}
//修改指定位置的数据
int xiugai(lianzhi p,int post,bian data)
{
    if(post < 0 || post > qiuchang(p))
    {
        printf("输入的位置有误\n");
        return -1;
    }
    int i;
    for(i = 0;i<post;i++)
        p = p->next;
    p->data = data;
    return 0;
}
//找到数据出现的位置
int zhao(lianzhi p, bian data)
{
    int le=0;
    while(p->next != NULL)
    {
        p = p->next;
        if(p->data == data)
        {
            printf("%d\n",le);
            return le;
        }
        le++;
    }
    return -1;
}
//删除指定的数据
int shanzhi(lianzhi p,bian data)
{
    lianzhi pdel =NULL;
    if(pankong(p))
    {
        printf("错误\n");
        return -1;
    }
    while(p->next != NULL)
    {
        if(p->next->data == data)//指针p指向的下一个地址的数据等于要删除的数据
        {
            pdel = p->next;//指针pdel指向p指针指向的下一个地址
            p->next = pdel->next;//吧pdel指向的下一个地址付给指针p的next
            free(pdel);//放空对空间
            pdel = NULL;//指针pedl指向空
        }
        else
        {
            p = p->next;//指针p往后移
        }
    }
    return 0;
}
//判断是否为空
int pankong(lianzhi p)
{
    return p->next == NULL;
}
//清空数据链表
void qingkong(lianzhi p)
{
    lianzhi pdel = NULL;
    while(p->next != NULL)
    {
        pdel = p->next;//将p的下一位地址传给pdel
        p->next = pdel->next;//将pdel的下一位地址传给p的next
        free(pdel);//放空pdel
        pdel = NULL;//让pdel指向空
    }
}

main.c文件可以根据自己的需要调用函数

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值