2023/2/3日链表练习

head.h

#ifndef HEAD_H__
#define HEAD_H__



#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef char datetype;
typedef struct node
{
    //数据域
    union
    {
        int len ;
        datetype date;

    };
    //指针域
    struct node *next;
}*Linklist,Node;



Linklist Linklistcreate();
Linklist LinklistcreateNode();
void InsetHead(Linklist L,datetype e);
void Linklistshow(Linklist L);
void InsetRear(Linklist L,datetype e1);
void deleteHead(Linklist L);
void Delerear(Linklist L);

void Searchpos(Linklist L,int pos);
void UpdatebyPos(Linklist L,int pos,datetype e);
Linklist Searchbydate(Linklist L,datetype key);
void Linklistupdatebydate(Linklist L,datetype e6,datetype key);
void Linklistdeletebydate(Linklist L,datetype e);
void LinklistRev(Linklist L);
void LinklistSort(Linklist L);
void Insetpos(Linklist L,int pos,datetype e3);
void deleterear(Linklist L,int pos);



#endif

main.c

#include "head.h"
int main(int argc, const char *argv[])
{
    
    Linklist L= Linklistcreate();
    if(L==NULL)
        return -1;
#if 0
    //头插:永远在头部插入

    printf("输入链表中的数据元素\n");

    datetype e;
    int n=5;
    for(int i=0;i<n;i++)
    {
        scanf("%c",&e);
        getchar();
        InsetHead(L,e);
    }
    Linklistshow(L);
#endif
//尾插:把新节点存在最后一个节点的后面
    datetype e1;int n1=5;
    printf("输入插入的数据元素\n");
    for(int i=0;i<n1;i++)
    {
        scanf("%c",&e1);
        getchar();
        InsetRear(L,e1);
    }
    Linklistshow(L);
#if 0
    //头删
    deleteHead(L);
    Linklistshow(L);

//尾删
    Delerear(L);
    Linklistshow(L);
//按位置插入
    printf("按位置插入\n");
    int pos;
    datetype e3;
    scanf("%d",&pos);
    getchar();
    printf("请输入要插入的元素");
    scanf("%c",&e3);
    Insetpos(L,pos,e3);
    Linklistshow(L);
//链表按位置删除
    printf("\n输入删除的位置:");
    scanf("%d",&pos);
    deleterear(L,pos);

    Linklistshow(L);
//按位置查找
    printf("\n输入查找的位置");
    scanf("%d",&pos);
    Searchpos(L,pos);
    Linklistshow(L);
//链表按位置修改
    printf("\n输入修改的位置");
    int pos1;
    datetype e4;
    scanf("%d",&pos1);
    getchar();
    printf("输入修改的元素");
    scanf("%c",&e4);
    UpdatebyPos(L,pos1,e4);
    Linklistshow(L);
#endif
//链表按元素查找
    datetype e5;
    printf("\n输入查找的元素\n");
    scanf("%c",&e5);
    Linklist p=Searchbydate(L,e5);
    if(p==NULL)
    {
        printf("查找失败\n");
    }
    else
    {
        printf("%c在链表中出现\n",p->date);
    }
//链表按元素修改
    datetype e6;datetype e7;
    printf("\n请输入要修改的元素\n");
    getchar();
    scanf("%c",&e6);
    printf("\n请输入修改后的值");
    getchar();
    scanf("%c",&e7);
    Linklistupdatebydate(L,e6,e7);
    Linklistshow(L);
//链表按元素删除
    datetype e8;
    printf("\n请输入要删除的元素\n");
    getchar();
    scanf("%c",&e8);
    Linklistdeletebydate(L,e8);
    Linklistshow(L);
//链表逆置:
    LinklistRev(L);
    printf("逆置完成\n");
    Linklistshow(L);
//链表排序
    LinklistSort(L);
    //遍历链表
    printf("排序完成\n");
    Linklistshow(L);
//空间释放
    Free(L);
    L=NULL;
    return 0;
}

test.c

