双向链表的基本操作(不循环)

什么是双向链表?

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表

如图:



双向链表的基本操作:头插,头删,尾插,尾删,任意位置前插入,任意位置后插入,查找节点。

代码块:

DLink.h


#pragma once 
#include <stdio.h>
typedef int DLinkType;

typedef struct DLinkNode {
	DLinkType data;
	struct DLinkNode* _next;
	struct DLinkNode* _prev;
} DLinkNode;



DLinkNode* BuyNode(DLinkType value);//创建节点

void DestroyNode(DLinkNode** PosNode);//删除节点

void PrintDlink(DLinkNode*head);//打印链表

void InitDLinkList(DLinkNode** head);//初始化

DLinkNode* PushBackDLinkList(DLinkNode*phead, DLinkType value);//尾插

void* PopBackDLinList(DLinkNode** head);//尾删

void PushFrontDLinkList(DLinkNode** head, DLinkType value);//头插

void PopFrontDLinkList(DLinkNode* head);//头删

DLinkNode* FindDLinkList(DLinkNode* head, DLinkType to_find);//查找

void InsertDLinkList(DLinkNode** head, DLinkNode* pos, DLinkType value);//在某个节点前插入元素

void InsertAfterDLinkList(DLinkNode** head, DLinkNode* pos, DLinkType value);//在某个节点后插入元素

DLink.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<stdlib.h>
#include<assert.h>
#include"DLink.h"


void DestroyNode(DLinkNode*PosNode)
{
	assert(PosNode);
	free(PosNode);
	PosNode = NULL;
}

void PrintDlink(DLinkNode* head)
{
	assert(head);
	DLinkNode*CurNode = head;
	printf("NULL<=");
	while (CurNode)
	{
		printf("%d<=>", CurNode->data);
		CurNode = CurNode->_next;
	}
	printf("NULL\n");
}

void InitDLinkList(DLinkNode** head)
{
	if (head == NULL) {
		return;
	}
	*head = NULL;
}

DLinkNode* BuyNode(DLinkType value) {
	DLinkNode* new_node = (DLinkNode*)malloc(sizeof(DLinkNode));
	if (new_node != NULL) {
		new_node->_prev = NULL;
		new_node->_next = NULL;
		new_node->data = value;
	}
	return new_node;
}

DLinkNode* PushBackDLinkList(DLinkNode**head, DLinkType value)//尾插
{
	assert(head);
	DLinkNode*InsertNode = BuyNode(value);
	if (*head == NULL)//如果链表还没有元素
	{
		*head = InsertNode;
		return InsertNode;
	}
	DLinkNode*CurNode = (*head);
	while (CurNode->_next != NULL)//循环到最后
	{
		CurNode = CurNode->_next;
	}
	CurNode->_next = InsertNode;
	InsertNode->_next = NULL;
	InsertNode->_prev = CurNode;
	return InsertNode;
}

void* PopBackDLinList(DLinkNode** head)
{
	assert(head);
	DLinkNode*CurNode = (*head);
	DLinkNode*PrevNode = NULL;//标记当前节点的前一个节点
	while (CurNode->_next != NULL)
	{
		PrevNode = CurNode;
		CurNode = CurNode->_next;
	}
	DestroyNode(CurNode);
	PrevNode->_next = NULL;
}

void PushFrontDLinkList(DLinkNode** head, DLinkType value)
{
	assert(head);
	DLinkNode*InsertNode=BuyNode(value);
	DLinkNode*TmpNode = (*head);
	(*head) = InsertNode;
	InsertNode->_prev = NULL;
	InsertNode->_next = TmpNode;
	return InsertNode;
}

void PopFrontDLinkList(DLinkNode** head)
{
	assert(head);
	*head = (*head)->_next;
}

DLinkNode* FindDLinkList(DLinkNode* head, DLinkType to_find)
{
	assert(head);
	DLinkNode*CurNode = (head);
	while (CurNode)
	{
		if (CurNode->data == to_find)
		{
			return CurNode;
		}
		CurNode = CurNode->_next;
	}
}

void InsertDLinkList(DLinkNode** head, DLinkNode* pos, DLinkType value)
{
	assert(pos);
	if (pos == (*head))//如果pos是头节点
	{
		PushFrontDLinkList(head, value);//头插法
		return;
	}
	DLinkNode*CurNode = (*head);
	DLinkNode*PrevNode = NULL;
	DLinkNode*InsertNode = BuyNode(value);
	while (CurNode!= pos)//循环到pos位置
	{
		PrevNode = CurNode;
		CurNode = CurNode->_next;
	}
	PrevNode->_next = InsertNode;
	InsertNode->_prev = PrevNode;
	InsertNode->_next = CurNode;
	CurNode->_prev = InsertNode;
}

void InsertAfterDLinkList(DLinkNode** head, DLinkNode* pos, DLinkType value)//任意位置后一位插入
{
	 assert(head);
         DLinkNode*InsertNode = BuyNode(value);
         if (pos->_next == NULL)
         {
          PushBackDLinkList(head,value);
          return;
         }
         DLinkNode*CurNode = (*head);
         while (CurNode != pos)
         {
          CurNode = CurNode->_next;
         }
         InsertNode->_next = CurNode->_next;
         CurNode->_next->_prev = InsertNode;
         CurNode->_next = InsertNode;
         InsertNode->_prev = CurNode;
}


test.c


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>
#include"DLink.h"
int main()
{
	DLinkNode* DLink;
	InitDLinkList(&DLink);
	DLinkNode* tmp = PushBackDLinkList(&DLink, 1);
	PushBackDLinkList(&DLink, 2);
	PushBackDLinkList(&DLink, 3);
	PushBackDLinkList(&DLink, 4);
	//PushFrontDLinkList(&DLink, 0);
	//InsertAfterDLinkList(&DLink, tmp, 5);
	//InsertDLinkList(&DLink,tmp , 0);
	//PopBackDLinList(&DLink);
	//PopFrontDLinkList(&DLink);
	//FindDLinkList(DLink, 3);
	PrintDlink(DLink);
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/komacc/article/details/80326849