[C语言]单向链表的总结

又优化了一下

12.22回顾

又回顾了一下,优化了一下代码,基础思路没有变,废话不多说,直接上代码

  1. 创建一个结构体(存一个数字和一个结构体指针)
typedef struct _Link{
	int data;
	struct _Link *next;
}Link;
  1. 创建链表

尾插法:

Link* Link_list_tail()//尾插法 
{
	int number;
	printf("输入多个数字添加到链表中,输入q结束\n");
	Link *head=(Link*)malloc(sizeof(Link));
	head->next=NULL;
	Link *tail=head;
	while(scanf("%d",&number)==1)
	{
		Link *p=(Link*)malloc(sizeof(Link));
		p->data=number;
		p->next=NULL;
		tail->next=p;
		tail=p;	
	}
	getchar();
	printf("OK\n"); 
	return head;
}

头插法:

Link* Link_list_head()//头插法 
{
	int number;
	printf("输入多个数字添加到链表中,输入q结束\n");
	Link *head=(Link*)malloc(sizeof(Link));
	head->next=NULL;
	while(scanf("%d",&number)==1)
	{
		Link *p=(Link*)malloc(sizeof(Link));
		p->data=number;
		p->next=head->next;
		head->next=p;
	}
	getchar();
	printf("OK\n");
	return head;
}

不过头插法输入的数据最后读的时候是反着的

  1. 查找某一个值k
