Estrutura de dados - lista duplamente vinculada

Prefiro confiar na minha própria força para abrir o meu futuro do que buscar o favor dos poderosos 

Diretório de artigos

O nome da função ou nome da variável de cada interface da lista vinculada de fio duplo 

Código-fonte de implementação da interface de lista duplamente vinculada

Índice rápido [arquivos de cabeçalho e declarações de função]

Implementação de interface de lista duplamente vinculada

Análise de Construção de Lista Duplamente Vinculada

Definição e inicialização de lista duplamente vinculada

Inserção e exclusão de lista duplamente vinculada


Revisão anterior:

Estrutura de dados - lista vinculada individualmente

Estrutura de Dados - Lista de Sequências

  Olá a todos, meu nome é Ji Ning.

  Este artigo apresenta uma lista vinculada com melhor desempenho do que uma única lista vinculada - uma lista duplamente vinculada, que pode implementar com mais eficiência a inserção, exclusão e pesquisa de dados.

  A primeira metade do artigo é o nome e o código-fonte correspondentes da lista duplamente vinculada, e a segunda metade do artigo é uma explicação específica da implementação da lista duplamente vinculada.

O nome da função ou nome da variável de cada interface da lista vinculada de fio duplo 

LTDDataType Renomeação de tipo de dados de lista duplamente vinculada
ListaNode estrutura de lista duplamente vinculada
LTNode Renomeação de lista duplamente vinculada
ComprarLTNode criar um nó
LTI inicializar nó
LTPrint imprimir lista duplamente vinculada
LTPushBack plugue de cauda
LTPopBack exclusão de cauda
LTPushFront plugue
LTPopFront exclusão de cabeça
Tamanho LTS Calcule o número de elementos da lista duplamente vinculada
LTFencontrar Encontre elementos da lista vinculada
LTInserir insira o nó antes da posição
LTErase Exclua o nó na posição pos

Código-fonte de implementação da interface de lista duplamente vinculada

Índice rápido [arquivos de cabeçalho e declarações de função]

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LTDataType;//重命名

typedef struct ListNode
{
	LTDataType Data;
	struct ListNode* next;
	struct ListNode* prev;
}LTNode;
LTNode* BuyLTNode(LTDataType x); //创建一个新节点
LTNode* LTInit(); //哨兵位的头结点
void LTPrint(LTNode*phead);//打印双链表
void LTPushBack(LTNode* phead, LTDataType x);//尾插
void LTPopBack(LTNode* phead);//尾删
void LTPushFront(LTNode* phead, LTDataType x);//头插
void LTPopFront(LTNode* phead);//头删
LTNode* LTFind(LTNode* phead, LTDataType x);//寻找结点
void LTInsert(LTNode*phead,LTNode* pos, LTDataType x); //在pos之前插入结点

Implementação de interface de lista duplamente vinculada

LTNode* BuyLTNode(LTDataType x)
{
	LTNode* nownode =(LTNode*)malloc(sizeof(LTNode));
	if (nownode == NULL)
	{
		perror("malloc fail");
	}
	nownode->Data = x;
	nownode->next = NULL;
	nownode->prev = NULL;
	return nownode;
}

LTNode* LTInit()
{
	LTNode* phead = BuyLTNode(0);
	phead->next = phead;
	phead->prev = phead;
	return phead;
}

void LTPushBack(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* tail = phead->prev;
	LTNode* nownode = BuyLTNode(x);
	nownode->next = phead;
	nownode->prev = tail;
	tail->next = nownode;
	phead->prev = nownode;
}

void LTPrint(LTNode* phead)
{
	assert(phead);
	printf("phead<=>");
	LTNode* cur = phead;
	while (cur->next!=phead)
	{
		printf("%d<=>", cur->next->Data);
		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 LTPushFront(LTNode* phead, LTDataType x)
{
	assert(phead);
	LTNode* first = phead->next;
	LTNode* nownode = BuyLTNode(x);
	nownode->next = first;
	nownode->prev = phead;
	phead->next = nownode;
	first->prev = nownode;
}

void LTPopFront(LTNode* phead)
{
	assert(phead);
	assert(phead->next != phead);//只有哨兵位的时候不能删除
	LTNode* first = phead->next;
	LTNode* second = first->next;
	phead->next = second;
	second->prev = phead;
	free(first);
}

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

void LTInsert(LTNode* phead, LTNode* pos, LTDataType x)
{
	assert(phead);
	assert(pos);
	LTNode* cur = phead;
	while (cur->next != pos)
	{
		cur = cur->next;
	}
	LTNode*nownode = BuyLTNode(x);
	nownode->next = pos;
	nownode->prev = cur;
	cur->next = nownode;
	pos->prev = nownode;
}

void LTErase(LTNode* phead, LTNode* pos)
{
	assert(pos&&phead);
	assert(pos->next != pos);
	assert(phead->next != phead);
	LTNode* cur = phead;
	LTNode* posNext = pos->next;
	while (cur->next != pos)
	{
		cur = cur->next;
	}
	cur->next = posNext;
	posNext->prev = cur;
	free(pos);
}

Análise de Construção de Lista Duplamente Vinculada

  Lista duplamente vinculada, em comparação com a lista vinculada única, o nó da lista duplamente vinculada tem dois domínios de ponteiro, um apontando para o próximo nó, o outro apontando para o nó anterior, a lista duplamente vinculada padrão tem um nó principal com um bit sentinela, a cabeça do bit sentinela O nó armazena o endereço do primeiro nó válido (phead->next) e o endereço do último nó válido (phead->prev).

Comparação de diagramas lógicos de lista vinculada simples e dupla

Comparação de diagramas físicos de listas vinculadas simples e duplas

Definição e inicialização de lista duplamente vinculada

  Há um campo de dados e dois campos de ponteiro na lista duplamente vinculada, um ponteiro aponta para o endereço do próximo nó e um ponteiro aponta para o endereço do nó anterior, e a estrutura da lista duplamente vinculada é renomeada novamente.

  Quando uma lista duplamente vinculada abre um novo nó, primeiro ela precisa abrir um espaço do tamanho de um nó, apontar seu próximo e NULL para vazio e, em seguida, atribuir seu valor de campo de dados a x.

Inserção e exclusão de lista duplamente vinculada

  Para deletar a lista duplamente vinculada, a primeira coisa a ficar clara é que o nó cabeça do bit sentinela não pode ser deletado, pois é o suporte estrutural de toda a lista duplamente vinculada. Ao excluir, encontre o nó anterior e o próximo nó do nó a ser excluído, aponte o próximo ponteiro do nó anterior para o próximo nó e aponte o ponteiro anterior do próximo nó para o nó anterior. Finalmente, o espaço do nó excluído é liberado.

  A inserção de uma lista duplamente vinculada, ao inserir, pode teoricamente inserir um nó em qualquer posição. Porque no momento da inicialização, os campos de ponteiro que definem os nós recém-criados estão todos vazios. Portanto, ao inserir, é necessário alterar os dois campos de ponteiro do nó inserido, apontar seu próximo ponteiro para o próximo nó e fazer com que seu ponteiro anterior aponte para o nó anterior. Da mesma forma, aponte o próximo ponteiro do nó anterior para este novo nó e aponte o ponteiro anterior do próximo ponteiro para este novo nó.

Acho que você gosta

Origin blog.csdn.net/zyb___/article/details/132063876
Recomendado
Clasificación