C语言链表相关知识

what?(链表是什么)

        1.链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。

        2.由一系列节点组成,节点在使用时可以动态生成。每个节点包括数据域和指针域。

        3.相比于数组创建复杂,但是使用起来更加方便(增删改查),并且事先可以不用知道节点的个数。

        4.分为有头结点和无头结点类型,区别在于有头结点的链表多出了一个节点放头指针的地址,而数据域为空,使得操作起来更加便捷。

About?(都与些函数有关)

        1.malloc()---动态分配一段内存空间

                原型为:void*malloc(unsigned int size)

                功能为:在内存的动态存储区申请一个长度为size字节的连续存储空间

        2.calloc()---动态分配连续内存空间

                原型为:void*calloc(unsigned int n,unsigned int size)(n 为元素的个数,size为元素存储长度)

                功能为:申请n个长度为size的存储空间

        3.realloc()---改变指针指向空间大小

                原型为:void*realloc(void *ptr,size_t size)

                功能为:改变指针ptr指向大小为size的空间

        4.free()---释放存储空间

                原型为:void free(void *p)

                功能为:将p指向的空间释放,交还给系统。

        以上函数使用库函数:#include<stdlib.h>,1也可以使用#include<malloc.h>.

How?(常用的操作---基于有头节点的链表)

        1.单链表的创建---有头结点

                (1)尾插---源代码

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node*next;
}node,*linklist;
node *creat()
{
	linklist L;
	node *r,*s;
	int n;
	L=r=(node *)malloc(sizeof(node));
	L->next=NULL;
	printf("请输入数据:");
	while(1)
	{
		scanf("%d",&n);
		if(n!=0)
		{
			s=(node *)malloc(sizeof(node));
			s->data=n;
			r->next=s;
			s->next=NULL;
			r=s;
		}
		else
			break;
	}
	return L;
}
void Output(linklist L)
{
	node *p;
	p=L->next;
	while(p)
	{
		printf("%d\t",p->data);
		p=p->next;
	} 
}
int main()
{
	linklist L;
	L=creat();
	Output(L);
} 

        此段代码可以实现链表的尾插,建立了两个函数,分别是创建和输出,括号中的!=0为结束条件,读者可以根据需要改变,创建时选择了尾插,原理如下:

        每次生成一个节点之后,让前一个节点只想新节点,新节点的指向为NULL,然后将新节点赋给原来的最后一个节点,这样做的目的是统一变量,方便循环的使用。

        当然也可以进行头插,不过这样做之后,输出来的数据是倒序的。代码如下:

                (2)头插---核心代码

 

node *creat()
{
	linklist L;
	node *r,*s;
	int n;
	L=r=(node *)malloc(sizeof(node));
	L->next=NULL;
	printf("请输入数据:");
	while(1)
	{
		scanf("%d",&n);
		if(n!=0)
		{
			s=(node *)malloc(sizeof(node));
			s->data=n;
			s->next=L->next;	
			L->next=s;
		}
		else
			break;
	}
	return L;
}

        2.单链表的增加

 

                (1)头插法---核心代码:

 

void Add(linklist L)
{
	node *p;
	p=(node *)malloc(sizeof(node));
	printf("请输入要添加的数:");
	scanf("%d",&p->data);
	p->next=L->next;
	L->next=p;
}

                (2)尾插法---核心代码

 

 

void Add(linklist L)
{
	node *p,*r;
	r=L->next;
	while(r->next)
	{
		r=r->next;
	}
	p=(node *)malloc(sizeof(node));
	printf("请输入要添加的数:");
	scanf("%d",&p->data);
	r->next=p;
	p->next=NULL;
}

                原理为:先遍历到最后一个节点,然后使得最后一个节点只想新插入的节点,新插入的节点指向空。
               (3)任意位置插入---核心代码

 

 

void Add(linklist L)
{
	node *p,*s;
	p=L;
	int i=1,m;
	printf("您想将数据插入到第几个");
	scanf("%d",&m); 
	while(p)
	{
		if(i==m)
			break;
		else
		{
			p=p->next;
			i++;
		}
		
	}
	s=(node *)malloc(sizeof(node));
	printf("请输入要添加的数:");
	scanf("%d",&s->data);
	s->next=p->next;
	p->next=s;
}


              原理为:设置一个计数器i,用来确定插入的位置,如果到了需要的位置,跳出循环,若没有则继续往后走,知道找到位置。

 

        3.单链表的删除---核心代码

 

void delete_linklist(linklist L)
{
	int n;
	node *p,*bp;
	bp=L;
	p=bp->next;
	printf("请输入要删除的数:");
	scanf("%d",&n);
	while(p)
	{
		if(n==p->data)
		{
			bp->next=p->next;
			break;	
		}	
		else
		{
			bp=bp->next;
			p=p->next;
		}
		
	}
	
}


              原理为:设置两个指针,一个是bp,另一个是p,其中bp位于p之前,若找到需要删除的数,则让bp指向p的下一下节点;没有找到的话就两个指针都往后移动。

 

        3.单链表的修改---核心代码

 

void revise(linklist L)
{
	int n; 
	node *p;
	p=L->next; 
	printf("请输入您所想修改的数:");
	scanf("%d",&n);
	while(p)
	{
		if(p->data==n)
			break;
		else
			p=p->next;
	}
	printf("请重新输入数据:");
	scanf("%d",&p->data); 
}

            原理为:先遍历查找到需要修改的数,查找到之后退出循环,更改数据。

 

        4.单链表的查询---源代码

为了方便体现效果,更改一下结构体中的数据类型

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node{
	char name[20];
	char number[20];
	char phone[20];
	struct node*next;
}node,*linklist;
node *creat()
{
	linklist L;
	node *r,*s;
	char a[20];
	int n;
	L=r=(node *)malloc(sizeof(node));
	L->next=NULL;
	printf("请输入学生信息:");
	while(1)
	{
		scanf("%s",a);
		if(strcmp(a,"0")!=0)
		{
			s=(node *)malloc(sizeof(node));
			strcpy(s->number,a);
			scanf("%s",s->name);
			scanf("%s",s->phone);
			r->next=s;
			s->next=NULL;	
			r=s;
		}
		else
			break;
	}
	return L;
}
void find(linklist L)
{
	char a[20];
	node *p;
	p=L->next;
	int i=0;
	printf("请输入您所想查找的学生姓名或者学号");
	scanf("%s",a);
	while(p)
	{
		if(strcmp(a,p->name)==0||strcmp(a,p->number)==0)
		{
			printf("您查找的学生信息为:\n");
			printf("%s\t%s\t%s\t",p->name,p->number,p->phone);
			i++;
		}
		p=p->next;	
	}
	if(i==0)
		printf("不好意思,没有您所想查找的学生"); 
	
}
int main()
{
	linklist L;
	L=creat();
	find(L);
} 


              原理为:遍历找到需要的信息,然后输出,设置一个计数器,如果遍历结束之后计数器仍然为0,则输出没有相关的学生信息。

 

 

              本篇博客先整理基本的操作,如有后续,则会继续整理。。。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值