诙谐友好版——1.2.有(无)头结点的单链表,实现增删改查,头尾中间插,3.完整版包含主函数及运行范例

本文详细介绍了链表数据结构的操作,包括有头结点的单链表初始化、头插法、输出、特定位置插入、输出、删除和查找。通过诙谐的代码解释了中间插入、头插法、尾插法、删除和查找的实现,同时提供了完整的代码示例,涵盖了头插、尾插、中间插入、删除和查找等操作。此外,还展示了无头结点的链表操作,如头插、尾插、插入和删除的方法。

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


1.主函数以及头插输入,特定位置插入信息,输出

1.定义结点

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct node
{
	char name[20];
	int num;
	struct node* next;
}Node,*Link; 

2.有头结点的单链表,初始化,创造旗帜(因为指针域为空,暂时不是人)

Link Init()
{
	Link head;
	head=(Node*)malloc(sizeof(Node));
	head->next=NULL;
	return head;
 } 

3。头插法

void Creatbe(Link head)
{
	Link r;
	char name[20];
	int num;
	printf("请输入头插实现学生的姓名及学号:\n");
	while(1)
	{
		scanf("%s",name);
		scanf("%d",&num);
		if(num==0)
			break;
		r=(Node*)malloc(sizeof(Node));
		strcpy(r->name,name);
		r->num=num;
		
		r->next=head->next;     //有头结点
		head->next=r;
	 } 
	 //return head;
} 

4.输出

void Output(Link head)
{
	Node* s;
	//s=(Node*)malloc(sizeof(Node));
	s=head->next;
	printf("学生信息如下:\n");
	while(s)
	{
		printf("姓名:%s\t",s->name);
		printf("学号:%d\n\n",s->num);
		s=s->next;
	}
}

5。特定位置有中间,头,尾

void Creatte(Link head,int i)
{
	Node* p=head,*s; //p找到第一个人的位置,有找到后面人的条件 
	int m=0;
	while(m<i-1&&p)//遍历找到要插入的结点位置,并且要防止溢出 
	{
		p=p->next;
		m++;
	}
	if(p)
	{
		printf("请输入在第%d位置要插入的学生姓名和学号:\n",i);
		s=(Node*)malloc(sizeof(Node));
		scanf("%s",s->name);
		scanf("%d",&s->num);
		s->next=p->next;
		p->next=s;
	}
}

//删除,查询调参都一样

主函数

int main()
{
	Node* be,*te;
	
	be=Init();
	Creatbe(be);
	Output(be);
	//头插输入 
	
	int j;
	printf("你想在第几个位置插入:");
	scanf("%d",&j);
	j=2;//想在第几个位置插入 
	
	te=Init(be);
	Creatte(be,j);
	Output(be);
	//特定位置插入
	
	int pos;
	scanf("%d",&pos);
	Delete(be,pos);
	//删
	
	Node* p;
	char posname[20];
	scanf("%s",posname); 
	p=Search(be,posname);
	//查 
	
	int Lenth;
	Length=ListLength(be);
	//长度 
	return 0;
}

2.插入(头插,特定位置插,尾插),删除查找(采用找朋友插队诙谐的代码解释,但请不要随意插队哦)

1.中间插

找朋友在特定地方插队

void Creatte(Link head,int i)
{
	int j=0;
	Node* p=head,*s;//p是朋友在的队伍,s是你 
	if(j<i-1&&p)
	{
		p=p->next;
		j++;//一个接一个人找 
	}
	printf("请输入在第%d位置上插入的学生姓名以及学号:\n",i);
	while(p)//朋友在队伍内 
	{
		s=(Node*)malloc(sizeof(Node));//准备给你腾地 
		scanf("%s",s->name);
		scanf("%d",&s->num);
		s->next=p->next;//礼貌的告诉朋友后面的人 
		p->next=s;//这个位置是你的了 
	}
 } 

2.头插

找朋友在第一个插队

void Creattou(Link head)
 {
 	Node* p;
 	printf("请输入要插入的学生姓名和学号:\n");
 	scanf("%s",p->name);
 	scanf("%d",&p->num);
 	p->next=head->next;//除了不再申请空间,和头插法方法一致 
 	head->next=p;
 }

3.尾插,

很不幸,朋友在最后面,你 找到队就行了,排最后吧,可别忘了给最后扩容啊

void Creathou(Link head)
{
	Node *p=head,*s;
	printf("请输入排队同学的姓名和学号:\n");
	s=(Node*)malloc(sizeof(Node)); 
	scanf("%s",s->name);
	scanf("%d",&s->num);
	p->next=s;
	s->next=NULL;//只要给自己扩容就行了,别忘了收尾,你后边没人了哈 
} 

插入集合

