ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

双向链表的基本操作

2022-01-18 20:58:38  阅读:183  来源: 互联网

标签:curNode list newNode 链表 双向 基本操作 NULL 节点


1. 与双向链表的初相识

首先,要明白它长什么样子:

  通过观察可以发现这玩意由好几个单体组成,长度不定。欸嘿嘿,但每一个单体都是一样的啊。

————有数据,有指向上一个单体的指针,有指向下一个单体的指针,只不过首尾指向空而已。

那么这几行代码就不南个理解啦!

typedef struct Node
{
	int data;//节点里存储的数据
	struct Node* front;//指向前一个单体的指针
	struct Node* tail; //指向后一个单体的指针
}NODE,*LPNODE;

创建一个节点就更好理解喽

LPNODE createNode(int data) 
{
	LPNODE newNode = (LPNODE)malloc(sizeof(NODE));//new一个节点
	assert(newNode);//断言,万一没有new出来就终止
	newNode->front = NULL;//就创建了一个节点,首尾指向空
	newNode->tail = NULL;
	newNode->data = data;//传数据
	return newNode;
}

其次,我们要处理的是一个双向链表,并不是一个一个的节点,那是不是得创建一个双像链表的结构呢?必须滴。

typedef struct DList 
{
	LPNODE frontNode; //双向链表的首节点
	LPNODE tailNode;  //双向链表的尾节点
	int curSize;      //当前链表列表有多少个节点
}DLIST,*LPDLIST;
LPDLIST createDList() //创建一个双向链表
{
	LPDLIST list = (LPDLIST)malloc(sizeof(DLIST));
	assert(list);
	list->frontNode = NULL;
	list->tailNode = NULL;
	list->curSize = 0;
	return list;
}

好啦下面进入插入删除操作啦;

   头部插入:

void push_front(LPDLIST list,int data) 
{
	if (list == NULL)//判断列表是否为NULL,NULL和’空‘两个意思哦
		return;
	LPNODE newNode = createNode(data);//先创建一个再插入啊
	if (list->curSize == 0)           //如果是空链表
	{
		list->frontNode = newNode;    //列表的头节点就是创建的那个
		list->tailNode = newNode;     //欸嘿嘿,尾节点也是它哦
		list->curSize++;              //插入了嘛,节点数就变了+1
	}
	else                              //如果不是空链表
	{
		newNode->tail = list->frontNode; //先创建的节点的尾部指向列表的头节点
		list->frontNode->front = newNode;//列表的头节点的指向下一个节点的指针指向新创建的节点
		list->frontNode = newNode;       //列表的头节点变成了新创建的节点
		list->curSize++;                 //插入了嘛,节点数就变了+1
	}
}

对于不是NULL节点插入的图像:         我画的不好看哈,将就着看吧。。。三步走

 尾部插入:

void push_back(LPDLIST list, int data) 
{
	if (list == NULL)//判断是否为NULL链表
		return;
	LPNODE newNode = createNode(data);//创建节点
	if (list->curSize == 0)           //如果为空链表,就。和头部插入一样了
	{
		list->frontNode = newNode;
		list->tailNode = newNode;
		list->curSize++;
	}
	else                             //如果不是
	{
		list->tailNode->tail = newNode;//链表的尾节点的尾部指向新链表
		newNode->front = list->tailNode;//新节点的头指针指向此时链表的尾节点
		list->tailNode = newNode;       //尾节点只有一个,,就是最后一个
		list->curSize++;                //插入了嘛,节点个数+1
	}
}

指定位置插入:  注意注意 这里用数据充当指定位置

void push_appoin(LPDLIST list, int posData, int data) 
{
	if (list == NULL||list->curSize==0)
		return;
	if (list->frontNode->data == posData)
	{
		push_front(list, data);
	}
	else 
	{
		LPNODE preNode = list->frontNode;//要插入的节点的前一个节点
		LPNODE curNode = list->frontNode;//要插入的节点的后一个节点
		while (curNode != NULL && curNode->data != posData) 
		{
			preNode = curNode;
			curNode = preNode->tail;
		}
		if (curNode == NULL) 
		{
			printf("未找到指定位置,无法插入!\n");
		}
		else 
		{
			LPNODE newNode = createNode(data);//创建要插入的节点
			preNode->tail = newNode;//前一个节点的尾指针指向新节点
			newNode->tail = curNode;//新节点的尾指针指向后一个节点
			curNode->front = newNode;//后一个节点的前指针指向新节点
			newNode->front = preNode;//新节点的前指针指向前一个节点
			list->curSize++;
		}
	}
}

 接下来删除的相应操作就不用多说了吧。

void pop_front(LPDLIST list) 
{
	if (list == NULL || list->curSize == 0) 
	{
		printf("无法删除!链表为空\n");
		return;
	}
	LPNODE nextNode = list->frontNode->tail;  //nextNode=NULL
	free(list->frontNode);
	list->frontNode = nextNode;				  //NULL
	if (nextNode != NULL)
	{
		nextNode->front = NULL;
	}
	else 
	{
		list->tailNode = NULL;
	}
	list->curSize--;
}
void pop_back(LPDLIST list) 
{
	if (list == NULL || list->curSize == 0) 
	{
		printf("链表为空无法删除!\n");
		return;
	}
	LPNODE preNode = list->tailNode->front;	//表尾的上一个节点
	free(list->tailNode);
	list->tailNode = preNode;
	if (preNode != NULL) 
	{
		preNode->tail = NULL;   //当只有一个节点preNode=NULL
	}
	else 
	{
		list->frontNode = NULL;
	}
	list->curSize--;
}
void pop_appoin(LPDLIST list, int posData) 
{
	if (list == NULL || list->curSize == 0) 
	{
		printf("链表为空无法删除!");
		return;
	}
	if (list->frontNode->data == posData) 
	{
		pop_front(list);
		return;
	}
	LPNODE preNode = list->frontNode;
	LPNODE curNode = list->frontNode;
	while (curNode != NULL&&curNode->data!=posData)
	{
		preNode = curNode;
		curNode = preNode->tail;
	}
	if (curNode == NULL)
	{
		printf("未找到指定位置无法删除!\n");
	}
	else 
	{
		if (list->tailNode == curNode) 
		{
			pop_back(list);
		}
		else 
		{
			preNode->tail = curNode->tail;
			//curNode->tail是不是不空
			//当删除的表尾时候,curNode->tail等于空
			curNode->tail->front = preNode;
			free(curNode);
			curNode = NULL;
			list->curSize--;
		}
	}
}

预祝新年快乐!!!

标签:curNode,list,newNode,链表,双向,基本操作,NULL,节点
来源: https://blog.csdn.net/qq_50208608/article/details/122565981

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有