C语言:学习单链表

首先,为什么要用到链表?以建立一个通讯录为例,我们需要这个程序来存储我的联系人列表,对每个联系人,我要记录他的名字和电话号码。我们可能会想到用结构数组来实现。

代码示例:

#include<stdio.h>

#define NSIZE 45 /*存放名字的数组大小*/

#define MAX 10 /*最多的联系人数量*/

 

struct people{

    char name[NSIZE];

    char phone[NSIZE];

};

int main()

{

    struct people lianxiren[MAX];

    int i=0;

    int j;

 

    puts("输入第一个联系人的名字:");

    while(i<MAX && gets(lianxiren[i].name)!=NULL && lianxiren[i].name[0]!='\0')

    {

        puts("输入电话号码:");

        scanf("%s",&lianxiren[i].phone);

        i++;

        while(getchar()!='\n')

            continue;

        puts("输入下一个联系人的姓名(回车键停止):");

    }

    if(i==0)

        printf("没有数据输入!\n");

    else

        printf("联系人列表:\n");

    for(j=0;j<i;j++)

        printf("姓名: %s 电话: %s\n",lianxiren[j].name,lianxiren[j].phone);

    printf("再见!\n");

    return 0;

}

运行结果:

151535_RnID_2864258.png

     我们发现,程序创建了一个结构数组,然后用户把数据填充到这个数组中。直到数组满(大于MAX)或者gets()失败时,或按下回车键,输入才会停止。

     这种方式存在一些问题。这个程序最多只能存储10个联系人,如果我们将MAX值改的大一些,例如500,他可以存储较多的联系人,但是当你只存寥寥几个联系人时,就浪费了大量的内存。还有如果相对原有的数据进行增加删除工作时也会很麻烦。也就是说这种数据表示不够灵活。

     这是我们就可以用链表来进行灵活、动态的操作。

 

     我们可以这样定义结构:

#define NSIZE 45 /*存放名字数组大小*/

typedef struct people {

     char name[NSIZE];//姓名,数据域

     char phonep[NSIZE];//电话,数据域

     struct people * next;//指针指向下一个结构体,指针域

}Linklist,*LNode;

结点图示:

151547_BdDJ_2864258.png

流程图示:

1、开辟头结点空间

151556_87VF_2864258.png

2、prev指向头结点,开辟curren指向的结点空间,采集数据

151607_cTxV_2864258.png

3、尾插法插入

151619_Kkoj_2864258.png

代码示例:

#include <stdio.h>

#include <stdlib.h>/*提供malloc()原型*/

#include <string.h>/*提供strcoy()原型*/

#define NSIZE 45    /*存放数组大小*/

typedef struct people{

    char name[NSIZE];

    char phone[NSIZE];

    struct people * next;

}Linklist,*LNode;

 

int main(void)

{

    Linklist *head;/*生成原始结点*/

    Linklist *prev,*curren;

    char flag='y';

 

    head=(LNode)malloc(sizeof(Linklist));/*开辟空间并被head指向*/

    head->next=NULL;/*封口*/

 

    prev=head; /*prev指向头结点*/

 

    while(flag=='y' || flag=='Y')

    {

        /*开辟空间,被curren指向*/

        curren=(LNode)malloc(sizeof(Linklist));

        /*收集并存储信息*/

        puts("姓名:");

        scanf("%s",curren->name);

        puts("电话:");

        scanf("%s",curren->phone);

        /*curren节点封口*/

        curren->next=NULL;

        /*尾插法 原结点尾部插入curren结点*/

        prev->next=curren;

        prev=curren;

        /*插入操作结束*/

        /*清除输入缓存*/

        fflush(stdin);

        puts("是否继续?(y/n)");

        flag=getchar();

    }

    /*输出存储的联系人及信息*/

    /*prev指向首结点*/

    prev=head->next;

    while(prev)

    {

        printf("姓名:%s 电话:%s\n",prev->name,prev->phone);

        /*指针后移*/

        prev=prev->next;

    }

    puts("再见!\n");

    return 0;   

}

运行结果:

转载于:https://my.oschina.net/superwuyaowork/blog/727241

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值