Link Insert(Link head, int a) {
	int j = 0;
	Node *p, *q;
	q = (Node *)malloc(sizeof(Node));
	printf("你想插入哪个数:\n");
	scanf("%d",&q->data);
	if(head == NULL) {
		printf("ERROR\n");
		return ;
	}
	if(a == 1) {
		q->next = head->next;//插头 
		head->next = q;
	} else {
		p = head;
		while(j < a-1 && p) {//非头 
			j++;
			p = p->next;
		} 
		if(p) {
			q->next = p->next;
			p->next = q;    
		} 	
	}
	return head;
}

4.删除

(完了,被发现了,队伍不要你了)


void delete(Link head,int  pos)
{
   Node *p=head,*s;
   int j=0;
   if(j<pos-1&&p)
   {
   	p=p->next;
   	j++;
   }
   if(p==NULL||p->next==NULL)
   	printf("这位置不对啊\n");
   else 
   {
   	q=p->next;
   	p->next=q->next;//找到你,直接让你朋友连你后边人(不拿我当回事) 
   	free(q);//你免费了>_< 
   }
} 

5.查找

在你们班找你

Node *Search(Link head,char name[20])
{
	Node *p=head->next;//从第一个人按顺序找下去 
	while(p)
	{
		if(strcmp(p->name,name)!=0)//苦苦的按名找啊 
		{
			p=p->next;
		}
	}
	if(p=NULL)
	{
		printf("这个班没有!\n");
	}
	return p;
} 

7.统计节点

//统计你们班有多少人

int ListLength(List head)
{
	int count=0;
	Node *p=head->next;
	while(p)
	{
		count++;
		p=p->next;
	}
	return count; 
}

//只在尾插时 扩充 空间
//只有查人和计数 才 ①p=head->next(在中间或者尾插也是这样); ②有返回值

3.完整代码及易错点标注

#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
	int data;
	struct node* next;
}Node,*Link;

Link Init()
{
	Node *head;
	head=(Node*)malloc(sizeof(Node));
	head->next=NULL;
	return head;
}

void Creatha(Link head)
{
	Node *r;
	int data;
	printf("请输入进行头插的数据:\n");
	while(1)
	{
		scanf("%d",&data);
		if(data==0)
			break;
		r=(Node*)malloc(sizeof(Node));
		r->data=data;
		
		r->next=head->next;
		head->next=r;
	}
}
void Creathb(Link head)
{
	Node *p,*s;
	p=head; //尾插1输入从头结点开始 
	int data;
	printf("请输入进行尾插的数据:\n");
	while(1)
	{
		scanf("%d",&data);
		if(data==0)
			break;
		s=(Node*)malloc(sizeof(Node));
		s->data=data;
		
		p->next=s;
		p=s;
	 } 
	 p->next=NULL;					//必须尾要指向空 
}
void Output(Link head)
{
	Node* p;
	p=head->next;					//从有意义的首节点开始输出 
	printf("以下是输出数据:\n");
	while(p)
	{
		printf("%d\t",p->data);
		p=p->next;
	}
	printf("\n");
}
void Insertmid(Link head,int i)
{
	Node *p=head,*s;//插中间从头结点开始遍历 
	int pos=0;
	while(pos<i-1&&p)
	{
		p=p->next;
		pos++;
	}
	if(p==NULL)
	{
		printf("ERROR\n");
	}
	else
	{
		s=(Node*)malloc(sizeof(Node));
		printf("请输入你在%d处要插入的数字:\n",i);
		scanf("%d",&s->data);
		
		s->next=p->next;
		p->next=s;
	} 
}
void Inserttou(Link head)
{
	Node *p;				//插头不用遍历,直接插 
	p=(Node*)malloc(sizeof(Node));					/插头必须申请空间 
	printf("请输入在首节点要插入的数据:\n");
	scanf("%d",&p->data);
	p->next=head->next;
	head->next=p;
}

~尾插

