数据结构基础4:带头指针双向。

一.基本概念:

一.基本结构:

1.逻辑结构:

数据结构基础4:带头指针双向。_第1张图片

二.结构体的基本组成。

数据结构基础4:带头指针双向。_第2张图片

和单链表非常大的区别就是函数不需要传二级指针,因为头不存有效数据。头节点不需要改变。

二.功能接口的实现

0.创建一个新的节点

//创建新的节点

ListNode* buylistnode(int x)
{
	ListNode* newhead = (ListNode*)malloc(sizeof(ListNode));
	newhead->data = x;
	newhead->next = NULL;
	newhead->prev = NULL;
	return newhead;
}

1.双向链表打印

void ListPrint(ListNode* pHead)
{
	assert(pHead->next != NULL);

	ListNode* cur = pHead->next;
	while (cur!= pHead)
	{
		printf("<-%d->", cur->data);
		cur = cur->next;
	}
	printf("\n");

}

2.双向链表尾插

// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x)
{
	assert(pHead->next);
	ListNode* newhead = buylistnode(x);

	ListNode* tile = pHead->prev;
	tile->next = newhead;
	newhead->prev = tile;

	newhead->next = pHead;
	pHead->prev = newhead;

}

3.双向链表尾删

// 双向链表尾删
void ListPopBack(ListNode* pHead)
{
	assert(pHead);
	assert(pHead->next != NULL);

	ListNode* tile = pHead->prev;
	ListNode* prevtile = pHead->prev->prev;

	free(tile);
	tile->prev = NULL;
	tile->next = NULL;

	prevtile->next = pHead;
	pHead->prev = prevtile;
	
}

4.双向链表头插

// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x)
{
	assert(pHead);

	ListNode* newnode = buylistnode(x);
	ListNode* next = pHead->next;
	
	pHead->next = newnode;
	newnode->prev = pHead;

	newnode->next = next;
	next->prev = newnode;

}

5.双向链表头删

// 双向链表头删
void ListPopFront(ListNode* pHead)
{
	assert(pHead);
	assert(pHead->next!= NULL);

	ListNode* next = pHead->next->next;
	ListNode* delnext = pHead->next;

	free(delnext);
	delnext = NULL;

	pHead->next = next;
	next->prev = pHead;
}

6.双向链表查找

// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x)
{
	assert(pHead);
	assert(pHead->next != NULL);

	ListNode* cur = pHead->next;

	while (cur != pHead)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}

	return NULL;
}

7.双向链表在pos的前面进行插入

// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x)
{

	ListNode* newnode = buylistnode(x);

	ListNode* nextprev = pos->prev;

	nextprev->next = newnode;
	newnode->prev = nextprev;

	newnode->next = pos;
	pos->prev = newnode;

}

8.双向链表删除pos位置的节点

// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{
	assert(pos);
	ListNode* prev = pos->prev;
	ListNode* next = pos->next;

	free(pos);
	pos = NULL;

	prev->next = next;
	next->prev = prev;
}

9.双向链表销毁

// 双向链表销毁
void ListDestory(ListNode* pHead)
{
	assert(pHead);
	assert(pHead->next != NULL);

	ListNode* cur = pHead->next;

	while (cur != pHead)
	{
		ListNode* next = cur->next;
		free(cur);
		cur = NULL;

		cur = next;
	}
}

三.整体代码

#define _CRT_SECURE_NO_WARNINGS 1

#include"list.h"

// 双向链表销毁
void ListDestory(ListNode* pHead)
{
	assert(pHead);
	assert(pHead->next != NULL);

	ListNode* cur = pHead->next;

	while (cur != pHead)
	{
		ListNode* next = cur->next;
		free(cur);
		cur = NULL;

		cur = next;
	}
}

//创建新的节点

ListNode* buylistnode(int x)
{
	ListNode* newhead = (ListNode*)malloc(sizeof(ListNode));
	newhead->data = x;
	newhead->next = NULL;
	newhead->prev = NULL;
	return newhead;
}