Link* Find(int k,Link *head)//寻找特殊值 
{
	Link *p=head->next;
	Link *q=head;
	while(p)
	{
		if(p->data==k)
		{
			printf("Find\n");
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p)
	{
		printf("Not Find\n");
	}
	return p;//返回指向关键值的指针 
}
  1. 增加某个数number到第targer个节点
Link* Add(int targer,int number,Link *head)//向某节点插入某个数字 
{
	int i;
	Link *p=head;
	for(i=0;i<targer-1&&p;i++)
	{
		p=p->next;
	}
	if(p)
	{
		Link *add=(Link*)malloc(sizeof(Link));
		add->data=number;
		add->next=p->next;
		p->next=add;
		printf("OK\n");
	}
	else
	{
		printf("NO\n");
	}
	return p;
}
  1. 删除某个值k
Link* Del(int k,Link *head)//删除某个值 
{
	Link *p=head->next;
	Link *q=head;
	while(p)
	{
		if(p->data==k)
		{
			printf("Find\n");
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p)
	{
		printf("No Find\n");
	}
	else
	{
		q->next=p->next;
		free(p);
		p=NULL;
		printf("OK\n");
	}
	return p;
}
  1. 链表逆置:

原地逆置:

Link* ReverseLink(Link *head)//原地逆置 
{
	Link *p=head->next;
	Link *q=head;
	head->next=NULL;
	while(p)
	{
		q=p;
		p=p->next;
		q->next=head->next;
		head->next=q;
	}
	printf("OK\n");
	return p;
}

递归逆置:

Link* ReverseLink_D(Link *head)//递归逆置 
{
	if(head->next||head)
	{
		return head;
	}
	Link *p=ReverseLink_D(head->next);
	Link *t=head->next;
	t->next=head;
	head->next=NULL;
	return p;
}
  1. 显示链表:
Link* Print(Link *head)//显示链表 
{
	Link *p=head->next;
	if(!p)
	{
		printf("NO");
	}
	while(p)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	putchar('\n');
	return p;
}
  1. 删除所有链表:
Link* Del_all(Link *head)//删除所有链表 
{
	Link *q=head->next;
	Link *p=q->next;
	head->next=NULL;
	while(p)
	{
		free(q);
		q=p;
		p=p->next;
	}
	q=NULL;
	p=NULL;
	printf("OK\n");
	return NULL;
}

下面是全部代码示意图:

#include <stdio.h>
#include <stdlib.h>
typedef struct _Link{
	int data;
	struct _Link *next;
}Link;
Link* Link_list_tail()//尾插法 
{
	int number;
	printf("输入多个数字添加到链表中,输入q结束\n");
	Link *head=(Link*)malloc(sizeof(Link));
	head->next=NULL;
	Link *tail=head;
	while(scanf("%d",&number)==1)
	{
		Link *p=(Link*)malloc(sizeof(Link));
		p->data=number;
		p->next=NULL;
		tail->next=p;
		tail=p;	
	}
	getchar();
	printf("OK\n"); 
	return head;
}
Link* Link_list_head()//头插法 
{
	int number;
	printf("输入多个数字添加到链表中,输入q结束\n");
	Link *head=(Link*)malloc(sizeof(Link));
	head->next=NULL;
	while(scanf("%d",&number)==1)
	{
		Link *p=(Link*)malloc(sizeof(Link));
		p->data=number;
		p->next=head->next;
		head->next=p;
	}
	getchar();
	printf("OK\n");
	return head;
}
Link* Find(int k,Link *head)//寻找特殊值 
{
	Link *p=head->next;
	Link *q=head;
	while(p)
	{
		if(p->data==k)
		{
			printf("Find\n");
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p)
	{
		printf("Not Find\n");
	}
	return p;//返回指向关键值的指针 
}
Link* Add(int targer,int number,Link *head)//向某节点插入某个数字 
{
	int i;
	Link *p=head;
	for(i=0;i<targer-1&&p;i++)
	{
		p=p->next;
	}
	if(p)
	{
		Link *add=(Link*)malloc(sizeof(Link));
		add->data=number;
		add->next=p->next;
		p->next=add;
		printf("OK\n");
	}
	else
	{
		printf("NO\n");
	}
	return p;
}
Link* Del(int k,Link *head)//删除某个值 
{
	Link *p=head->next;
	Link *q=head;
	while(p)
	{
		if(p->data==k)
		{
			printf("Find\n");
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p)
	{
		printf("No Find\n");
	}
	else
	{
		q->next=p->next;
		free(p);
		p=NULL;
		printf("OK\n");
	}
	return p;
}
Link* Del_all(Link *head)//删除所有链表 
{
	Link *q=head->next;
	Link *p=q->next;
	head->next=NULL;
	while(p)
	{
		free(q);
		q=p;
		p=p->next;
	}
	q=NULL;
	p=NULL;
	printf("OK\n");
	return NULL;
}
Link* ReverseLink(Link *head)//原地逆置 
{
	Link *p=head->next;
	Link *q=head;
	head->next=NULL;
	while(p)
	{
		q=p;
		p=p->next;
		q->next=head->next;
		head->next=q;
	}
	printf("OK\n");
	return p;
}
Link* ReverseLink_D(Link *head)//递归逆置 
{
	if(head->next||head)
	{
		return head;
	}
	Link *p=ReverseLink_D(head->next);
	Link *t=head->next;
	t->next=head;
	head->next=NULL;
	return p;
}
Link* Print(Link *head)//显示链表 
{
	Link *p=head->next;
	if(!p)
	{
		printf("NO");
	}
	while(p)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	putchar('\n');
	return p;
}
int main()
{
	Link *head=(Link*)malloc(sizeof(Link));
	head->next=NULL;
	while(1){
		printf("输入1创建链表\n");
		printf("输入2查找某值\n");
		printf("输入3插入某数到某个节点\n");
		printf("输入4删除某值\n");
		printf("输入5逆置链表\n");
		printf("输入6显示链表\n");
		printf("输入7删除整个链表\n");
		printf("输入0结束程序\n");
		int n;
		scanf("%d",&n);
		if(n==0)
		{
			break;
		}
		switch (n){
			case 1:
				head=Link_list_tail();
				break;
			case 2:
				printf("输入需要查找的值\n");
				int k;
				scanf("%d",&k);
				Find(k,head);
				break;
			case 3:
				printf("输入要插入的节点序号和要插入的值\n");
				int targer,number;
				scanf("%d%d",&targer,&number);
				Add(targer,number,head);
				break;
			case 4:
				printf("输入一个数来删除它\n");
				int key;
				scanf("%d",&key);
				Del(key,head);
				break;
			case 5:
				printf("逆置链表\n");
				ReverseLink(head);
				break;
			case 6:
				printf("显示链表\n");
				Print(head);
				break;
			case 7:
				printf("删除整个链表\n");
				Del_all(head);
				break;
			defult:
				break;
		} 
	}
	printf("Goodbye!");
	getchar();
	getchar(); 
	return 0;
}

12.20旧版

  1. 创建一个结构体(存一个数字和一个结构体指针)
typedef struct _list{
	int date;
	struct _list *next;
}List;
  1. 创建链表

尾插法:

List* link_list_tail()//尾插法 
{
	int number;
	printf("输入多个数字添加到链表中,输入q结束\n");
	List *head=(List*)malloc(sizeof(List));
	head->next=NULL;
	List *tail=head;
	while(scanf("%d",&number)==1)
	{
		List *p=(List*)malloc(sizeof(List));
		p->date=number;
		p->next=NULL;
		tail->next=p;
		tail=p;
	}
	getchar();
	return head;
}

头插法:

List* link_list_head()//头插法反着的 
{
	int number;
	printf("输入多个数字添加到链表中,输入q结束\n");
	List *head=(List*)malloc(sizeof(List));
	head->next=NULL;
	while(scanf("%d",&number)==1)
	{
		List *p=(List*)malloc(sizeof(List));
		p->date=number;
		p->next=head->next;
		head->next=p;
	}
	getchar();
	return head;
}

不过头插法输入的数据最后读的时候是反着的

  1. 查找某一个值k
List* find(int k,List*head)//查找某值 
{
	List *p=head->next;
	List *q=head;
	while(p)
	{
		if(p->date==k)
		{
			printf("Find\n");
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p)
	{
		printf("No\n");
	}
	return q;//返回前一个的指针 
}
  1. 增加某个数number到第targer个节点
List* add(int targer,int number,List*head)//增加某个数到某个节点 
{
	int i;
	List *p=head;
	for(i=0;i<targer-1&&p;i++)
	{
		p=p->next;//找到它的前一个指针 
	}
	if(p)
	{
		List *tar=(List*)malloc(sizeof(List));
		tar->date=number;
		tar->next=p->next;
		p->next=tar;
		printf("OK\n"); 
	}else
	{
		printf("No\n");
	}
	return p;
}
  1. 删除某个值k
List* del(List *head,int k)//删除某个值 
{
	List*p=head->next;
	List*q=head;
	while(p)
	{
		if(p->date==k){
			printf("Find\n");
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p){
		printf("No\n");
	}else{
		p=p->next;
		free(q->next);
		q->next=p;
		printf("OK\n");
	}
}
  1. 链表逆置:

原地逆置:

List* ReverseLink(List *head)//原地逆置 
{
	List* p=head->next;
	List* q=p;
	head->next=NULL;
	while(p)
	{
		q=p;
		p=p->next;
		q->next=head->next;
		head->next=q;
	}
}

递归逆置:

List* ReverseLink_D(List *head)//递归逆置 
{
	if(head->next==NULL||head==NULL){
		return head;
	}//递归结束条件
	List *p=ReverseLink_D(head->next);
	List *t=head->next;
	t->next=head;
	head->next==NULL;
	return p;
}
  1. 显示链表:
List* print(List*head)//显示链表 
{
	List*p=NULL;
	if(head->next){
		p=head->next;
	}else{
		printf("NO\n");
		return NULL;
	}
	while(p)
	{
		printf("%d ",p->date);
		p=p->next;
	}
	putchar('\n'); 
	return head;
}
  1. 删除所有链表:
List* del_all(List*head)//删除所有链表 
{
	List*p=head->next->next;
	List*q=head->next;
	head->next=NULL;
	for(;p;q=p,p=p->next)
	{
		free(q);
		
	}
	printf("OK\n");
}
  1. 最后综合一下(可以把上述内容放到一个文件里面调用更方便)
#include<stdio.h>
#include<stdlib.h>
typedef struct _list{
	int date;
	struct _list *next;
}List;
List* link_list_tail()//尾插法 
{
	int number;
	printf("输入多个数字添加到链表中,输入q结束\n");
	List *head=(List*)malloc(sizeof(List));
	head->next=NULL;
	List *tail=head;
	while(scanf("%d",&number)==1)
	{
		List *p=(List*)malloc(sizeof(List));
		p->date=number;
		p->next=NULL;
		tail->next=p;
		tail=p;
	}
	getchar();
	return head;
}
List* link_list_head()//头插法反着的 
{
	int number;
	printf("输入多个数字添加到链表中,输入q结束\n");
	List *head=(List*)malloc(sizeof(List));
	head->next=NULL;
	while(scanf("%d",&number)==1)
	{
		List *p=(List*)malloc(sizeof(List));
		p->date=number;
		p->next=head->next;
		head->next=p;
	}
	getchar();
	return head;
}

List* find(int k,List*head)//查找某值 
{
	List *p=head->next;
	List *q=head;
	while(p)
	{
		if(p->date==k)
		{
			printf("Find\n");
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p)
	{
		printf("No\n");
	}
	return q;//返回前一个的指针 
}

List* add(int targer,int number,List*head)//增加某个数到某个节点 
{
	int i;
	List *p=head;
	for(i=0;i<targer-1&&p;i++)
	{
		p=p->next;//找到它的前一个指针 
	}
	if(p)
	{
		List *tar=(List*)malloc(sizeof(List));
		tar->date=number;
		tar->next=p->next;
		p->next=tar;
		printf("OK\n"); 
	}else
	{
		printf("No\n");
	}
	return p;
}
List* del(List *head,int k)//删除某个值 
{
	List*p=head->next;
	List*q=head;
	while(p)
	{
		if(p->date==k){
			printf("Find\n");
			break;
		}
		q=p;
		p=p->next;
	}
	if(!p){
		printf("No\n");
	}else{
		p=p->next;
		free(q->next);
		q->next=p;
		printf("OK\n");
	}
}
List* del_all(List*head)//删除所有链表 
{
	List*p=head->next->next;
	List*q=head->next;
	head->next=NULL;
	for(;p;q=p,p=p->next)
	{
		free(q);
		
	}
	printf("OK\n");
}
List* ReverseLink(List *head)//原地逆置 
{
	List* p=head->next;
	List* q=p;
	head->next=NULL;
	while(p)
	{
		q=p;
		p=p->next;
		q->next=head->next;
		head->next=q;
	}
}
List* ReverseLink_D(List *head)//递归逆置 
{
	if(head->next==NULL||head==NULL){
		return head;
	}//递归结束条件
	List *p=ReverseLink_D(head->next);
	List *t=head->next;
	t->next=head;
	head->next==NULL;
	return p;
}
List* print(List*head)//显示链表 
{
	List*p=NULL;
	if(head->next){
		p=head->next;
	}else{
		printf("NO\n");
		return NULL;
	}
	while(p)
	{
		printf("%d ",p->date);
		p=p->next;
	}
	putchar('\n'); 
	return head;
}
int main()
{
	List*head=NULL;
	while(1){
		printf("输入1创建链表\n");
		printf("输入2查找某值\n");
		printf("输入3插入某数到某个节点\n");
		printf("输入4删除某值\n");
		printf("输入5逆置链表\n");
		printf("输入6显示链表\n");
		printf("输入7删除整个链表\n");
		printf("输入0结束程序\n");
		int n;
		scanf("%d",&n);
		if(n==0)
		{
			break;
		}
		switch (n){
			case 1:
				head=link_list_tail();
				break;
			case 2:
				printf("输入需要查找的值\n");
				int k;
				scanf("%d",&k);
				List*p=find(k,head);
				break;
			case 3:
				printf("输入要插入的节点序号和要插入的值\n");
				int targer,number;
				scanf("%d%d",&targer,&number);
				add(targer,number,head);
				break;
			case 4:
				printf("输入一个数来删除它\n");
				int key;
				scanf("%d",&key);
				del(head,key);
				break;
			case 5:
				printf("逆置链表\n");
				ReverseLink(head);
				break;
			case 6:
				printf("显示链表\n");
				print(head);
				break;
			case 7:
				printf("删除整个链表\n");
				del_all(head);
				break;
			defult:
				break;
		} 
	} 
	return 0;
}
  1. 运行结果:

1
创建一个链表:
在这里插入图片描述
查找链表中是否存在某个值:
在这里插入图片描述
插入某数到某个节点:
在这里插入图片描述
删除链表中的一个值:
在这里插入图片描述
逆置链表:
在这里插入图片描述
删除整个链表:
在这里插入图片描述
结束程序:
在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值