链表之双向链表

又是敲代码学习的一天,虽然学的很痛苦,但是看到自己学完后有成果出来还是 很高兴的。
接下来废话不多说直接上代码,代码里有各个函数的解释说明,贯穿着我对这个双向链表的理解

//感觉这个双向链表,就是在单向链表中稍微多加了一个数据域--前指针,
//其他的话也没什么太大的区别,其次在进行数据交换时要注意两个数据之间指针的断连
//是先断还是先连,这个要考虑清楚,不然写代码的时候会感到很困惑
//首先定义一下结构体
typedef struct Node
{
	int data;		//数据域
	Node * left;	//这是指向左边节点的指针域
	Node* right;	//这是指向右边节点的指针域
}Node;
//创建头节点,作为链表的头
Node * createHeadNode()
{
	Node * headNode = (Node*)malloc(sizeof(Node));
	headNode->left = headNode->right = NULL;
	return headNode;
}
//创建节点,使后面的申请节点操作更为方便,有要创建节点直接调用该函数即可
Node * createNode(int data)
{
	Node * newNode = (Node*)malloc(sizeof(Node));
	newNode->data = data;
	newNode->left = newNode->right = NULL;
	return newNode;
}
/*在链表头部插入数据,这个时候要考虑表头后面是否有数据,
没有数据操作就很方便,直接将两个节点连接就行。但是头节点后头有数据操作就会麻烦一些,
要考虑到节点之间连接的先后顺序,顺序没想清楚的话就很容易出问题
连接方法是这样的:
			1. 先让头节点后头的那个节点和新生成的节点先相互连上即:
		 		headNode->right->left = newNode;
				newNode->right = headNode->right;
			2. 然后让头节点和新节点连上
				newNode->left = headNode;
				headNode->right = newNode;
			如果还是不是很理解的话可以自己画个图看看,多看一阵子就想出来,时间关系我就不多讲了
*/
//链表头部插入数据
void headAddNode(Node * headNode,int data)
{
	Node * newNode = createNode(data);
	if (headNode->right == NULL)
	{
		headNode->right = newNode;
		newNode->left = headNode;
	}
	else
	{
		headNode->right->left = newNode;
		newNode->right = headNode->right;
		newNode->left = headNode;
		headNode->right = newNode;
	}
}
/*
	这个操作就有点麻烦了,要三个指针了,一个记录当前位置,一个记录下一个节点的地址,
	还要有一个新节点,这里主要是要找的尾节点,用循环结构就行,找到之后就很方便了,
	代码在下面自己体会吧,不是很难,这个只要想清楚你要干什么,然后就是你完成这件事的一些条件,把这些条件满足就行,事情不就完成了
*/
//尾部插入数据
void tailNodeData(Node * headNode,int data)
{
	Node * newNode = createNode(data);
	Node* proPMove = headNode;
	Node * pMove = headNode;
	while (pMove)
	{
		proPMove = pMove;
		pMove = pMove->right;
	}
	proPMove->right = newNode;
	newNode->left = proPMove;
}
//将链表的数据输出
void printNodeData(Node * headNode)
{
	Node* pMove = headNode->right;
	while (pMove)
	{
		printf("%d-->", pMove->data);
		pMove = pMove->right;
	}
	printf("\n");
	
}

int main()
{
	Node * List = createHeadNode();//创建双向链表的头,不存放数据

	for (int i = 0; i < 10; i++)
	{
		headAddNode(List, i);
	}
	printNodeData(List);//打印链表里的数据
	tailNodeData(List, 11);
	printNodeData(List);
	return 0;
}

看了这么多了,是不是很累了,再坚持一下,或者休息一下再来看
其实这个双向链表还有别的实现方式–借助第二个结构体

typedef struct List
{
	int size ;			//用于统计几点的数目
	List * head;		//用于指向链表的头部
	List * tail;		//用于指向链表的尾部
}List

/*
	然后很简单了,这个就交给文章前的你来完成了
*/

此时的你经过上面的双向链表的学习,有没有一点想法。有没有想实现双向循环链表。
这时你会有灵感吗?
如果没有的话,那我来提醒一下你。其实这时候你只要将这个双向链表的left的NULL赋为最后一个节点的地址,最后一个节点的right赋为头节点的地址。这样不就头尾连接起来了。是不是很神奇。
那这样有思路了,剩下的就交给你来实现了。代码我就不写了,如果有遇到什么问题可以私信我哦,有空看到了会回复的。
好了,今天就先写到这里了,好困太晚了,先睡了。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值