// 双向链表打印
void ListPrint(ListNode* pHead)
{
	assert(pHead->next != NULL);


	ListNode* cur = pHead->next;

	while (cur!= pHead)
	{
		printf("<-%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL");
	printf("\n");

}
// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x)
{
	assert(pHead);
	ListNode* newhead = buylistnode(x);

	ListNode* tile = pHead->prev;
	tile->next = newhead;
	newhead->prev = tile;

	newhead->next = pHead;
	pHead->prev = newhead;

}
// 双向链表尾删
void ListPopBack(ListNode* pHead)
{
	assert(pHead);
	assert(pHead->next != NULL);

	ListNode* tile = pHead->prev;
	ListNode* prevtile = pHead->prev->prev;

	free(tile);
	tile = NULL;

	prevtile->next = pHead;
	pHead->prev = prevtile;
	
}
// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x)
{
	assert(pHead);

	ListNode* newnode = buylistnode(x);
	ListNode* next = pHead->next;
	
	pHead->next = newnode;
	newnode->prev = pHead;

	newnode->next = next;
	next->prev = newnode;

}
// 双向链表头删
void ListPopFront(ListNode* pHead)
{
	assert(pHead);
	assert(pHead->next!= NULL);

	ListNode* next = pHead->next->next;
	ListNode* delnext = pHead->next;

	free(delnext);
	delnext = NULL;

	pHead->next = next;
	next->prev = pHead;
}
// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x)
{
	assert(pHead);
	assert(pHead->next != NULL);

	ListNode* cur = pHead->next;

	while (cur != pHead)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}

	return NULL;
}
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x)
{

	ListNode* newnode = buylistnode(x);

	ListNode* nextprev = pos->prev;

	nextprev->next = newnode;
	newnode->prev = nextprev;

	newnode->next = pos;
	pos->prev = newnode;

}
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos)
{
	assert(pos);
	ListNode* prev = pos->prev;
	ListNode* next = pos->next;

	free(pos);
	pos = NULL;

	prev->next = next;
	next->prev = prev;
}





#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include

// 带头+双向+循环链表增删查改实现
typedef int LTDataType;
typedef struct ListNode
{
	LTDataType data;
	struct ListNode* next;
	struct ListNode* prev;
}ListNode;


// 双向链表销毁
void ListDestory(ListNode* pHead);
// 双向链表打印
void ListPrint(ListNode* pHead);
// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x);
// 双向链表尾删
void ListPopBack(ListNode* pHead);
// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x);
// 双向链表头删
void ListPopFront(ListNode* pHead);
// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x);
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos);

/
#define _CRT_SECURE_NO_WARNINGS 1

#include"list.h"

void text1()
{
	ListNode* head = (ListNode*)malloc(sizeof(ListNode));
	head->next = head;
	head->prev = head;

	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	ListPushBack(head, 5);

	ListPrint(head);

	ListPopBack(head);
	ListPopBack(head);
	ListPopBack(head);

	ListPrint(head);

	ListPushFront(head, 6);
	ListPushFront(head, 7);
	ListPushFront(head, 8);
	ListPushFront(head, 9);

	ListPrint(head);

	ListPopFront(head);
	ListPopFront(head);


	ListPrint(head);

	ListNode* del1 = ListFind(head, 6);
	ListInsert(del1, 6);
	ListNode* del2 = ListFind(head, 2);
	ListInsert(del2, 1);
	ListPrint(head);

	del1 = ListFind(head, 6);
	ListErase(del1);
	del2 = ListFind(head, 2);
	ListErase(del2);

	ListPrint(head);

	ListDestory(head);
	ListPrint(head);
}

int main()
{
	text1();
	return 0;
}



今天的分享就到这里了谢谢大家的阅读,我会继续带来更加优质的文章!
数据结构基础4:带头指针双向。_第3张图片

你可能感兴趣的:(数据结构,双向带头链表,函数实现)