基于linux的C语言

本文详细介绍了链式存储的概念,特别是在C语言中如何实现。内容涵盖单向列表、头指针、节点定义、链表创建、元素插入、删除、查找、修改和显示等操作。此外,还讨论了单向循环链表和双向链表的结构及修改方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据结构中的链式存储

一,概念

        程序中存储多个数据时,数据与数据之间的存储不⼀定是连续的,数据元素 的存储位置可以是任意的,随机的。不能像之前的顺序存储⼀样,可以使⽤ 地址来表⽰先后。链式存储就不⾏,不能⽤地址的先后来表⽰。

        链式存储:存储 数据+关系

                             数据元素:   

数据(前一个元素的地址)关系(后一个元素的地址)

        即在存储数据的同时也存储数据的关系,用来表示数据间的先后关系。

二,单向列表

       概念: 在使用有先后关系的链式存储时,在存储关系时只存储后一个元素的地址就能知道元素的值。

                           链表元素(图形表示):   

                                next(下一个元素的地址)

        链表元素(代码表示):

         struct node

         {

                xxx data;

                 struct node * next;

         }; 

        链表概念

        1. 头指针:是⼀个指针,存储链表中第0个元素的地址(永远表⽰链表的 开始);便于说明链表的位置,⽅便后期找到链表

        2. 节点:链表中的⼀个元素就叫做⼀个节点 头节点:在链表中通常会加⼊⼀个不存储任何数据的空节点,作为链表 的第0个元素,作⽤是之后⽅便操作链表。

        链表的运算

        创建链表

        执行链表的运算首先就得创建一个链表

//类型声明
#include<stdio.h>

//类型声明
struct node
{
	int data;
	struct node * next;
};

//创建一个链表
struct node * create()
{
	//创建一个空节点,头节点不存储任何数据相当于空节点
	struct node * p = malloc(sizeof(struct node));	//申请一个结构体作为空节点。
	if(p == NULL)
	{
		printf("malloc error\n");
		return NULL;
	}
	//头节点不存储任何数据,所以p->next是没有数据的。
	p->next = NULL;
	return p;

}

        1, 链表元素插⼊

                要插入一个数据元素,就是把要插入位置的数据元素向后移动然后插入需要插入的数据元素。即先移位后插入

void insert(struct node * head,int pos,int data)	//head;头指针,头节点的地址
{

	
	struct node * p = head;//p也是头节点的地址

	int i = 0;//当前有0个
	
	//找到待插入的前一个元素的地址
	while(p->next != NULL && i < pos-1)//条件就是i == pos前一个   pos作为元素地址下标
	{
		p = p->next;//p
		i++;
	}

	//p;就是要插入位置的前一个
	//创建新节点
	struct node * q = malloc(sizeof(struct node));
	q->data = data;

	//插入数据元素
	q->next = p->next;
	p->next = q;
}

//函数调用
int main()
{
struct node * head = create();

	insert(head,插入位置的地址下标,10);
}

        2, 删除元素

        要删除数据元素首先要确定数据元素是否为空。

//删除数据元素
int empty(struct node * head)	//要删除数据元素首先要判断数据元素是否存在。
{
	if(head->next == NULL)
	{
		printf("is empty\n");	//如果数据元素不存在就返回为1
		return 1;
	}
	else
		return 0;	//如果数据元素存在就返回0
}
//执行数据的删除
void del(struct node * head,int data)	
{

	struct node * p = head;	//head和p都作为头节点

	if( empty(head) )
	{
		return ;	//数据元素不为空就执行操作
	}

	while(p->next != NULL)
	{
		if(p->next->data == data)	//找到要删除的数据元素。
		{
			struct node * q = p->next;//q就是要删除的数据元素的地址下标
			p->next = q->next;
			printf("del is %d\n",q->data);
			free(q);	//申请的空间需要得到释放
			break;
		}
		p = p->next;
	}

}

//函数调用
int main()
{
struct node * head = create();

	del(head,数据元素下标);
}

        3,查找:

//判断数据元素是否存在
int empty(struct node * head)	
{
	if(head->next == NULL)
	{
		printf("is empty\n");	//如果数据元素不存在就返回为1
		return 1;
	}
	else
		return 0;	//如果数据元素存在就返回0
}
//查找数据元素
void search(struct node * head,int data)
{
	
	if( empty(head) )	//首先也的判断数据元素是否为空。
	{
		return ;	//数据元素不为空就执行操作
	}
	struct node * p = head;

	while(p->next != NULL)
	{
		p = p->next;
		if( p->data == data )
		{
			printf("find data %d\n",data);
			return ;
		}
	}
}

//函数调用
int main()
{
struct node * head = create();

	search(head,需要查找的数据元素下标);
}

         4,修改

        需要修改一个数据元素首先就要找打这个数据元素。

//修改数据元素
void update(struct node * head,int src,int dest)
{

	struct node * p = head;

	while(p->next != NULL)	//要修改数据元素首先要找到这个数据元素然后再执行操作。
	{
		p = p->next;
		if( p->data == src )
		{
			p->data = dest;	//找到数据元素执行修改。
			printf("update ok\n");
			return ;
		}
	}

}
//函数调用
int main()
{
struct node * head = create();

	update(head,需要被修改的元素的地址下标,修改后的数据元素);
}

        5,显示所有的数据元素

//显示所有的数据元素
void show(struct node * head)
{

	struct node * p = head;

	//struct node * p = head->next;   p != NULL
	while(p->next != NULL)	//当数据元素为空就停止访问
	{
		p = p->next;
		printf("%d ",p->data);
	}
	printf("\n");

}
//函数调用
int main()
{
struct node * head = create();

	show(head);
}

        单向循环链表: 整个数据的最后一个元素不在是空(NULL)而是指向头指针,存储head。

即:P->NULL改为p->head.

        双向链表:数据的关系不再是只存储后一个元素的地址,而是存储前一个和后一个的地址。

        数据元素(图形说明):

数据关系 prior(前一个元素的地址)关系next(后一个元素的地址)

         数据元素(代码说明):

                        struct  node

                        {

                                xxx data;

                                struct  *prior(前一个元素的地址)

                                struct  *next(后一个元素的地址);

                         };

在创建链表时,只需要在单向列表的基础上加上  p->prior==NULL即可。

在修改链表数据时:

        q->prior = p;

        q->next = p->next;

        p->next = q;

        q->next->prior = q;

在删除链表数据元素时:

        q = p->next;

        p->next = q->next;

        q->next->prior = p;

        free(q);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值