Structures de données : piles et files d'attente (super détaillées)

Table des matières

modifier

empiler:

Le concept et la structure de la pile :

 Implémentation de la pile :

file d'attente:

Le concept et la structure de la file d'attente :

 Implémentation de la file d'attente :

Connaissances approfondies :

 Ce qui précède est mon opinion personnelle et mon analyse de l'apprentissage des tableaux linéaires. Bienvenue à tous pour discuter dans la zone de commentaires !

Merci pour les gars à trois connexions en un clic ! Merci pour les gars à trois connexions en un clic ! Merci pour les gars à trois connexions en un clic !


empiler:

Le concept et la structure de la pile :

        Pile : une liste linéaire spéciale qui permet uniquement l'insertion et la suppression d'éléments à une extrémité fixe . La fin des opérations d'insertion et de suppression de données est appelée le haut de la pile et l'autre extrémité est appelée le bas de la pile . Les éléments de données dans la pile suivent le principe de LIFO (Last In First Out). Généralement utilisé dans 1. la mise en file d'attente d'équité (machine à dessiner des numéros) ; 2. BFS (traversée en largeur d'abord).

Pousser la pile : L'opération d'insertion de la pile est appelée pousser/pousser/pousser, et les données entrantes se trouvent en haut de la pile.

Popping : L'opération de suppression de la pile est appelée popping. Les données de sortie sont également en haut de la pile.

 Implémentation de la pile :

        L'implémentation de la pile peut généralement être réalisée à l'aide d'un tableau ou d'une liste chaînée.Toute proportionnalité , la structure du tableau est meilleure . Parce que le coût d'insertion des données à la fin du tableau est relativement faible . La queue d'insertion de la chaîne doit mobiliser plus de données , et il y a plus de consommation dans le processus .

// Prise en charge de la pile à croissance dynamique
typedef int STDataType ;
typedef struct Stack
{
STDataType * _a ;
int _top  ; // Haut de la pile
int _capacity  ; // capacité
} Pile  ;
// Initialise la pile
void StackInit ( Stack * ps );
// Pousser dans la pile
void StackPush ( Stack * ps , STDataType data );
// sort
void StackPop ( Stack * ps );
// Récupère l'élément supérieur de la pile
STDataType StackTop ( Stack * ps );
// Récupère le nombre d'éléments valides dans la pile
int StackSize ( Pile * ps );
// Vérifie si la pile est vide, renvoie un résultat non nul si elle est vide, renvoie 0 si elle n'est pas vide
int PileVide ( Pile * ps );
// Détruit la pile
void StackDestroy ( Stack * ps );

 // Initialise la pile


//初始化
void SLInit(SL* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

//Pousser dans la pile

//入栈
void SLPush(SL* ps, STDataType x)
{
	assert(ps);
	//栈顶=容量说明需要扩容
	if (ps->capacity == ps->top)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->capacity = newcapacity;
		ps->a = tmp;
	}
	ps->a[ps->top] = x;
	//后缀++方便下一次入栈和打印栈顶
	ps->top++;
}

// sort

//出栈
void SLPop(SL* ps)
{
	assert(ps);
	//为空情况“0”
	assert(ps->top > 0);
	//
	--ps->top;
}

// Récupère l'élément supérieur de la pile

//获得栈顶元素
STDataType SLTTop(SL* ps)
{
	assert(ps);
	//为空情况“0”
	assert(ps->top > 0);
	int n = (ps->top) - 1;
	return ps->a[n];
}

 // Récupère le nombre d'éléments valides dans la pile

//获取栈中有效元素个数
int SLSize(SL* ps)
{
	assert(ps);
	return ps->top;
}

// Détruit la pile

//销毁栈
void SLDestroy(SL* ps)
{
	assert(ps);
	//开辟数组优势:一次全部释放
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

// Vérifie si la pile est vide, renvoie un résultat différent de zéro si elle est vide et renvoie 0 si elle n'est pas vide

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool SLEmpty(SL* ps)
{
	assert(ps);
	//为“0”说明为NULL
	if (ps->top == 0)
	{
		return true;
	}
	return false;
}

file d'attente:

Le concept et la structure de la file d'attente :

         Queue : Une table linéaire spéciale qui permet uniquement d'insérer des données à une extrémité et de supprimer des données à l'autre extrémité . La file d'attente a FIFO (First In First Out).
Dans la file d'attente : la fin de l'opération d'insertion est appelée la queue de la file d'attente ; 
Hors de la file d'attente : la fin de l'opération de suppression est appelée la tête de la file d'attente.

 Implémentation de la file d'attente :

        Les files d' attente peuvent également être implémentées dans la structure des tableaux et des listes chaînées Il est préférable d' utiliser la structure des listes chaînées , car si vous utilisez la structure des tableaux , l' efficacité du retrait de la file d' attente et de la sortie des données en tête du tableau sera relativement faible .

// Structure en chaîne : représente la file d'attente
typedef struct QListNode
{
struct QListNode * _pNext ;
QDataType _data ;
} QNode ;
// La structure de la file d'attente
typedef struct file d'attente
{
QNode * _front ;
QNode * _rear ;
} file d'attente  ;
// Initialise la file d'attente
void QueueInit ( File d'attente * q );
// La fin de la file entre dans la file
void QueuePush ( Queue * q , QDataType data );
// La tête de la file d'attente est hors de la file d'attente
void QueuePop ( File d'attente * q );
// Récupère l'élément en tête de la file d'attente
QDataType QueueFront ( File d'attente * q );
// Récupère l'élément de queue de la file d'attente
QDataType QueueBack ( File d'attente * q );
// Récupère le nombre d'éléments valides dans la file d'attente
int QueueSize ( File d'attente * q );
// Vérifie si la file d'attente est vide, renvoie un résultat non nul si elle est vide, renvoie 0 si elle n'est pas vide
int File d'attente vide ( File d'attente * q );
// détruit la file d'attente
void QueueDestroy ( File d'attente * q );

//initialisation

//初始化
void QueueInit(Que* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

//Mise en file d'attente

//入列
void QueuePush(Que* pq, Qdatatype x)
{
	assert(pq);
	//开辟队列结构动态内存
	Qnode* newnode = (Qnode*)malloc(sizeof(Qnode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	//第一次或N+1次
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

// retirer de la file d'attente

//出列
void QueuePop(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	
	if (pq->head->next == NULL)
	{
		//就剩下一个
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		//剩下两个及以上
		Que * del = pq->head;
		pq->head = pq->head->next;
		free(del);
		}

	pq->size--;
}

// Récupère l'élément en tête de la file d'attente 

// 获取队列头部元素 
Qdatatype QueueFront(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

// Récupère l'élément de queue de la file d'attente 

// 获取队列队尾元素 
Qdatatype QueueBack(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

// Récupère le nombre d'éléments valides dans la file d'attente 

// 获取队列中有效元素个数 
int QueueSize(Que* pq)
{
	assert(pq);

	return pq->size;
}

// Vérifie si la file d'attente est vide, renvoie un résultat non nul si elle est vide et renvoie 0 si elle n'est pas vide 

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Que* pq)
{
	assert(pq);

	return pq->head == NULL;
}

//détruire

//销毁
void QueueDestroy(Que* pq)
{
	assert(pq);
	while (pq->head)
	{
		Que* del = pq->head->next;
		free(pq->head);
		pq->head = del;
		pq->size--;
	}

	pq->head = pq->tail = NULL;
}

Connaissances approfondies :

        Les files d'attente conviennent à la mise en œuvre à l'aide de listes chaînées. De faux problèmes de débordement se produiront lors de l'utilisation de structures séquentielles (c'est-à-dire des espaces continus fixes). Par conséquent, les grands noms ont conçu des files d'attente circulaires. Les files d'attente circulaires sont conçues pour résoudre le problème des faux débordements dans structures séquentielles.

        File d'attente circulaire : En pratique, on utilise parfois une file d'attente appelée file d'attente circulaire. Par exemple, lorsque le cours sur le système d'exploitation explique le modèle producteur-consommateur, une file d'attente circulaire peut être utilisée. Une file d'attente circulaire peut être implémentée à l'aide d'un tableau ou d'une liste chaînée circulaire.

 

        En même temps, il pointe vers une position qui est vide , et lorsque la prochaine position d'arrière (queue) est avant (tête), cela signifie qu'il a été rempli.Voici un espace supplémentaire pour juger s'il est plein ou pas! ! !

 Ce qui précède est mon opinion personnelle et mon analyse de l'apprentissage des tableaux linéaires. Bienvenue à tous pour discuter dans la zone de commentaires !

Merci pour les gars à trois connexions en un clic ! Merci pour les gars à trois connexions en un clic ! Merci pour les gars à trois connexions en un clic !

                                              

Je suppose que tu aimes

Origine blog.csdn.net/weixin_71964780/article/details/132274646
conseillé
Classement