Structure de données - une liste liée circulaire bidirectionnelle avec le nœud principal d'une table linéaire

Préface

Il existe de nombreux types de listes chaînées (selon leader ou non, cyclique ou non cyclique, etc.), mais nous nous concentrons sur seulement deux, dont l'une a une structure très simple est une liaison sans tête unidirectionnelle non cyclique liste . Voir son fonctionnement

Structure de données-liste de table linéaire

Ce type de résultat n'est fondamentalement pas utilisé dans le développement, car une structure simple signifie souvent une opération compliquée , comme les questions d'OJ dans la recherche d'emploi. Fondamentalement, la liste chaînée utilise cette structure. Pour ceux qui s'intéressent à ces questions d'OJ, voir

Liste liée classique

L'autre est la structure la plus complexe de la liste chaînée - une liste chaînée circulaire bidirectionnelle avec un nœud d'en-tête.
Insérez la description de l'image ici
Cette structure semble être très compliquée, mais son fonctionnement est très simple, comme l'opération d'insertion de queue la plus couramment utilisée, et sa complexité temporelle Il est O (1) . Dans le même temps, la liste dans la STL en C ++ est cette structure.
Pour cette structure, parce qu'elle a un nœud principal, elle peut faire en sorte que la plupart des opérations utilisent le même code, comme l'insertion d'en-tête, etc., et parce qu'elle est cyclique, donc pratique pour l'insertion de la queue et d'autres opérations

Faites attention au jugement de la liste vide

head->prev=head
haed->next=head

atteindre

(1) Définition de la structure

typedef struct DListNode
{
    
    
	struct ListNode* next;//指向前一个结点
	struct ListNode* prev;//指向后一个结点
	DLdatatype val;
}DListNode;

(2) Fonctions de base

1: Appliquer pour un nœud ,
Insérez la description de l'image ici
2: Imprimer
Faites attention à l'impression, il n'y a pas de NULL dans cette structure, c'est-à-dire que la condition pour juger de la fin ne peut pas être NULL, mais la tête
Insérez la description de l'image ici

(3) Réalisation de l'opération

1: insertion de la queue
Insérez la description de l'image ici
Insérez la description de l'image ici
2: suppression de la queue
Insérez la description de l'image ici
Insérez la description de l'image ici
3: insertion de la tête
Insérez la description de l'image ici
Insérez la description de l'image ici

Insérez la description de l'image ici
4: suppression de l'en-tête
Insérez la description de l'image ici
5: recherche du nœud

Insérez la description de l'image ici
6: Insérer
Insérez la description de l'image ici
à n'importe quelle position ( après un nœud) 7: Insérer à n'importe quelle position (avant un nœud)
Insérez la description de l'image ici
8: Supprimer à n'importe quelle position
Insérez la description de l'image ici
9: Détruire
Insérez la description de l'image ici

tester

Insérez la description de l'image ici

Code

Dlist.h

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

typedef int DLdatatype;
typedef struct DListNode
{
    
    
	struct DListNode* next;
	struct DListNode* prev;
	DLdatatype val;

}DListNode;

void printlist(DListNode* head);//打印
DListNode* CreatNode(DLdatatype x);//申请结点

void ListPushBack(DListNode* head, DLdatatype x);//尾插
void ListPopBack(DListNode* head);//尾删
void listPushFront(DListNode* head, DLdatatype x);//头插
void listPopFront(DListNode* head);//头删

DListNode* find(DListNode* head, DLdatatype x);//找某个元素
void listinseret_behind(DListNode* head,DLdatatype pos, DLdatatype x);//任意位置插入(后面)
void listinseret_front(DListNode* head,DLdatatype pos, DLdatatype x);//任意位置插入(前面)
void listdelete(DListNode* head,DLdatatype pos);//任意位置删除

void listdestory(DListNode* head);//链表销毁

Dlist.c

#include "DList.h"

DListNode* CreatNode(DLdatatype x)
{
    
    
	DListNode* NewNode = (DListNode*)malloc(sizeof(DListNode));
	NewNode->val = x;
	NewNode->next = NULL;
	NewNode->prev = NULL;
	return NewNode;
}

void printlist(DListNode* head)
{
    
    
	assert(head);
	DListNode* cur = head->next;
	while (cur!=head)
	{
    
    
		printf("%d->", cur->val);
		cur = cur->next;
	}
	if (head->next == head)
		printf("NULL");

}

