数据结构—双向链表

结构


带头链表里的头结点,实际为"哨兵位",哨兵位结点不存储任何有效元素,只是站在这里"放哨
的"

实现双向链表

List.h

cpp 复制代码
#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

//定义双向链表结点的结构
typedef int LTDataType;
typedef struct ListNode
{
	int data;
	struct ListNode* next;
	struct ListNode* prev;

}LTNode;


//初始化
//void LTInit(LTNode** pphead);
LTNode* LTInit();

void LTPrint(LTNode* phead);

//插入
//1.传一级还是二级,要看pphead指向的结点会不会发生改变
//2.如果发生改变,那么pphead的改变要影响实参,传二级
//3.如果不发生改变,pphead不会影响实参,传一级
void LTPushBack(LTNode* phead, LTDataType x);
void LTPushFront(LTNode* phead, LTDataType x);

//删除
void LTPopBack(LTNode* phead);
void LTPopFront(LTNode* phead);

bool LTEmpty(LTNode* phead);


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

//在pos位置之后插入结点 
void LTInsert(LTNode* pos, LTDataType x);
//删除指定位置的结点
void LTErase(LTNode* pos);
//销毁
void LTDesTroy(LTNode** pphead);

//为了保持接口的一致性,优化接口都为一级指针
void LTDesTroy2(LTNode* phead);

List.c

cpp 复制代码
#include"List.h"
LTNode* LTBuyNode(LTDataType x)
{
	LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
			exit(1);
	}
	newnode->data = x;
	newnode->next = newnode->prev = newnode;
}
//初始化
//void LTInit(LTNode** pphead)
//{
//	//创建一个头结点(哨兵位)
//	*pphead = LTBuyNode(-1);
//
//}

LTNode* LTInit()
{
	LTNode* phead = LTBuyNode(-1);
	return phead;
}

void LTPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* newnode = LTBuyNode(x);
	newnode->next = phead;
	newnode->prev = phead->prev;

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

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

	LTNode* newnode = LTBuyNode(x);

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

void LTPrint(LTNode* phead)
{
	LTNode* pcur = phead->next;
	while (pcur!=phead)
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("\n");
}

bool LTEmpty(LTNode* phead)
{
	assert(phead);
	return phead->next == phead; 
}


void LTPopBack(LTNode* phead)
{
	assert(phead);
	assert(!LTEmpty(phead));

	LTNode* del = phead->prev;
	LTNode* prev = del->prev;

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

	free(del);
	del = NULL;
}

void LTPopFront(LTNode* phead)
{
	assert(phead);
	assert(!LTEmpty(phead));

	LTNode* del = phead->next;
	del->next->prev = phead;
	phead->next = del->next; 
	free(del);
	del = NULL;

}


LTNode* LTFind(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* pcur = phead->next;
	while(pcur != phead)
	{
		if (pcur->data == x)
		{
			return pcur;
		}
		pcur = pcur->next;
	}
	return NULL;
}

void LTInsert(LTNode* pos, LTDataType x)
{
	assert(pos);

	LTNode* newnode = LTBuyNode(x);

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

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


void LTErase(LTNode* pos)
{
	assert(pos);
	pos->prev->next = pos->next;
	pos->next->prev = pos->prev;

	free(pos);
	pos = NULL;
}


void LTDesTroy(LTNode** pphead)
{
	assert(pphead && *pphead);
	LTNode* pcur = (*pphead)->next;
	while (pcur!=*pphead)
	{
		LTNode* Next = pcur->next;
		free(pcur);
		pcur = Next; 
	}
	
	 //销毁哨兵位结点
	free(*pphead);
	*pphead = NULL;
	pcur = NULL;
}


void LTDesTroy2(LTNode* phead)
{
	assert(phead);
	LTNode* pcur = phead->next;
	while (pcur != phead)
	{
		LTNode* Next = pcur->next;
		free(pcur);
		pcur = Next;
	}
	free(phead);
	phead = pcur = NULL;
}

test.c

cpp 复制代码
#include"List.h"

void ListTest01()
{
	//创建双向链表
	/*LTNode* plist = NULL;
	LTInit(&plist);*/

    LTNode*plist=LTInit();

	LTPushBack(plist, 1);
	LTPushBack(plist, 2);
	LTPushBack(plist, 3);
	LTPushBack(plist, 4);
	LTPrint(plist);

	/*LTPushFront(plist, 1);
	LTPrint(plist);
	LTPushFront(plist, 2);
	LTPrint(plist);
	LTPushFront(plist, 3);
	LTPrint(plist);
	LTPushFront(plist, 4);
	LTPrint(plist);*/

	/*LTPopBack(plist);
	LTPrint(plist);
	LTPopBack(plist);
	LTPrint(plist);
	LTPopBack(plist);
	LTPrint(plist);
	LTPopBack(plist);
	LTPrint(plist);*/



	/*LTPopFront(plist);
	LTPrint(plist);
	LTPopFront(plist);
	LTPrint(plist);
	LTPopFront(plist);
	LTPrint(plist);
	LTPopFront(plist);
	LTPrint(plist);*/

	//LTNode* pos = LTFind(plist, 2);
	/*if (pos == NULL)
	{
		printf("没有找到!\n");
	}
	else
	{
		printf("找到了!\n");
	}*/


	/*LTInsert(pos, 13);
	LTPrint(plist);*/


	/*LTErase(pos);
	LTPrint(plist);*/

	//LTDesTroy(&plist);
	LTDesTroy2(plist);
}


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

顺序表和链表的分析

相关推荐
jnrjian2 分钟前
USE_CONCAT in list OR 以及 filter Nest LOOP
数据结构·list
阿华的代码王国9 分钟前
【JavaEE】多线程编程引入——认识Thread类
java·开发语言·数据结构·mysql·java-ee
weixin_4866811431 分钟前
C++系列-STL容器中统计算法count, count_if
开发语言·c++·算法
一道秘制的小菜39 分钟前
C++第七节课 运算符重载
服务器·开发语言·c++·学习·算法
标标大人1 小时前
c语言中的局部跳转以及全局跳转
android·c语言·开发语言
代码小狗Codog2 小时前
C++独立开发开源大数计算库 CBigNum
数据结构·c++
咕噜咕嘟嘟嘟2 小时前
343. 整数拆分
数据结构·算法
WenGyyyL2 小时前
力扣最热一百题——二叉树的直径
java·c++·算法·二叉树·深度优先
sdlkjaljafdg2 小时前
vector<bool>性能测试
开发语言·c++·算法
imaima6663 小时前
数据结构——二叉树的介绍
数据结构