链表(一)

在C语言中,链表是我们不可避免的难题,如何解决成为了一个问题,首先我们需要先认识链表…

链表的定义

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
简单来说,链表就是动态分配的存储结构,由多个结点构成,各节点包括:1.数据域 2.指针域。从链表的实现方式一般分为单链表、双链表、循环链表。

链表与数组的区别

从链表与数组的功能来看,链表是一个功能更强大的数组,那么两者有什么区别呢?
1.内存分配 数组静态分配内存,链表动态分配内存;
2.内存存储 数组在内存中连续,链表不连续;
3.定位方式 数组利用下标定位,时间复杂度为O(1),链表需要从头遍历,时间复杂度O(n);
4.插入删除方式 数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1)。
5.内存利用 申请数组前需要规定大小,可能会浪费空间,链表的空间利用率较高

数组的优点

  • 随机访问性强(通过下标进行快速定位)
  • 查找速度快

数组的缺点

  • 插入和删除效率低(插入和删除需要移动数据)
  • 可能浪费内存(因为是连续的,所以每次申请数组之前必须规定数组的大小,如果大小不合理,则可能会浪费内存)
  • 内存空间要求高,必须有足够的连续内存空间
  • 数组大小固定,不能动态拓展

链表的优点

  • 插入删除速度快(通过改变指针的指向可以方便的增加删除元素)
  • 内存利用率高,不会浪费内存(可以使用内存中细小的不连续空间(大于node节点的大小),并且在需要空间的时候才创建空间,不需要时可以释放)
  • 大小没有固定,拓展很灵活。

链表的缺点

  • 不能随机查找,必须从第一个开始遍历,查找效率低!

单链表

在这里插入图片描述
单链表的声明

strcut node
{
	int data;//数据
	strcut node *pnext;//指针指向下一结点
};
int count;//记录链表长度(全局变量)

单链表的建立

struct node*create()
{
	strcut node *phead=NULL;
	struct node *pnew,*pend;
	pnew=pend=(struct node *)malloc(sizeof(struct node));
	scanf("%d",&pnew->data);
	while(pnew->data>0)
	{
		if(count==1)
		{
			pnew->next=phead;
			pend=pnew;
			phead=pnew;
		}
		else
		{
			pnew->next=NULL;
			pend->next=pnew;
			pend=pnew;
		}
		pnew=(struct node *)malloc(sizeof(struct node));
		scanf("%d",&pnew->data);
	}
	free(pnew);
	return phead;
}

单链表的插入(头插法)

struct node* insert(struct node *phead)
{
	struct node *pnew;
	pnew=(struct node*)malloc(sizeof(struct node));
	scanf("%d",&pnew->data);
	pnew->next=phead;	
	phead=pnew;	
	count++;	
	return phead;
}

单链表的插入(尾插法)

struct node* insert(struct node *phead)
{
	struct *pnew,*pend;
	pend=phead;
	while(pend&&pend->next!=NULL)
	pend=pend->next;
	pnew=(struct node*)malloc(sizeof(struct node));
	scanf("%d",&pnew->data);
	pend->next=pnew;
	pnew->next=NULL;
	count++;
	return phead;
}

单链表在某一位置处插入(比如在数据flag的位置后插入)

struct node* insert(struct node *phead,int flag)
{
	struct *pnew,*ptemp;
	ptemp=phead;
	while(ptemp&&ptemp->data!=flag)
	ptemp=ptemp->next;
	pnew=(struct node*)malloc(sizeof(struct node));
	scanf("%d",&pnew->data);
	pnew->next=ptemp->next;
	ptemp->next=pnew;
	count++;
	return phead;
}

单链表的删除

struct node* del(struct node *phead,int index)//**index**是要删除的结点数
{
	int i;
	struct node *ppre,*ptemp;
	ppre=ptemp=phead;
	for(i=0;i<index;i++)
	{
	ppre=ptemp;
	ptemp=ptemp->next;
	}//从开始到要删除的节点依次遍历,找到要删除的结点前的结点;
	ppre->next=ptemp->next;//将要删除的结点前的结点的指针,指向要删除的结点指向的结点
	free(ptemp);
	return phead;
}

在这里插入图片描述
单链表的查找

void search(struct node *phead)
{
	int search_data,flag=0;
	struct node *pnew;
	pnew=phead;
	printf("请输入要查找的数据:\n");
	scanf("%d",&search_data);
	while(pnew!=NULL&&pnew->next!=NULL)
	{
		if(pnew->data==search_data)
		{
			printf("Right\n");
			flag=1;
			break;
		}
		pnew=pnew->next;
	}
	if(flag==0)
		printf("Wrong\n");
}

单链表的修改

void modify(struct node *phead)
{
	int modify_data1,modify_data2,flag=0;
	struct node *pnew;
 	pnew=phead;
 	printf("请输入要修改的原数据:\n");
 	scanf("%d",&modify_data1);
 	while(pnew!=NULL&&pnew->next!=NULL)
 	{
 		if(pnew->data==modify_data1)
 		{
 			printf("请输入修改后的新数据:\n");
 			scanf("%d",&modify_data2);
 			pnew->data=modify_data2;
 		}
 		pnew=pnew->next;
 	}
}

可以说单链表的修改与查找是很像的,修改是在查找的基础上完成的
单链表的显示

void print(struct node *phead)
{
	struct node *pnew;
	pnew=phead;
	while(pnew!=NULL&&pnew->next!=NULL)
	{
		printf("%d ",pnew->data);
		pnew=pnew->next;
	}
}

单链表的排序(交换数据域)

struct node* sort(struct node *phead)
{
	struct node *pnew,*pend;
	for(pnew=phead;pnew!=NULL;pnew=pnew->next)
	{
		for(pend=pnew->next;pend!=NULL;pend=pend->next)
			if(pend->data<pnew->data)
			{
				int temp;
				temp=pend->data;
				pend->data=pnew->data;
				pnew->data=temp;
			}
	}
	return phead;
}

主函数

#include <stdio.h>
int main()
{
	struct node *phead;
	phead=(struct node*)malloc(struct node);
	int index;
	scanf("%d",&index);
	phead=create();
	phead=insert(phead);
	phead=del(phead,index);
	modify(phead);
	search(phead);
	sort(phead);
	print(phead);
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值