C 语言--链表(初学者专享)

本文章针对方向有:链表创建、遍历、找数字、删除节点、添加节点、反向输出案例、释放链表;

  由于第一次发表不太知道具体写什么,因为在本人查找链表时,发现查出来的案例大多数很高级,不是很"亲民",站在同样刚学完c语言的角度,写了几个很基础的链表样例分享一下,希望可以对同为初学者的你有些帮助!

(因为属于个人打的代码,很对方法可能有些个人特色,不是特别传统,但是还是希望可以在思维上有些帮助)

因为本人能力有限,如果有出错,或者可以改进的地方,非常非常非常,愿意接受整改(可以进步了,哈哈)

下面是完整代码:

#include<stdio.h>
#include<stdlib.h>
typedef struct _node{
	//本节点储存的数字 
	int val;
	//指向下一个节点 
	_node* next;
}node;
node *add(node *head,int number);
void bianli(node *head);
void find(node *head,int number);
void del(node *head,int number);
node *_more(node *head,int number,int more);
void back(node *head);
int main()
{
	node *head=NULL;
	int number;
	//输入 
	printf("请输入数字(-1截至):\n");
	do{
		scanf("%d",&number);
		if(number!=-1){
			//如果用void,在函数里改变的head,不能改变原head指针
			//所以要返回指针 
			head=add(head,number);
		}
	}while(number!=-1);
	//遍历 
	bianli(head);
	//找数字
	printf("找数字:\n");
	scanf("%d",&number);
	find(head,number);
	//删除节点 
	 printf("要删除的数字:\n");
	 scanf("%d",&number);
	 del(head,number);
	 //添加节点 
	 printf("在哪个数字后面添加:\n");
	 scanf("%d",&number);
	 int more;
	 printf("添加的数字:\n");
	 scanf("%d",&more);
	 head=_more(head,number,more);
	 bianli(head);
	 //反向输出
	 printf("反向输出:\n");
	 back(head) ;
	 //释放链表 
	 node *p,*q=NULL; 
	 for(p=head;p;p=q){
	 	//q指向下一节点,释放p,然后下一轮p指向q,也就是到了下一位置 
		q=p->next;
		free(p);
	} 
	 return 0;
}
node *add(node *head,int number)
{
	//为新节点申请空间 
	node *p;
	p=(node*)malloc(sizeof(node));
	//初始化新节点 
	p->val=number;
	p->next=NULL;
	//找到最后一位节点 
	node *last=head;
	//last不是是空,也就last不是空的head 
	if(last){
		while(last->next){
			last=last->next;
		}
		//找到最后一位,把p接在后面 
		last->next=p;
	}
	//如果last是空head,也就是第一次添加节点,那就把p放在head上就好 
	else{
		head=p;
	}
	return head;
}
void bianli(node *head)
{
	node *p;
	for(p=head;p;p=p->next){
		printf("%d\t",p->val);
	}
	printf("\n");
}
void find(node *head,int number)
{
	node *p;
	int flag=1;
	for(p=head;p;p=p->next){
		if(p->val==number){
			printf("找到了!\n");
			flag=0;
			break;
		}
	}
	if(flag) printf("没找到!\n");
}
void del(node *head,int number)
{
	node *p,*q;
	//q为q的上一个节点,在把p删除时,要把q的节点接触到p的下一个(跳过p) 
	 for(q=NULL,p=head;p;q=p,p=p->next)
	 {
	 	if(p->val==number){
	 		//确保q存在,如果q是NULL,也就是删除的是第一个,则p就没有前一个指针 
	 		//只要出现在赋值里面的指针要保证存在,在for里已经保证p存在,需要再保证q存在 
	 		if(q){
	 			q->next=p->next;
	 			free(p);
			 }
			 //如果删除第一个节点,就把head接到下一个 
			 else{
			 	head=p->next;
			 	//别忘记释放这个节点 
			 	free(p);
			 }
			 break;
		 }
	 }
	 bianli(head);
}
node *_more(node *head,int number,int more)
{
	node *p;
	for(p=head;p;p=p->next)
	{
		if(p->val==number)
		{
		//申请新节点 ,并初始化 
		node *q=(node*)malloc(sizeof(node));
		q->val=more;
		//原:1->2 
		//让q的下一个接到q的下一个 ,(1->2,3->2)
		q->next=p->next;
		//让p的下一个回接到q(1->3,3->2) 
		p->next=q;
		//现在:1->3->2 
		}
	}
	return head;
} 
void back(node *head)
{
	node *p=head,*q;
	while(p->next) p=p->next;
	//把p反在最后一个节点并输出 
	printf("%d\t",p->val);
	int flag=1;
	while(flag){
		//把q放在p的前一个节点 ,为了p下一次可以前移 
		for(q=head;q;q=q->next){
			if(q->next==p) break;
		}
		//把p重新排列,到与q在同一节点停止,相当于前移了一位 
		for(p=head;p;p=p->next){
			if(p==q) break;
		}
		printf("%d\t",p->val);
		//如果p到了头节点,跳出循环 
		if(p==head) flag=0;
	}
	printf("\n");
}

谢谢观看!

                                                            -----来自DUT

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悲伤玉米芹菜粥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值