【数据结构】带头结点双向循环链表

List.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int LTDataType;

typedef struct ListNode
{
	LTDataType data;
	struct ListNode* prev;
	struct ListNode* next;
}ListNode;

void ListPushBack(ListNode** pphead, LTDataType n);
void ListPopBack(ListNode** pphead);
void ListPrint(ListNode* phead);
void ListInit(ListNode** pphead); //该接口主要是为了建立头指针
ListNode* BuyListNode(LTDataType n);
void ListPrint(ListNode* phead);
void ListPushFront(ListNode** pphead, LTDataType n);
void ListPopFront(ListNode** pphead);
ListNode* ListFind(ListNode* phead, LTDataType n);
void ListInsert(ListNode** pphead);
void ListInsert(ListNode* pos, LTDataType n);
void ListErase(ListNode* pos);
void ListNodeFree(ListNode** pphead);
void ListNodeDestroy(ListNode** pphead);

.
.
.
.
List.c

#include"List.h"


//该函数主要是为了建立头结点
void ListInit(ListNode** pphead)
{
	//assert(*pphead != NULL);
	*pphead = BuyListNode(0);
	(*pphead)->next = *pphead;
	(*pphead)->prev = *pphead;
}

ListNode* BuyListNode(LTDataType n)
{
	ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
	if (newNode == NULL)
	{
		printf("扩容失败!");
		exit(-1);
	}
	newNode->data = n;
	newNode->next = NULL;
	newNode->prev = NULL;
	return newNode;
}


void ListPrint(ListNode* phead)
{
	assert(phead);
	ListNode* cur = phead->next;//不能把头结点的值打印出来
	//遍历链表
	while (cur != phead)
	{
		printf(" %d ", cur->data);
		cur = cur->next;
	}
	printf("\n");
}


void ListPushBack(ListNode** pphead, LTDataType n)
{
	assert(*pphead);

	ListNode* newNode = BuyListNode(n);
	ListNode* tail = (*pphead)->prev;
	//head....tail newNode

	tail->next = newNode;
	newNode->prev = tail;

	newNode->next = *pphead;
	(*pphead)->prev = newNode;

}

void ListPopBack(ListNode** pphead)
{

	assert(*pphead);
	assert((*pphead)->next != (* pphead));

	ListNode* tail = (*pphead)->prev;
	ListNode* tailPrev = tail->prev;

	//free的两部曲
	free(tail);
	tail = NULL;

	(*pphead)->prev = tailPrev;
	tailPrev->next = *pphead;

}


void ListPushFront(ListNode** pphead, LTDataType n)
{
	assert(*pphead);

	ListNode* first = (*pphead)->next;
	ListNode* newNode = BuyListNode(n);

	newNode->prev = (*pphead);
	(*pphead)->next = newNode;

	first->prev = newNode;
	newNode->next = first;
}


void ListPopFront(ListNode** pphead)
{
	assert(*pphead);
	assert((* pphead)->next!=(*pphead));

	ListNode* first = (*pphead)->next;
	ListNode* second = (*pphead)->next->next;

	second->prev = (*pphead);
	(*pphead)->next = second;

	//free两部曲
	free(first);
	first = NULL;

}

ListNode* ListFind(ListNode* phead, LTDataType n)
{
	assert(phead);

	ListNode* cur = phead->next;                                                           
	while (cur != phead)
	{
		if (cur->data == n)
			return cur;
		else
			cur = cur->next;
	}

	return NULL;
}

//在pos后面插入n
void ListInsert(ListNode* pos, LTDataType n)
{
	assert(pos);
	//pos newNode posNext
	ListNode* newNode = BuyListNode(n);
	ListNode* posNext = pos->next;

	newNode->prev = pos;
	pos->next = newNode;

	posNext->prev = newNode;
	newNode->next = posNext;
}

//删除pos后面的值
void ListErase(ListNode* pos)
{	
	assert(pos!=NULL);

	ListNode* posPrev = pos->prev;
	ListNode* posNext = pos->next;
	posPrev->next = posNext;
	posNext->prev = posPrev;
	
	//free两部曲
	free(pos);
	pos = NULL;
}

void ListNodeFree(ListNode** pphead)
{
	free(*pphead);
	(*pphead) = NULL;
}


void ListNodeDestroy(ListNode** pphead)
{
	ListNode* cur = (*pphead)->next;
	while (cur != *pphead)
	{
		ListNode* curNext = cur->next;

		free(cur);
		cur = NULL;

		cur = curNext;

	}
}

.
.
.
test.c

#include"List.h"
//带头 双向 循环 链表

void TestList1()
{
	ListNode* phead = NULL;
	ListInit(&phead);
	ListPushBack(&phead,1);
	ListPushBack(&phead, 2);
	ListPushBack(&phead, 3);
	ListPushBack(&phead, 4);
	ListPushBack(&phead, 5);
	ListPrint(phead);

	ListPopBack(&phead);
	ListPopBack(&phead);
	ListPopBack(&phead);
	ListPopBack(&phead);
	ListPopBack(&phead);
	//ListPopBack(&phead);


	ListPrint(phead);
}

void TestList2()
{
	ListNode* phead = NULL;
	ListInit(&phead);
	ListPushFront(&phead, 1);
	ListPushFront(&phead, 2);
	ListPushFront(&phead, 3);
	ListPushFront(&phead, 4);
	ListPushFront(&phead, 5);
	ListPrint(phead);

	/*ListPopFront(&phead);
	ListPopFront(&phead);
	ListPopFront(&phead);
	ListPopFront(&phead);
	ListPrint(phead);*/
	ListNode* pos=ListFind(phead,5);
	ListInsert(pos, 666);
	ListPrint(phead);

	pos = ListFind(phead, 5);
	ListErase(pos);
	ListPrint(phead);


	ListNodeDestroy(&phead);
	ListPrint(phead);

}




int main()
{
	TestList2();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值