双向链表的创建,插入,删除与打印

本文详细介绍了双向链表的构成,包括头节点和普通结点的结构,以及如何创建链表、进行头插法、尾插法和指定位置插入节点、删除节点以及打印链表的操作。
摘要由CSDN通过智能技术生成

1,双向链表的构成

双向链表一般是由一个头节点和若干个普通结点组成的,而头节点的结构如下

struct List
{
	int size;//用来对链表中的结点计数
	struct Node* firstNode;//指向第一个结点
	struct Node* lastNode;//指向最后一个结点
};

一般结点结构如下

struct Node
{
	int data;//储存数据
	struct Node* right;//指向上一个结点
	struct Node* left;//指向下一个结点
};

2,双向链表的创建

创建双向链表,首先就是要创建头节点

struct List* createList()
{
	struct List* list = (struct List*)malloc(sizeof(List));//使用malloc函数动态分配空间
	list->firstNode = list->lastNode = NULL;
	return list;
}

 3,插入结点

一般来说,双链表中,插入结点的方法有三种,分别为头插法,尾插法和指定位置插入法

1,头插法

头插法,顾名思义,就是在链表的开头插入一个新的结点,代码如下

struct Node* createNode(int data)
{
	struct Node* newNode = (struct Node*)malloc(sizeof(Node));//使用malloc函数动态分配空间
	newNode->data = data;//储存数据
	newNode->right = newNode->left = NULL;
	return newNode;
}
void insertNodeByHead(struct List* list, int data)
{
	struct Node* newNode = createNode(data);
	if (list->firstNode == NULL)//如果链表为空,直接将新的结点变成第一个结点和最后一个结点
	{
		list->firstNode = newNode;
		list->lastNode = newNode;
	}
	else
	{
		list->firstNode->left = newNode;
		newNode->right = list->firstNode;
		list->firstNode = newNode;
	}
	list->size++;//链表中结点数目加一
}

2,尾插法

尾插法,和头插法原理一样,只不过是从最后一个结点插入,这里就不多说,代码如下

struct Node* createNode(int data)
{
	struct Node* newNode = (struct Node*)malloc(sizeof(Node));//使用malloc函数动态分配空间
	newNode->data = data;//储存数据
	newNode->right = newNode->left = NULL;
	return newNode;
}
void insertNodeByTail(struct List* list, int data)
{
	struct Node* newNode = createNode(data);
	if (list->firstNode == NULL)
	{
		list->firstNode = newNode;
		list->lastNode = newNode;
	}
	else
	{
		list->lastNode->right = newNode;
		newNode->left = list->lastNode;
		list->lastNode = newNode;
	}
	list->size++;
}

3,指定位置插入

接下来就是指定位置插入法了,指定位置插入法是三种插入方法中最难,但也是用处最广泛的方法,它的原理是从第一个结点开始向后寻找,当找到指定的结点是,将新的结点插到它的前面,代码如下

struct List* createList()
{
	struct List* list = (struct List*)malloc(sizeof(List));//使用malloc函数动态分配空间
	list->firstNode = list->lastNode = NULL;
	return list;
}
void insertNodeByAppoin(struct List* list, int posdata, int data)
{
	if (list->firstNode == NULL)
	{
		printf("链表为空\n");
	}
	else if (list->firstNode->data == posdata)
	{
		insertNodeByHead(list, data);
	}
	else
	{
		struct Node* posNode = list->firstNode->right;
		struct Node* posNodeFront = list->firstNode;
		while (posNode->data != posdata && posNode != NULL)//当没有找到合适的结点,就向后循环
		{
			posNodeFront = posNode;
			posNode = posNode->right;
		}
		if (posNode == NULL)
		{
			printf("无法找到\n");
		}
		else
		{
			struct Node* newNode = createNode(data);
			newNode->left = posNodeFront;
			newNode->right = posNode;
			posNode->left = newNode;
			posNodeFront->right = newNode;
			list->size++;
		}
	}
}

3,结点的删除

结点的删除和插入很相似,但删除一般只有指定位置删除法,代码如下

void deleteNodeByAppoin(struct List* list, int posdata)
{
	struct Node* posNode = list->firstNode;
	struct Node* posNodeFront = NULL;
	while (posNode->data != posdata)//找到指定位置
	{
		posNodeFront = posNode;
		posNode = posNode->right;
	}
	posNodeFront->right = posNode->right;
	free(posNode);//删除结点
}

4,链表的打印

链表的打印没什么多说的,代码如下

void printList(struct List* list)
{
	struct Node* pMove = list->firstNode;
	while (pMove)
	{
		printf("%d", pMove->data);//打印该节点的数据
		pMove = pMove->right;//指向下一个结点
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值