c语言 挑战本站最详细注释双链表实现

经过上一个文章单链表的实现,我决定写一个具有详细注释的双链表代码展示

声明:本文章采用头结点方式,本文章结构先是代码分装函数,最后有全部代码实现


1.   定义创建并初始化

#include<stdio.h>          //引用头文件
#include<stdlib.h>
#include<assert.h>        
typedef struct Node      //定义一个结构体
{
	int data;                     //数据域
	struct Node* per;            //前指针域
	struct Node* next;          //后指针域三部分
}Node;                //给结构体重新起一个名字                 
      
      //创建并初始化
Node*  initList()      //返回的结点类型为Node*
{
	Node* L = (Node*)malloc(sizeof(Node));     //动态开辟一个结点
	assert(L);        //判断L是否成功开辟,如果开辟失败直接报错
	L->data = 0;      //头结点的数据域来储存链表元素个数
	L->per = 0;   
	L->next = 0;       //两个指针置空
	return L;           //返回结点
}

2.   头插法添加结点

void headInsert(Node* L,int x)
{
	Node* node = (Node*)malloc(sizeof(node));  //动态开辟一个结点
	assert(node);                              //判断L是否成功开辟,如果开辟失败直接报错
	node->data = x;              //x是想插入的元素
	if (L->data==0)               //判断是否为第一次插入,如果为空进入if语句
	{
		node->next = NULL;                   //因为 为空与不为空操作步骤不一样    
		node->per = L;
		L->next = node;
	}
	else
	{                              //不为空,
		node->per = L;
		node->next = L->next;
		L->next->per = node;
		L->next = node;
	}
	L->data++;									//记录元素个数,加一
}

3.  尾插法添加结点

					
void tailList(Node* L, int x)
{
	Node* n = L;
	Node* node = (Node*)malloc(sizeof(Node));
	assert(node);
	node->data = x;          //道理和上面代码类似,本处便不再解释
	
	while (n->next)         //循环遍历,作用:找到最后一个结点
		{
		n = n->next;
		}
                                  //找到会跳出循环,进行尾插
	node->next = n->next;         //先连接尾部
	n->next = node;
	node->per = n;               //连接头部
	L->data++;                   //记录长度元素个数加一
	
}

4.  删除任意位置结点

void deleteList(Node* L,int data)
{
	Node* node = L->next;          
	if (node == NULL)              //判断链表是否为空
	{
		printf("不存在");
         exit(-1);                 //中断程序
	}
	while (node)                   //判断node结点是否为空指针
	{
		if (node->data == data)     //找到后还要分两种情况 
		{
			if (node->next == NULL)   //第1种为尾结点
			{
				node->per->next = NULL;
				node->per = NULL;
				break;                //跳出循环
			}
			node->next->per = node->per;  //第2种不为尾结点
			node->per->next = node->next;
			
		}
		node = node->next;            //循环遍历,当node为空指针时跳出循环
	 }
	free(node);         //释放要删除的结点
	node = NULL;       //避免野指针出现
	L->data--;         //记录元素个数减一
 
}

5.打印链表

							
void printList(Node* L)
{
	Node* node = L->next;           //跳过头结点
	while (node != NULL)            //循环遍历每一个元素
	{
		printf("%d->", node->data);
		node = node->next;
	}
	printf("NULL\n");           //为了美观
}

6.主函数,来调用其它子函数

int main()
{
	
	Node* L=initList();         
	headInsert(L, 1);         //头插添加元素1
	headInsert(L, 2);         //头插添加元素2
	tailList(L, 1);           //头插添加元素1
	tailList(L, 2);           //头插添加元素2
	printList(L);       //打印链表
	deleteList(L, 2);         //删除元素为2的结点
	deleteList(L, 1);         //删除元素为1的结点
	printList(L);       //再打印链表
	return 0;
}

整体代码

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef struct Node
{
	int data;
	struct Node* per;
	struct Node* next;
}Node;
							  //初始化
Node*  initList()
{
	Node* L = (Node*)malloc(sizeof(Node));
	assert(L);
	L->data = 0;
	L->per = 0;
	L->next = 0;
	return L;
}
								//头插法
void headInsert(Node* L,int x)
{
	Node* node = (Node*)malloc(sizeof(node));
	assert(node);
	node->data = x;
	if (L->data==0)
	{
		node->next = NULL;
		node->per = L;
		L->next = node;
		L->data++;
	}
	else
	{
		node->per = L;
		node->next = L->next;
		L->next->per = node;
		L->next = node;
	}
	L->data++;									//记录元素个数
}
							//尾插法
							
void tailList(Node* L, int x)
{
	Node* n = L;
	Node* node = (Node*)malloc(sizeof(Node));
	assert(node);
	node->data = x;
	
	while (n->next)
		{
		n = n->next;
		}
	node->next = n->next;
	n->next = node;
	node->per = n;
	L->data++;
	
}

							//删除
							
void deleteList(Node* L,int data)
{
	Node* node = L->next;
	if (node == NULL)
	{
		printf("不存在");
		exit(-1);
	}
	while (node)
	{
		if (node->data == data)
		{
			if (node->next == NULL)
			{
				node->per->next = NULL;
				node->per = NULL;
				break;
			}
			node->next->per = node->per;
			node->per->next = node->next;
			
		}
		node = node->next;
	 }
	free(node);
	node = NULL;
	L->data--;

}
							//打印
void printList(Node* L)
{
	Node* node = L->next;
	while (node != NULL)
	{
		printf("%d->", node->data);
		node = node->next;
	}
	printf("NULL\n");
}

int main()
{
	
	Node* L=initList();
	/*headInsert(L, 1);
	headInsert(L, 2);
	tailList(L, 1);
	tailList(L, 2);
	printList(L);
	deleteList(L, 2);*/
	deleteList(L, 1);
	printList(L);
	return 0;
}

所有注释都是我亲自写的,如果文章对您有帮助,别吝啬您的手指嘿,嘿嘿嘿,谢谢大家,热烈欢迎大家评论!!

  • 36
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 52
    评论
评论 52
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

洁洁!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值