C中单向链表的简单使用

#include <stdio.h>
#include <stdlib.h>
 
//结构体,为链表做准备
typedef struct A{
	int num;
	struct A *next;
} AA;
/*
 *创建链表函数
*/
AA *create(int n){
	int i;
	AA *head, *node, *end;	//定义头结点,普通节点,尾节点
 
	head = (AA *)malloc(sizeof(AA));	//给头节点分配地址
	end = head;	//一开始为空链表则头尾节点一样。
 
	for(i = 0; i < n;i++){
		node = (AA *)malloc(sizeof(AA));	//为普通节点开辟内存
		printf("NUM:\n");
		scanf("%d",&node->num);
 
		end->next = node; 
		end = node;
		//这两个顺序不能反,要调一调上一个节点让其连接新建的节点,新建节点时,head不动,node先去开辟一个新节点,
		//此时end还没动还在上一个节点,开辟好新节点了end所在的节点(即是新开节点的上一个节点)的指针是没有指向任何东西的,
		//此时就要让上一个节点指向新开的节点,而end刚好在上一个节点中,就让end->next = node即可让上一个节点指向新节点,
		//连接起来后又因为end是尾节点,要跟着node走,所以让end = node即可让end来到最后一个节点上
	}
	end->next = NULL;	//为了安全,最后一个节点赋空,至此,已完成链表创建.
	return head;	//返回头结点
}
/*
 *获取链表指定节点
*/
AA *get_linked_value(AA *head,int n){ //n为第几个节点
	//获取头指针
	AA *h = head; 
	int i = 1;
 
	//要判断n是否大于n来返回报错信息,第一个节点是头节点不能被改
	if(n < 1 || n > get_linked_len(h))
		goto ERROR;	//跳去报错区域执行报错
 
	//用循环获取到指定节点
	for(i;i <= n;i++){
		//从头节点开始,一次次获取下一个节点来拿到指定位置的节点
		h = h->next;
	}
 
	return h;
//报错区域
ERROR:
	printf("该节点不存在");
}
/*
 *改变链表指定节点的值
*/
void change_linked_value(AA *head,int n,int value){
	//先获取指定节点,调用已经写好的函数
	AA *node = get_linked_value(head,n);
	//改变值
	node->num = value;
}
/*
 *增加链表的节点(在末尾添加)
*/
AA *add_linked_value(AA *head,int value){
	AA *node = head;
	AA *end = NULL;	
	//用循环,获取到最后一个节点
	while(!(node->next == NULL)){
		node = node->next;
	}
 
	//新增一个节点,用malloc为节点开辟一块内存
	end = (AA *)malloc(sizeof(AA));
	//创建好一个节点立刻为其指针赋NULL
	end->next = NULL;
	end->num = value;
	//之前的最后一个节点(即现在的倒数第二个节点)的指针指向end
	node->next = end;
 
	//返回尾节点
	return end;
}
/*
 *在指定位置插入新的节点
*/
AA *insert_linked_value(AA *head,int n,int value){
	AA *newNode,*node,*beforeN;	//定义新节点,原来位置的节点和原来位置的上一个节点
	AA *h = head;
	//用之前写好的函数获取到指定位置的节点及其上一个节点,把新节点的指针指向原来位置的节点
	//,而上一个节点把指针指向新节点即可
	node = get_linked_value(h,n);
	beforeN = get_linked_value(h,n-1);
	
	//为新节点开辟一块内存空间
	newNode = (AA *)malloc(sizeof(AA));
	//立刻为新节点的指针赋值,为原来位置的节点
	newNode->next = node;
	newNode->num = value;
	//把原来位置的上一个节点的指针指向新节点
	beforeN->next = newNode;
	
	return newNode;
}
/*
 *删除指定位置的节点
*/
void delete_linked_value(AA *head,int n){
	AA *h = head;
	AA *beforeH = NULL;
 
	//获取该节点的以及其上一个节点
	beforeH = get_linked_value(h,n-1);
	h = get_linked_value(h,n);
 
	判断是否要删除尾节点
	if(n == get_linked_len(h)){
		//删除尾节点,把尾节点的上一个节点的指针设为NULL
		beforeH->next = NULL;
		//free掉尾节点
		free(h);
	}
	//删除节点,先把上一个节点的指针指向要删除的节点的下一个节点
	beforeH->next = h->next;
	//把要删除的节点free掉
	free(h);
}
/*
 *输出链表内容函数
*/
void linked_list(AA *head){
	//输出链表
	while(!(head->next == NULL)){
		//要先把head调至第二个节点,因为第一个节点head没有任何数据,只是一个头节点,只有指针存的是第二个节点的地址
		head = head->next;
		printf("%d\n",head->num);
	}
}
/*
 *获取链表的节点个数
*/
int get_linked_len(AA *head){
	AA *h = head;
	int len = 0;
 
	//循环来统计个数
	while(!(h->next == NULL)){
		h = h->next;
		len++;
	}
	return len;
}
/*
 *主函数
*/
void main(){
	AA *head;
	AA *node;
	int n;
	printf("n:\n");
	scanf("%d",&n);
	//创建链表
	head = create(n);
 
	//获取第2个节点的值
	node = get_linked_value(head,2);
	printf("%d\n",node->num);
 
	//改变第2个节点的值
	change_linked_value(head,2,222);
 
	//删除第3个节点
	delete_linked_value(head,3);
 
	//插入一个节点
	insert_linked_value(head,3,888);
 
	//新增一个节点
	add_linked_value(head,222);
	//输出链表内容
	linked_list(head);
 
	getchar();
	getchar();
}

图形解释:

               1、创建链表

               

                 2、新增节点

                 

                   3、插入节点

                   

               

                      4、删除节点

                      

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值