C语言-----线性单链表

所谓链表,就是用一组任意的存储单元存储线性表元素的一种数据结构。
链表又分为单链表、双向链表和循环链表等。我们先讲讲单链表。
所谓单链表,是指数据接点是单向排列的。一个单链表结点,其结构类型分为两部分:
1、数据域:用来存储本身数据
2、链域或称为指针域:用来存储下一个结点地址或者说指向其直接后继的指针。

struct stu{
    char            name[32];
    struct stu      *next;
};

这样就定义了一个单链表的结构,其中char name[20]是一个用来存储姓名的字符型数组,指针*link是一个用来存储其直接后继的指针。
定义好了链表的结构之后,只要在程序运行的时候爱数据域中存储适当的数据,如有后继结点,则把链域指向其直接后继,若没有,则置为NULL。
单链表的基本运算:
建立了一个单链表之后,如果要进行一些如插入、删除等操作该怎么办?所以还须掌握一些单链表的基本算法,来实现这些操作。单链表的基本运算包括:查找、插入和删除。
1、查找
对单链表进行查找的思路为:对单链表的结点依次扫描,检测其数据域是否是我们所要查好的值,若是返回该结点的指针,否则返回NULL。
因为在单链表的链域中包含了后继结点的存储地址,所以当我们实现的时候,只要知道该单链表的头指针,即可依次对每个结点的数据域进行检测。
2、插入(后插)
假设在一个单链表中存在2个连续结点p、q(其中p为q的直接前驱),若我们需要在p、q之间插入一个新结点s,那么我们必须先为s分配空间并赋值,然后使p的链域存储s的地址,s的链域存储q的地址即可。(p->link=s;s->link=q),这样就完成了插入操作。
3、删除
假如我们已经知道了要删除的结点p的位置,那么要删除p结点时只要令p结点的前驱结点的链域由存储p结点的地址该为存储p的后继结点的地址,并回收p结点即可。

下面是自己写的简单的单链表代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stu{
    char                    name[32];
    struct stu      *next;
};
/*创建链表,参数n是初始化链表时建立的数据个数
prev:指向当前结点的前一个结点
cur:指向当前结点
head:保存表头结点的指针*/
struct stu* CreatList(int n){
    int i;
    char age[12];
    struct stu *prev,*cur,*head;
    head=(struct stu*)malloc(sizeof(struct stu));
    if(head==NULL){
        printf("Can't alloc memory\n");
        return NULL;
    }
    prev=head;
    head->name[0]='\0';
    head->next=NULL;
    for(i=1;i<=n;i++){
        cur=(struct stu*)malloc(sizeof(struct stu));
        if(cur==NULL){
            printf("Can't alloc memory\n");
            return NULL;                
        }
        prev->next=cur;
        printf("请输入第%d个数据的姓名\n",i);
        printf("请输入姓名:");
        scanf("%s",cur->name);
        cur->next=NULL;
        prev=cur;
    }
    printf("创建链表成功!\n");
    return head;
}/*这样就写好了一个可以建立包含N个人姓名的单链表了。
写动态内存分配的程序应注意,请尽量对分配是否成功进行检测。*/

/*查找链表的函数,其中head指针是链表的表头指针,_name指针是要查找的人的姓名
返回值:返回与所要查找结点的地址*/
struct stu* SearchCur(struct stu *head,char *_name){
    struct stu  *cur,*tmp;
    char                *str;
    cur=head->next;
    while(cur!=NULL){
        str=cur->name;
        if( strcmp(str,_name)==0 ){
            printf("找到所需的数据\n");    
            return cur;
        }
        cur=cur->next;
    }
    if(cur==NULL)
        printf("没有找到所需的数据\n");  
}
/*查找链表的函数,其中head指针是链表的表头指针,_name指针是要查找的人的姓名
返回值:返回的是上一个查找函数的直接前驱结点的指针*/
struct stu * SearchFront(struct stu *head,char* _name){
    struct stu *cur,*fro;
    char             *str;
    cur=head->next;
    fro=head;
    while(cur!=NULL){
        str=cur->name;
        if(strcmp(_name,str)==0){
            printf("找到所需的数据\n");    
            return fro; 
        }
        cur=cur->next;
        fro=fro->next;
    }
    if(cur==NULL)
        printf("没有找到所需的数据\n");  
}
void Insert(struct stu *prev,char *_name){
    struct stu *ins;
    if((ins=(struct stu*)malloc(sizeof(struct stu)))==NULL){
        printf("Can't alloc memory\n");
        exit(1);            
    }
    strcpy(ins->name,_name);
    ins->next=prev->next;
    prev->next=ins;
}
void Delete(struct stu *fro,struct stu *del){
    struct stu *tmp;
    tmp=del;
    fro->next=del->next;
    free(tmp);
}
/*遍历链表,打印链表数据*/
void Print(struct stu *head){
    struct stu *cur;
    cur=head->next;
    while(cur!=NULL){
        printf("%s\n",cur->name);
        cur=cur->next;
    }
}
int main(){
    int number=3;
    char _name[32];
    struct stu *head,*cur,*fro;
    head=CreatList(number);
    if(head==NULL)
        return -1;

    Print(head);

    printf("请输入删除的姓名:");
    scanf("%s",_name);  
    cur=SearchCur(head,_name);
    if(cur==NULL)
        return -1;

    fro=SearchFront(head,_name);
    Delete(fro,cur);

    Print(head);

    printf("\n");
    return 0;   
}

输出结果:
请输入第1个数据的姓名
请输入姓名:kevin
请输入第2个数据的姓名
请输入姓名:tim
请输入第3个数据的姓名
请输入姓名:jobs
创建链表成功!
kevin
tim
jobs
请输入删除的姓名:tim
找到所需的数据
找到所需的数据
kevin
jobs

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值