void ListPushBack(DListNode* head, DLdatatype x)
{
    
    
	assert(head);
	DListNode* NewNode=CreatNode(x);

	NewNode->next = head;
	(head->prev)->next = NewNode;
	NewNode->prev = head->prev;
	head->prev = NewNode;
}

void ListPopBack(DListNode* head)
{
    
    
	assert(head);
	assert(head->next != head);//如果链表为空,断言
	DListNode* delelte = head->prev;
	head->prev = delelte->prev;
	delelte->prev->next = head;
	free(delelte);
}

void listPushFront(DListNode* head, DLdatatype x)
{
    
    
	assert(head);
	DListNode* NewNode = CreatNode(x);

	NewNode->next = head->next;
	NewNode->prev = head;
	head->next->prev = NewNode;
	head->next = NewNode;

}
void listPopFront(DListNode* head)
{
    
    
	assert(head);
	assert(head->next != head);
	DListNode* first = head->next;
	first->next->prev = head;
	head->next = first->next;
	free(first);

}

DListNode* find(DListNode* head, DLdatatype x)
{
    
    
	assert(head);
	DListNode* cur = head->next;
	while (cur->next != head && cur->val != x)
	{
    
    
		cur = cur->next;
	}
	if (cur->next == head && cur->val!=x)
	{
    
    
		return NULL;//未找到
	}
	else
	{
    
    
		return cur;//否则返回
	}

}

void listinseret_behind(DListNode* head, DLdatatype pos, DLdatatype x)
{
    
    
	assert(head);
	DListNode* insert = find(head, pos);
	if (insert == NULL)
	{
    
    
		printf("%d不存在\n", pos);
	}
	else
	{
    
    
		DListNode* NewNode = CreatNode(x);
		NewNode->next = insert->next;
		NewNode->prev = insert;
		insert->next->prev = NewNode;
		insert->next = NewNode;
	}

}

void listinseret_front(DListNode* head, DLdatatype pos, DLdatatype x)
{
    
    
	assert(head);
	DListNode* insert = find(head, pos);
	if (insert == NULL)
	{
    
    
		printf("%d不存在\n", pos);
	}
	
	{
    
    
		DListNode* NewNode = CreatNode(x);
		NewNode->next = insert;
		NewNode->prev = insert->prev;
		NewNode->prev->next = NewNode;
		insert->prev = NewNode;
	
	}

}

void listdelete(DListNode* head, DLdatatype pos)
{
    
    
	assert(head);
	assert(pos != head);
	DListNode* delete = find(head, pos);
	if (delete == NULL)
	{
    
    
		printf("%d不存在\n", pos);
	}
	else
	{
    
    
		delete->prev->next = delete->next;
		delete->next->prev = delete->prev;
		free(delete);
	}

}

void listdestory(DListNode* head)
{
    
    
	assert(head);
	DListNode* cur = head->next;
	DListNode* pre = NULL;
	while (cur->next != head)
	{
    
    
		pre = cur;
		cur = cur->next;
		free(pre);
		
	}
	head->next =head;
	head->prev = head;

}

test.c

#include "DList.h"

void test()
{
    
    
	DListNode* head=(DListNode*)malloc(sizeof(DListNode));
	head->prev = head;
	head->next = head;
	printf("尾插4个结点\n");
	ListPushBack(head, 1);
	ListPushBack(head, 2);
	ListPushBack(head, 3);
	ListPushBack(head, 4);
	printlist(head);
	printf("\n");
	printf("\n");

	printf("尾删2个结点\n");
	ListPopBack(head);
	ListPopBack(head);
	printlist(head);
	printf("\n");
	printf("\n");

	printf("头插4个结点\n");
	listPushFront(head, 5);
	listPushFront(head, 6);
	listPushFront(head, 7);
	listPushFront(head, 8);
	printlist(head);
	printf("\n");
	printf("\n");

	printf("头删2个结点\n");
	listPopFront(head);
	listPopFront(head);
	printlist(head);
	printf("\n");
	printf("\n");

	printf("在5后面插入7\n");
	listinseret_behind(head, 5, 7);
	printlist(head);
	printf("\n");
	printf("\n");

	printf("删除1\n");
	listdelete(head, 1);
	printlist(head);
	printf("\n");
	printf("\n");


	printf("销毁\n");
	listdestory(head);
	printlist(head);
	printf("\n");
	printf("\n");

}

int main()
{
    
    
	test();
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_39183034/article/details/113136845
conseillé
Classement