带头节点的双向循环链表的基本操作

·什么是带头结点的双向循环链表

我们直接给出带头结点的双向循环链表的图示:

带头节点的双向循环链表的基本操作_第1张图片那么有无头结点的区别是什么呢?

头节点是为了操作的统一、方便而设立的,一般来说,头节点放在第一元素节点之前,其数据域一般无意义(当然有些情况下也可存放链表的长度、用做监视哨等)。有头节点后,对在第一元素节点前插入节点和删除第一节点,其操作与对其他节点的操作统一了。而且无论链表是否为空,头指针均不为空。

第二个问题,双向循环链表相比较于单链表有哪些不同?

单向链表和双向链表的区别在于:单向链表中,每个节点只有一个指向下一个节点的指针,而双向链表则有两个指针,分别指向上一个和下一个节点。进一步的如果是一个循环链表,那么就不存在NULL,可以直接通过最后一个节点访问到头结点。

·代码及其实现

·Dlist.h

#include 
#include 
typedef int DataType;

typedef struct DListNode
{
	struct DListNode* pNext;
	struct DListNode* pPre;
	DataType Data;
}DListNode,*pDListNode;


// 初始化 
void DListInit(pDListNode* pHead);
void PrintDList(pDListNode pHead);
static pDListNode CreateNewNode(DataType data);

// 双向链表的尾插 
void DListPushBack(pDListNode *pHead, DataType data);

// 双向链表的尾删 
void DListPopBack(pDListNode *pHead);

// 双向链表的头插 
void DListPushFront(pDListNode *pHead, DataType data);

// 双向链表的头删 
void DListPopFront(pDListNode *pHead);

// 任意位置插入 
void DListInsert(pDListNode pos, DataType data);

// 任意位置删除 
void DListErase(pDListNode pos);

// 查找值为data的结点 
pDListNode* DListFind(pDListNode *pHead, DataType data);

// 销毁 
void DListDestroy(pDListNode* pHead);

·Dlist.c

#include "DList.h"

static pDListNode CreateNewNode(DataType data)
{
	pDListNode newNode = (pDListNode)malloc(sizeof(DListNode));
	newNode->Data = data;
	newNode->pPre = NULL;
	newNode->pNext = NULL;

	return newNode;
}

// 初始化 
void DListInit(pDListNode* pHead)
{
	(*pHead) = (pDListNode)malloc(sizeof(DListNode));
	(*pHead)->pNext = (*pHead);
	(*pHead)->pPre = (*pHead);
}
void DListPushBack(pDListNode *pHead, DataType data)
{
	pDListNode newNode = NULL;
	pDListNode cur = *pHead;
	newNode = CreateNewNode(data);
	while (cur->pNext != *pHead)
	{
		cur = cur->pNext;
	}
	newNode->pNext = cur->pNext;
	newNode->pPre = cur;
	cur->pNext->pPre = newNode;
	cur->pNext = newNode;
}
void PrintDList(pDListNode pHead)
{
	pDListNode cur = pHead->pNext;
	while (cur->pNext != pHead)
	{
		printf("%d", cur->Data);
		cur = cur->pNext;
		printf("\n");
	}
	printf("%d", cur->Data);
	printf("\n");
}

void DListPopBack(pDListNode* pHead)
{
	pDListNode cur = *pHead;
	pDListNode pLast = cur->pPre;
	cur->pPre->pPre->pNext = cur;
	cur->pPre = cur->pPre->pPre;
	free(pLast);
}
void DListPushFront(pDListNode *pHead, DataType data)
{
	pDListNode newNode = NULL;
	pDListNode cur = *pHead;
	newNode = CreateNewNode(data);
	cur->pNext->pPre = newNode;
	newNode->pNext = cur->pNext;
	cur->pNext = newNode;
	newNode->pPre = cur;
}
void DListPopFront(pDListNode *pHead)
{
	pDListNode cur = *pHead;
	pDListNode Last = cur->pNext;
	cur->pNext = Last->pNext;
	Last->pNext->pPre = cur;
}

void DListErase(pDListNode pos)
{
	pDListNode pre = NULL;
	pDListNode next = NULL;
	/*pos->pPre->pNext = pos->pNext;
	pos->pNext->pPre = pos->pPre;*/
	pre = pos->pPre;
	next = pos->pNext;
	pre->pNext = next;
	next->pPre = pre;
	free(pos);
}

pDListNode* DListFind(pDListNode *pHead, DataType data)
{
	pDListNode cur = *pHead;
	pDListNode last = *pHead;
	while (cur->Data != data)
	{
		cur = cur->pNext;
		if (cur->pNext == last)
		{
			printf("未找到\n");
			break;
			return;
		}
	}
	return cur;
}

void DListInsert(pDListNode pos, DataType data)
{
	pDListNode newNode = CreateNewNode(data);
	newNode->pNext = pos->pNext;
	newNode->pPre = pos;
	pos->pNext->pPre = newNode;
	pos->pNext = newNode;
}

void DListDestroy(pDListNode* pHead)
{

}
void test()
{
	DListNode* DList = NULL;
	DListInit(&DList);
	DListPushBack(&DList, 1);
	DListPushBack(&DList, 2);
	DListPushBack(&DList, 3);
	DListPushBack(&DList, 4);
	DListInsert(DListFind(&DList,2), 5);
	PrintDList(DList);
}
int main()
{
	test();
	system("pause");
	return 0;
}

 

你可能感兴趣的:(数据结构与算法)