#include "head.h"
Linklist Linklistcreate()
{
Linklist L=(Linklist)malloc(sizeof(Node));
if(L==NULL)
return NULL;
//节点创建成功
L->len=0;//链表长度初始化;
L->next=NULL;//链表指向为空;
return L;
}
//创建普通节点
Linklist LinklistcreateNode()
{
Linklist p=(Linklist)malloc(sizeof(Node));
if(p==NULL)
return  NULL;
p->date=0;
p->next=NULL;//表示创建新节点指针域为空
return p;
}
//头插:永远在头结点后面插入
void InsetHead(Linklist L,datetype e)
{
//1,创建新节点
Linklist p=LinklistcreateNode();
if(p==NULL)
return;
//创建成功
p->date=e;//为新节点赋值;
p->next=L->next;//将原来L的next地址给p的next地址
L->next=p;//将p的地址给L的next
L->len++;//L的长度增加
}
//遍历链表
//无返回值函数
void Linklistshow(Linklist L)
{
printf("输出链表中数据元素\n");
while(L->next)
{
L=L->next;
printf("%c\t",L->date);
}
printf("\n");
}
//单向链表尾插
void InsetRear(Linklist L,datetype e1)
{
//先创建一个新节点
Linklist p=Linklistcreate();
if(p==NULL)
return;
//找到最后一个节点
Linklist q=L;
while(q->next!=NULL)
{
q=q->next;
}
//把新节点插入到最后一个节点的后面
p->date=e1;
q->next=p;
L->len++;
}
//头删:永远山粗头节点的后继节点
//无返回值函数
void deleteHead(Linklist L)
{
//判断链表是否为空
if(L->next==NULL)
return;
//删除
Linklist p=L->next;
L->next=p->next;
free(p);
p=NULL;
L->len--;
}
//尾删:永远只删除最后一个节点
void Delerear(Linklist L)
{
if(L->next==NULL)
return;
Linklist p=L;
for(int i=0;i<L->len-1;i++)
{
p=p->next;
}
free(p->next);
p->next=NULL;
L->len--;
} 
//按位置插入
void Insetpos(Linklist L,int pos,datetype e3)
{
if(L->next==NULL||pos<1||pos>L->len+1)
return;
Linklist p=L;
for(int i=0;i<pos-1;i++)
{
p=p->next;
}
Linklist s=Linklistcreate();
s->date=e3;
s->next=p->next;
p->next=s;
L->len++;
}
//链表按位置删除
void deleterear(Linklist L,int pos)
{
if(L->len==0||pos<1||pos>L->len)
{
return;
}
Linklist p=L;
for(int i=0;i<pos-1;i++)
{
p=p->next;
}
Linklist q=p->next;
p->next=q->next;
free(q);
q=NULL;
L->len--;
}
//按位置查找
void Searchpos(Linklist L,int pos)
{
if(L==NULL||pos<1||pos>L->len)
return;
Linklist p=L;
for(int i=0;i<pos;i++)
{
p=p->next;
}
printf("%d位置的元素为%c",pos,p->date);
}
//按位置修改数据元素
void UpdatebyPos(Linklist L,int pos,datetype e)
{
if(L->len==0||pos<1||pos>L->len)
return;
for(int i=0;i<pos;i++)
{
L=L->next;
}
L->date=e;
}
//链表按元素查找
Linklist Searchbydate(Linklist L,datetype key)
{
if(L->len==0)
{
return NULL;
}
Linklist p=L;
for(int i=1;i<=L->len;i++)
{
p=p->next;
if(p->date==key)
{
return p;
}
}
return NULL;
}
//链表按元素修改
void Linklistupdatebydate(Linklist L,datetype e6,datetype key)
{
Linklist q=Searchbydate( L, e6);
if(q==NULL)
{
printf("链表中没有此元素\n");
return;
}
q->date=key;
}
//链表按元素删除
void Linklistdeletebydate(Linklist L,datetype e)
{
if(L->len==0)
return;
Linklist p=L;
for(int i=1;i<L->len;i++)
{
p=p->next;
if(p->date==e)
{
deleterear(L,i);
return;
}
}
}
//链表逆置
void LinklistRev(Linklist L)
{
Linklist p=L->next;//将头节点的位置保存
L->next=NULL;//让头节点孤立
while(p)
{
Linklist k=p;//将p保存于k中
p=p->next;//p开始后移
k->next=L->next;//开始从头节点插入
L->next=k;
}
}
//链表排序
void LinklistSort(Linklist L)
{
Linklist p=L->next;//将头节点的next赋给p
L->next=NULL;//讲头节点与后面分割开
while(p)
{
Linklist t=p;//将偏移后的p保存下来
p=p->next;//p再偏移
Linklist q=L;//将头节点再赋给q
while(q->next!=NULL&&q->next->date<t->date)//判断条件,新加入的节点后不为0并且与要加入的值比较
{
q=q->next;//如果满足就后移
}
//找到了要加入的前一个节点位置,然后按位置加入
t->next=q->next;
q->next=t;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值