void Insertwei(Link head)
{
	Node *p,*s;
	p=head;				//尾插从头结点开始遍历 
	while(p&&p->next)					//进去循环机制用while,if是条件语句 
	{
		p=p->next;
	}									/是while(p)	j++;p=p->next;平替 
	if(p)
	{
		printf("请输入尾插的数:\n");
		s=(Node*)malloc(sizeof(Node));
		scanf("%d",&s->data);
		p->next=s;
		p=s;
	 } 
	p->next=NULL;
}
void Delete(Link head,int i)
{
	int pos=0;
	Node *p=head,*q;						//删除从头结点开始遍历 
	while(pos<i-1 && p)
	{
		p=p->next;
		pos++;
	}
	if(p==NULL||p->next==NULL)
	{
		printf("没有这个数,删不了!\n");
	}
	else 
	{
		q=p->next;
		p->next=q->next;
		free(q); 
	}
}
int Search(Link head,int j)
{
	int pos=0; 
	Node *p;
	p=head->next;//查找也从有意义的首结点开始 
	while(pos<j-1&&p)
	{
		p=p->next;
		pos++;
	}
	if(p==NULL||p->next==NULL)
	{
		printf("没找到!\n");
	}
	return p->data;
}
int Cnt(Link head)
{
	Node *p=head->next;//计数时也是从有意义的首节点开始遍历 
	int i=0;
	while(p)
	{
		i++;
		p=p->next;
	} 
	return i;
}
int main()
{
	Node *ha,*hb;
	
	ha=Init();
	Creatha(ha);
	Output(ha);
	
	hb=Init();
	Creathb(hb);
	Output(hb);
	
	Inserttou(hb);
	Output(hb);
	
	int i=2;
	Insertmid(hb,i);
	Output(hb);
	
	Insertwei(hb);
	Output(hb);
	
	int n=2;
	printf("想要删除第%d位数:\n",n);
	Delete(hb,i);						//函数类型为空主函数不用写类型 
	Output(hb);

	int j=1,m;
	printf("想要调查第%d位数:\n",j);
	m=Search(hb,j);
	printf("调查第%d位数值为%d",j,m);
	
	int count=0;
	count=Cnt(hb);
	printf("该链表的长度为%d\n",count);
	
	return 0;
}

4.范例

​​​​​​
在这里插入图片描述

无头结点

结点定义一样

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node {
	int data;
	struct node* next;
}Node, *Link;
//定义结点

尾插

Link Creatwei() {
	Link head = NULL;// 初 始 化 头 结 点 
	Node *p, *q;   //p是旧结点,q是新节点 
	int data;
	printf("由尾插创建的链表:\n");
	while(1) {
		scanf("%d",&data);
		if(data == 0) {
			break;
		}
		q = (Node *)malloc(sizeof(Node));
		q->data = data;
		q->next = NULL;   //新节点指针域设为空 
	
		if(head == NULL) { //情况:头结点为空 
			head = q;  //头指针指向第一个节点 
			p = head;     //p指向第一个节点 
		}   else {
			p->next = q; 
			p = q;        //和有头节点的尾插法一样 
		} 
	}
	return head;   
}
//尾插 

头插

Link Creattou() {
	Link head = NULL;  //首节点置空
	Node *p;
	int data;
	printf("由头插法输入链表数据:\n");
	while(1) {
		scanf("%d",&data);
		if(data == 0) {
			break;
		}
		p = (Node *)malloc(sizeof(Node));
		p->data = data;
		
		p->next = head;    //作为首节点,没有头结点,所以不需要指向head->next;
		head = p;       //
	}
	return head;
} 

输出

void Output(Link head) {
	Node *p;
	p = head;      //直接p指向头指针,不用指向头结点head->next 
	printf("输出链表:\n");
	while(p) {
		printf("%d ",p->data);
		p = p->next;
	}
	printf("\n");
}

插入(头,尾,中)

Link Insert(Link head,int a) {
	Node *p, *q;
	int j = 1;
	q = (Node *)malloc(sizeof(Node));
	printf("输入要插的数:\n");
	scanf("%d",&q->data);
	
	if(a == 1) { //插到首位 
		q->next = head;   //q走到首结点,作为首结点,没有头结点不需要head->next 
		head = q;
	} else {    //不在首位
		p = head;
		while(j < a-1 && p) {
		j++;
		p = p->next;
	}
		if(p) {
			q->next = p->next;
			p->next = q; 
		} else if(p == NULL) {
			printf("ERROR\n");
		}
	}
	return head;
}

删除(首结点,非首)

Link Delete(Link head, int a) {
	int j = 1;
	Node *p = head, *q;
	if(head == NULL) {
		printf("头结点为空。\n");
		return ;
	}
	if(a == 1) {
		q = head;
		head = head->next;
		free(q);
	} else {
		while(j < a-1 && p) {
			j++;
			p = p->next;
		} 
		if(p) {
			q = p->next;
			p->next = q->next;
			free(q);
		}
	}
	return head;
}

主函数

int main() {
	Node *wei = NULL, *tou = NULL; //没有头结点需要对第一个节点进行操作
	wei = Creatwei(wei);
	Output(wei);
	
//	tou = Creattou(tou);
//	Output(tou);

	int a;
	printf("你想在第几个位置插入:\n");
	scanf("%d",&a);
	wei = Insert(wei,a);
	Output(wei);
	
	int b;
	printf("你要删除哪个节点:\n");
	scanf("%d",&b);
	wei = Delete(wei,b);
	Output(wei);
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值