数据结构——初识链表(c语言实现)

初识链表

在存储一大波数的时候,我们通常使用的是数
组,但有时候数组显得不够灵活,比如下面例子。
有一串已经从小到大拍好序的数:2 3 5 8 9 10 18 26 32。现在需要往这组数里面插入数字6,使得这组数仍符合从小到大排列。如果我们使用数组来操作,则需要把8 9 10 18 26 32分别往后挪一位,如下:
在这里插入图片描述
以上只是在9个数的数组里插入一个数,这里只需要挪动6次。如果我们有100个数呢,10000个数呢???这样操作效率是否很低?那么我们如果使用了链表则会大大提高效率。那什么是链表?请看下图:
在这里插入图片描述

malloc函数

首先在写程序之前,我们先来熟悉一个函数:

malloc(4);

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

malloc(sizeofint);

现在你已经成功申请了4个字节的空间来准备存放一个整数,那么如何来对这个空间进行操作呢?这里我们需要用一个指针来指向这个空间,即存储这个空间的首地址。

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

malloc函数的返回值类型是 void *类型。void *表示未确定类型的指针。在c/c++中,void *类型可以强制转换为任何其他类型。上面代码中我们将其强制转换成整型指针,以便告诉计算机4个字节作为一个整体用来存放整数。

好!了解了数组,了解了指针和结构体,然后又认识了malloc函数,现在我们可以写代码了。

用链表的方法,在一组有序的数中,插入一个数。

首先我们先定义一个结构体类型来存放这个结点,如下:

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

上面代码中,我们定义了一个叫做node的结构体类型,这个结构体类型有两个成员。一个是整形data,用来存储具体数值,第二个成员是一个指针,用来存放下一个节点地址。因为下一个结点地址的类型也是struct node,所以这个指针的类型也必须是struct node*类型的指针。

完整代码解析

#include<stdio.h>
#include<stdlib.h>//malloc函数需要的头文件
//创建一个结构体用来表示链表的结点类型
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++)//循环读入n个数
	{
		scanf("%d",&a);
		p=(struct node *)malloc(sizeof(struct node));
		//动态申请一个空间,用来存放一个结点,并用临时指针p这个结点 
		p->data=a;//将数据存储到date数据域中 
		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;//指向下一个结点数据域 
	}

	/***插入一个数***/
	printf("\n");
	int num;
	scanf("%d",&num);//输入要插入的数
	t=head;//从链表头部开始遍历
	while(t!=NULL)//当没有到达链表尾部的时候循环
	{
		if(t->next->data>num)
		//如果当前结点下的下一个结点的数值大于待插入数,将数插入到中间用来存放新增结点
		{
			p=(struct node *)malloc(sizeof(struct node));
			//动态申请一个空间,用来存放一个结点,并用临时指针p这个结点
			p->data=num;
			p->next=t->next;
			//新增结点的后继指针指向当前结点的后继指针所指向的结点
			t->next=p;//当前结点的后继指针指向新增结点
			break;//插入完毕之后结束循环
		}
		t=t->next;//继续下一个结点
	}
	
	/*输出链表中的所有数*/
	t=head;
	while(t!=NULL)
	{
		printf("%d   ",t->data);
		t=t->next;//指向下一个结点数据域 
	}

看完以上内容,你是否能举一反三呢?上面是一组有序数列中插入一个数,那么我们能否根据上面知识点写一段在有序数列中删除一个数的程序呢?

代码段下回分享!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值