Table des matières
Le concept et la structure de la pile :
Le concept et la structure de la file d'attente :
Implémentation de la file d'attente :
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 dynamiquetypedef int STDataType ;typedef struct Stack{STDataType * _a ;int _top ; // Haut de la pileint _capacity ; // capacité} Pile ;// Initialise la pilevoid StackInit ( Stack * ps );// Pousser dans la pilevoid StackPush ( Stack * ps , STDataType data );// sortvoid StackPop ( Stack * ps );// Récupère l'élément supérieur de la pileSTDataType StackTop ( Stack * ps );// Récupère le nombre d'éléments valides dans la pileint 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 videint PileVide ( Pile * ps );// Détruit la pilevoid 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 :
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'attentetypedef struct QListNode{struct QListNode * _pNext ;QDataType _data ;} QNode ;// La structure de la file d'attentetypedef struct file d'attente{QNode * _front ;QNode * _rear ;} file d'attente ;// Initialise la file d'attentevoid QueueInit ( File d'attente * q );// La fin de la file entre dans la filevoid QueuePush ( Queue * q , QDataType data );// La tête de la file d'attente est hors de la file d'attentevoid QueuePop ( File d'attente * q );// Récupère l'élément en tête de la file d'attenteQDataType QueueFront ( File d'attente * q );// Récupère l'élément de queue de la file d'attenteQDataType QueueBack ( File d'attente * q );// Récupère le nombre d'éléments valides dans la file d'attenteint 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 videint File d'attente vide ( File d'attente * q );// détruit la file d'attentevoid 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 !