C语言基础-链表

1、为什么要使用链表

对于数据的处理,增删改查会减少工作量

2、链表与数组的区别与实现

 (:set nu):显示行号

 

 代码实现:

#include <stdio.h>

//结构体初始化
//第一个元素为整型
//第二个为名叫next的指针,指向结构体本身
struct Test
{
	int data;
	struct Test *next;
};

int main()
{	
	//实例化3个结构体
	struct Test t1 = {1,NULL};
	struct Test t2 = {2,NULL};
	struct Test t3 = {3,NULL};
	
	//t1的指针指向结构体t2
	t1.next = &t2;
	//t2的指针指向结构体t3
	t2.next = &t3;
	
	printf("%d %d %d\n",t1.data,t1.next->data,t1.next->next->data);

} 

3、链表静态添加与动态遍历

//遍历链表的方法
void printLink(struct Test *head)
{
	//定义一个结构体型指针
	struct Test *point;
	//指向head
	point = head;
	//当point不为空时,说明还没到最后一个
	//打印当前数据
	//打印完成后,point再指向下一个结构体
	while(point != NULL)
	{
		printf("%d",point->data);
		point = point->next;
	}
}

完整代码:

#include <stdio.h>

//结构体初始化
//第一个元素为整型
//第二个为名叫next的指针,指向结构体本身
struct Test
{
	int data;
	struct Test *next;
};

//遍历链表的方法
void printLink(struct Test *head)
{
	//定义一个结构体型指针
	struct Test *point;
	//指向head
	point = head;
	//当point不为空时,说明还没到最后一个
	//打印当前数据
	//打印完成后,point再指向下一个结构体
	while(point != NULL)
	{
		printf("%d",point->data);
		point = point->next;
	}
}

int main()
{	
	//实例化3个结构体
	struct Test t1 = {1,NULL};
	struct Test t2 = {2,NULL};
	struct Test t3 = {3,NULL};
	
	//t1的指针指向结构体t2
	t1.next = &t2;
	//t2的指针指向结构体t3
	t2.next = &t3;
	
	printLink(&t1);
	//printf("%d %d %d\n",t1.data,t1.next->data,t1.next->next->data);

} 

4、统计链表节点个数及链表查找

//获取链表节点数
int getLinkNum(struct Test *head)
{
	int num = 0;
	while(head != NULL)
	{
		num++;
		head = head->next;
	}
	return num;
}

int main()
{	
	
	int a = getLinkNum(&t1);
	printf("%d",a);
} 
//链表查找
int searchLink(struct Test *head,int data)
{
	while(head != NULL)
	{
		if(head->data == data)
		{
			return 1;
		}
		head = head->next;
	}
	return 0;
}

5、链表从指定节点后方插入新的节点

//链表插入
void insertLink(struct Test *head,int data,struct Test *new)
{
	struct Test *p = head;
	while(p!= NULL)
	{
		if(p->data == data)
		{
			new->next = p->next;
			p->next = new;
		}
		p = p->next;
	}
}

int main()
{	
	//创建新的结构体
	struct Test new = {99,NULL};
	
	insertLink(&t1,3,&new);

	
} 

6、链表从指定节点前方插入新的节点

两种情况:

①在head前插入

②在不是head前插入

#include <stdio.h>

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

//遍历链表的方法
void printLink(struct Test *head)
{
	
	struct Test *point;
	
	point = head;
	//当point不为空时,说明还没到最后一个,打印当前数据,打印完成后,point再指向下一个结构体
	while(point != NULL)
	{
		printf("%d ",point->data);
		point = point->next;
	}
} 
//在data前方插入new
//第一种在head前面插入,但是插入方法里面的head是局部变量,main里面的head不变,所以写一个指针函数获取插入后的head
struct Test *insertFrom(struct Test *head,int data,struct Test *new)
{
	struct Test *p = head;
	
	if(p->data == data)
	{
		new->next = head;
		return new;
	}
	//第二种,在非首项前插入
	while(p->next != NULL)
	{
		if(p->next->data == data)
		{
			new->next = p->next;
			p->next = new;
			return head;
		}
		p = p->next; 
	}
}

int main()
{	
	//实例化3个结构体
	struct Test t1 = {5,NULL};
	struct Test t2 = {56,NULL};
	struct Test t3 = {3,NULL};
	
	//t1的指针指向结构体t2
	t1.next = &t2;
	//t2的指针指向结构体t3
	t2.next = &t3;
	
	struct Test *head = &t1;
	
	struct Test new = {99,NULL};
	head = insertFrom(head,56,&new);
	printLink(head);
	
} 

7、链表删除指定节点

两种情况:

①删除head,改head

②删除非head

#include <stdio.h>
#include <stdlib.h>
struct Test
{
	int data;
	struct Test *next;
};

//遍历链表的方法
void printLink(struct Test *head)
{
	
	struct Test *point;
	
	point = head;
	//当point不为空时,说明还没到最后一个,打印当前数据,打印完成后,point再指向下一个结构体
	while(point != NULL)
	{
		printf("%d ",point->data);
		point = point->next;
	}
} 

//删除
struct Test *deleatLink(struct Test *head,int data)
{
	struct Test *p = head;
	//第一种删除首项
	if(p->data == data)
	{
		head = p->next;
        free(p);
		return head;
	}
	//第二种,删除非首项
	while(p->next != NULL)
	{
		if(p->next->data == data)
		{
			p->next = p->next->next;
			return head;
		}
		p = p->next; 
	}
}

int main()
{	
	//实例化3个结构体
	struct Test t1 = {5,NULL};
	struct Test t2 = {56,NULL};
	struct Test t3 = {3,NULL};
	
	//t1的指针指向结构体t2
	t1.next = &t2;
	//t2的指针指向结构体t3
	t2.next = &t3;
	
	struct Test *head = &t1;
	
	head = deleatLink(head,3);
	printLink(head);
	
} 

8、链表动态创建之头插法

新节点作为头

#include <stdio.h>
#include <stdlib.h>
struct Test
{
	int data;
	struct Test *next;
};

//遍历链表的方法
void printLink(struct Test *head)
{
	
	struct Test *point;
	
	point = head;
	//当point不为空时,说明还没到最后一个,打印当前数据,打印完成后,point再指向下一个结构体
	while(point != NULL)
	{
		printf("%d ",point->data);
		point = point->next;
	}
} 



//动态创建头插法
struct Test *insertFromHead(struct Test *head)
{
	struct Test *new;
	new = (struct Test *)malloc(sizeof(struct Test));
	new->next=NULL;//!!!开辟内存后指针要指空,否则为野指针
	printf("请输入你的链表数据:");
	scanf("%d",&(new->data));
	
	if(head == NULL)
	{
		head = new;
		return head;
	}
	else
	{
		new->next = head;
		head = new;
		return head;
	}
	
}

int main()
{	
	//你的链表数据个数
	int i = 6;
	struct Test *head = NULL;
	while(i--)
	{
		head = insertFromHead(head);
		
	}
	printLink(head);
	return 0;
} 

9、链表动态创建之尾插法

新节点作为尾

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值