图解无头单向非循环链表和带头双向循环链表


链表是一种重要的数据结构,其概念:链表是一种 物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链
接次序实现的

这里介绍两种链表:

  1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。
  1. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。

单链表(单向不带头)

在这里插入图片描述

数据节点和头结点

在这里插入图片描述

typedef int Data;        //数据类型
typedef struct lists{
       //自定义单链表结构体
	Data _data;
	struct lists* _next;
}lists;

//自定义头结点
typedef struct firstlist{
   //用来找到并操作链表,必须从头开始
	struct lists* _head;
}firstlist;

新增节点函数和初始化

//结构体初始化
void init(firstlist* flist){
   
	if (flist == NULL){
   
		return flist;
	}
	flist->_head = NULL;   //数据设为空
}

lists* xinzeng(Data _data){
   //将一个数据传入一个新链表,返回新链表的地址
	lists* newlist = (lists*)malloc(sizeof(lists));
	newlist->_data = _data;
	newlist->_next = NULL;
	return newlist;
}

基本操作

1.尾插

在这里插入图片描述

//尾插
void weicha(firstlist* lit,Data data){
   //将data尾插到lit链表中
	//传firstlist是因为知道头结点地址就可以操作链表了
	if (lit == NULL){
   //如果是空链表直接返回null
		return;
	}
	//空链表插入第一个数据
	if (lit->_head == NULL){
   
		lit->_head = xinzeng(data);
	}
	else{
   //不是空链表则需要遍历
		lists* list = lit->_head;
		//因为_head是第一个元素的地址,所以要lists*
		while (list->_next != NULL){
   
			list = list->_next;
		}
		list->_next = xinzeng(data);
	}
}

2.尾删

在这里插入图片描述

//尾删
void weishan(firstlist* flist){
   
	if (flist == NULL||flist->_head==NULL){
   
		return;
	}
	//用两个变量one 和two来操作
	lists* one = flist->_head;
	lists* two = NULL;
	if (one->_next != NULL){
   
		two = one;
		one = one->_next;
	}
	free(one);
	if (two == NULL){
   //这种是只有头节点,two就没变
		flist->_head = NULL;
	}
	else{
   
		two->_next = NULL;
	}
}

3.头插

在这里插入图片描述

//头插
void toucha(firstlist* flist,Data data){
   
	if (flist == NULL){
   
		return;
	}
	if (flist->_head == NULL){
   
		flist->_head = xinzeng(data);
	}
	else{
   
		lists* b = xinzeng(data);
		b->_next = flist->_head;
		flist->_head = b;	
	}
}

4.头删

//头删
void toushan(firstlist* list){
   
	if (list==NULL){
   
		return;
	}
	if (list->_head == NULL){
   
		return;
	}
	else{
   
		struct lists* next = list->_head->_next;
		free(list->_head);
		list->_head = next;
	}
}

5.任意位置新增节点

//在哪新增一个节点
void jiaru(lists* a,Data data){
   //用不到头节点所以直接操作
	lists* list = xinzeng(data);
	list->_next = a->_next;
	a->_next = list;
}

6.任意位置删除

//删除那个位置的下一个
void shanchu(lists* a,Data data){
   
	lists* next = a->_next;
	if (next == NULL){
   
		return;
	}
	li
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值