手撕带头双向循环链表

链表的概念和结构

链表是一种物理存储上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的

链式结构逻辑连续,物理不一定连续

带头双向循环链表的实现

带头 双向 循环链表

申请新结点

手撕带头双向循环链表_第1张图片

链表初始化

手撕带头双向循环链表_第2张图片

打印

 手撕带头双向循环链表_第3张图片

尾插

手撕带头双向循环链表_第4张图片

测试

 手撕带头双向循环链表_第5张图片

尾删 

手撕带头双向循环链表_第6张图片

测试

手撕带头双向循环链表_第7张图片

 头插

手撕带头双向循环链表_第8张图片

测试

手撕带头双向循环链表_第9张图片

 头删

手撕带头双向循环链表_第10张图片

测试

手撕带头双向循环链表_第11张图片

 链表长度

手撕带头双向循环链表_第12张图片

测试

手撕带头双向循环链表_第13张图片

查找

手撕带头双向循环链表_第14张图片

 

在pos位置前插入

手撕带头双向循环链表_第15张图片

测试

 手撕带头双向循环链表_第16张图片

 删除pos位置

手撕带头双向循环链表_第17张图片

测试

 手撕带头双向循环链表_第18张图片

销毁链表

 手撕带头双向循环链表_第19张图片

完整代码

List.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "List.h"

LTNode* LTInit()            //初始化链表
{
	LTNode* head = BuyListNode(0);
	
	head->next = head;
	head->prev = head;

	return head;
}

LTNode* BuyListNode(LTDataType x)                //创建新结点
{
	LTNode* newnode =(LTNode*)malloc(sizeof(LTNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	newnode->x = x;
	newnode->next = NULL;
	newnode->prev = NULL;

	return newnode;
}

void LTPrint(LTNode* phead)                  //打印
{
	assert(phead);
	LTNode* cur = phead->next;
	printf("phead <=> ");
	//不打印头结点
	while (cur != phead)
	{
		printf("%d <=> ", cur->x);
		cur = cur->next;
	}
	printf("\n");
}

void LTPopBack(LTNode* phead)           //尾删
{
	assert(phead);
	assert(phead->next != phead);

	LTNode* tail = phead->prev;
	LTNode* tailprev = tail->prev;
	tailprev->next = tail->next;
	phead->prev = tailprev;
	free(tail); 
}

void LTPushBack(LTNode* phead, LTDataType x)     //尾插
{
	assert(phead);

	LTNode* newnode = BuyListNode(x);
	LTNode* tail = phead->prev;
	
	tail->next = newnode;
	newnode->prev = tail;

	newnode->next = phead;
	phead->prev = newnode;
}

void LTPushFront(LTNode* phead, LTDataType x)     //头插
{
	assert(phead);

	LTNode* headnext = phead->next;
	LTNode* newnode = BuyListNode(x);

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

	newnode->next = headnext;
	headnext->prev = newnode;
}

void LTPopFront(LTNode* phead)           //头删
{
	assert(phead);
	assert(phead->next != phead);

	LTNode* pheadnext = phead->next;
	LTNode* pheadnnext = pheadnext->next;

	free(pheadnext);

	pheadnnext->prev = phead;
	phead->next = pheadnnext;
}

int LTSize(LTNode* phead)         //链表长度
{
	assert(phead);

	LTNode* cur = phead->next;
	int size = 0;
	while (cur != phead)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

LTNode* LTFind(LTNode* phead, LTDataType x)    //查找
{
	assert(phead);

	LTNode* cur = phead->next;
	while (cur != phead)
	{
		if (cur->x == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

void LTInsert(LTNode* pos, LTDataType x)        //在pos位置前插入
{
	assert(pos);

	LTNode* posprev = pos->prev;
	LTNode* newnode = BuyListNode(x);

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

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

void LTErase(LTNode* pos)           //删除pos位置
{
	assert(pos);

	LTNode* posprev = pos->prev;
	LTNode* posnext = pos->next;

	free(pos);

	posprev->next = posnext;
	posnext->prev = posprev;
}

void LTDestory(LTNode* phead)          //销毁链表
{
	assert(phead);

	LTNode* cur = phead->next;
	LTNode* curnext = cur->next;
	while (cur!= phead)
	{
		free(cur);
		cur = curnext;
		curnext = cur->next;
	}
	free(phead);
}

List.h

#pragma once

#include 
#include 
#include 

typedef int LTDataType;

typedef struct ListNode
{
	struct ListNode* next;
	struct ListNode* prev;
	LTDataType x;
}LTNode;

LTNode* LTInit();            //初始化链表

LTNode* BuyListNode(LTDataType x);                //创建新结点

void LTPrint(LTNode* phead);                  //打印

void LTPopBack(LTNode* phead);           //尾删

void LTPushBack(LTNode* phead, LTDataType x);     //尾插

void LTPushFront(LTNode* phead, LTDataType x);     //头插

int LTSize(LTNode* phead);         //链表长度

LTNode* LTFind(LTNode* phead, LTDataType x);    //查找

void LTInsert(LTNode* pos, LTDataType x);        //在pos位置前插入

void LTErase(LTNode* pos);           //删除pos位置

void LTDestory(LTNode* phead);          //销毁链表

你可能感兴趣的:(数据结构,链表,数据结构)