链表(1)

在存储一大波数的时候,我们通常使用的数组,但有时候数组显得不够灵活,比如下面这个例子。
有一串已经从小到大排好序的数 2 3 5 8 9 10 18 26 32.现在需要往这串数中插入6使其得到的新序列仍符合从小到大排列。如果使用数组实现这一操作,则需要将8和8后面的数都依次往后挪一位。这样操作显然很耽误时间,如果使用链表则会快很多。
那该如何实现链表呢?在C语言中可以使用指针和动态分配内存函数malloc来实现。

malloc(4)

malloc函数的作用就是从内存中申请分配指定字节大小的内存空间。上面这行代码就申请了4个字节。如果你不知道int类型是4个字节的,还可以使用sizeof(int)获取int类型所占用的字节数,如下:

malloc(sizeofint));

这样就成功地从内存中申请了4个字节的空间来准备存放一个整数,这里需要用一个指针来指向这个空间,即存储这个空间的首地址。注意当在程序中使用malloc函数时需要用到stdlib.h头文件。

int *p;
p=int *)malloc(sizeofint));

现在我们可以通过指针p对刚才申请的4个字节的空间进行操作了,例如我们像这个空间中存入整数10,完整代码如下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *p;//定义一个指针p
    p=(int *)malloc(sizeof(int));//指针p获取动态分配的内存空间地址
    *p=10;//向指针p所指向的内存空间中存入10
    printf("%d",*p);//输出指针p所指向的内存中的值

    getchar();getchar();
    return 0;
}

运行结果是:

10

接下来就要看看链表中的每一个结点是如何存储的。
每一个结点都由两部分组成。左边部分用来存放具体的值,那么用一个整型变量就可以;右边的部分需要存储下一个结点的地址,可以用指针来实现(也称为后继指针)。这里可以定义一个结构体类型来存储这个结点,如下。

struct node
{
    int data;
    struct node *next;
};

上面代码中,我们定义了一个叫做node的结构体类型,这个结构体类型有两个成员。第一个是整型data,用来存储具体的数值;第二个成员是一个指针,用来存储下一个结点的地址。
要建立链表,首先需要一个头指针head指向链表的最开始。当链表还没有建立的时候指针head为空。

struct node *head;
head = NULL;//头指针初始为空

现在我们来创建第一个结点,并用临时指针p指向这个结点。

struct node *p;
//动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点
p=(struct node *)malloc(sizeof(struct node));

接下来分别设置新创建的这个结点的左半部分和右半部分。

scanf("%d",&a);
p->data=a;//将数据存储到当前结点的data域中
p->next=NULL;//设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空

然后来设置头指针并设置新创建结点的*next指向空。头指针的作用是方便以后从头遍历整个链表。

if(head==NULL)
    head=p;//如果这是第一个创建的结点,则将头指针指向这个结点
else
    q->next=p;//如果不是第一个创建的结点,则将上一个结点的后继指针指向当前结点

最后要将指针p也指向当前结点

q=p;//指针p也指向当前结点

完整代码如下。

#include<stdio.h>
#include<stdlib.h>
//创建一个结构体用来表示链表的结点类型 
struct node
{
 int data;
 struct node *next;
};
int main()
{
 struct node *head,*p,*q,*t;
 int i,n,a;
 scanf("%d",&n);
 head = NULL;//头指针初始为空 
 for(i = 1;i <= n;i++)
 {
  scanf("%d",&a);
  //动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点 
  p=(struct node *)malloc(sizeof(struct node));
  p->data = a;//将数据存储在当前结点的data域中 
  p->next = NULL;//设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空 
  if(head == NULL)
   head = p;//如果这是第一个结点,则将头指针指向这个结点 
  else
   q->next = p;//如果不是,则将上一个结点的后继指针指向当前结点 
  q=p;//指针q也指向当前结点 
 }
 //输出链表中的所有数 
 t = head;
 while(t!=NULL)
 {
  printf("%d",t->data );
  t=t->next ;//继续下一个结点 
 }
 return 0;
}

可以输入一下数据进行验证。

9
2 3 5 8 10 18 20 32

运行结果是:

2 3 5 8 10 18 20 32
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值