"Aha Algorithm" Chapitre 2 - Liste chaînée de la pile de files d'attente

insérez la description de l'image ici


avant-propos

Dans la section précédente, nous avons appris le tri rapide du tri à bulles dans l'algorithme de tri. Le principal contenu d'apprentissage de cette section est donc la connaissance de la structure de données pertinente de la liste liée de la pile de files d'attente.


1. Connaissance de base de la structure des données (connaissance des connexions)

Sur la base de l'étude de ce livre, certains noobs algorithmiques et même des élèves du primaire apprennent, je voudrais donc ajouter quelques connaissances de base sur la structure des données à tout le monde, afin que chacun puisse mieux comprendre les connaissances de cette section

1. Que signifie "premier entré, dernier sorti" dans la pile ?

La pile a deux opérations principales pour la gestion des données :

  1. Pousser la pile : L'opération d'insertion de la pile est appelée pousser/pousser/pousser, et la pile est poussée depuis le haut de la pile.
  2. Popping : L'opération de suppression de la pile est appelée popping et la pile est extraite du haut de la pile.
    insérez la description de l'image ici

2. La définition de la pile
La pile ne permet que l'opération d'insertion et de suppression d'éléments dans une section fixe. L'extrémité qui effectue les opérations d'insertion et de suppression de données est appelée le haut de la pile, et l'extrémité qui n'effectue pas d'opérations est appelée le bas de la pile. Les éléments de la pile suivent le principe du dernier entré, premier sorti (LIFO - Last En premier sorti). C'est-à-dire, premier entré, dernier sorti, dernier entré, premier sorti

3.
La métaphore de l'image de la différence entre une pile et une file d'attente est qu'une pile est comme une balle, et le premier à entrer est abattu à la fin, tandis que la file d'attente est à l'intérieur de la file d'attente, premier arrivé, premier servi.

Après avoir lu ceux-ci, si vous voulez en savoir plus sur les files d'attente et les piles, vous pouvez lire mes deux blogs ci-dessous pour apprendre
[structure de données] expliquer les files d'attente en termes simples avec mille mots (code original joint | explication super détaillée)

【Structure de données】 Pile d'explications approfondies en mille mots (avec code d'origine | explication super détaillée)

Deux, la file d'attente

définition de la file d'attente

队列:Une table linéaire spéciale qui permet uniquement d'insérer des opérations de données à une extrémité et de supprimer des opérations de données à l'autre extrémité . La file d'attente a le premier entré, premier sorti

FIFO(First In First Out)Dans la file : la fin de l'opération d'insertion est appelée la queue de la file Hors de la file : la fin de l'opération de suppression est appelée la tête de la file

Le diagramme de structure de données est le suivant :
insérez la description de l'image ici
la tête de la file d'attente (tête) supprime les données, appelées "hors de la file d'attente" et la
queue de la file d'attente (queue) insère des données, appelées "entrée dans la file d'attente"
. Lorsqu'il n'y a pas d'élément dans la file (head == tail), on parle de file vide

description du sujet

Au début du nouveau semestre, Xiao Hum et Xiao Ha étaient assis à la même table, puis Xiao Hun a demandé à Xiao Ha quel était son numéro QQ, mais Xiao Ha n'a pas donné facilement son numéro QQ aux autres, alors il a donné une chaîne de nombres mystérieux, mais les nombres sont des nombres réguliers

La règle est de supprimer d'abord le premier nombre, puis de mettre le deuxième nombre à la fin de la chaîne, puis de supprimer le troisième nombre et de mettre le quatrième nombre à la fin...

Jusqu'à ce qu'il reste le dernier numéro, le dernier numéro est également supprimé. Relier les numéros supprimés ensemble est le numéro QQ de Xiaoha. La chaîne de chiffres que Xiaoha a cryptée pour lui est "920430714", quel est le numéro QQ de Xiaoha ?

idées de résolution de problèmes
insérez la description de l'image ici
insérez la description de l'image ici

L'opération de suppression d'un numéro en tête d'équipe est head++
L'opération d'ajout d'un numéro en fin d'équipe est q[tail]=x , tail++

Maintenant, il y a 9 numéros, après avoir mis 9 numéros dans la file d'attente, tête == 1, queue == 10, à ce moment le nombre entre la tête et la queue est le numéro "valide" dans la file d'attente actuelle

spectacle de code comme ci-dessous

//方法一:
#include<iostream>
using namespace std;
int main()
{
    
    
	int q[102]={
    
    0,6,3,1,7,5,8,9,2,4},head,tail;
	//初始化队列
	head=1;//指向第一个
	tail=10;//指向最后一个的下一个
	while(head<tail)//队列不为空
	{
    
    
		//打印队首
		printf("%d ",q[head]);
		head++;//队首出队 
		
		//先将新队首得数添加到队尾
		q[tail]=q[head];
		tail++;
		//再将队首出队 
		head++; 
	}
	return 0;
}

exemple d'instance

输入:6 3 1 7 5 8 9 2 4
输出:6 1 5 9 4 7 2 8 3

Encapsulez les trois éléments de base de la file d'attente (un tableau et deux variables) dans un type de structure. En fait, la première méthode ne devrait pas être utilisée dans le concours d'algorithmes.

//方法二

#include<iostream>
using namespace std;
struct queue
{
    
    
	int data[100];
	int head;
	int tail;
};
int main()
{
    
    
	struct queue q;
	int i;
	//初始化队列
	q.head=1;
	q.tail=1;
	for(int i=1;i<=9;++i)
	{
    
    
		//依次向队列插入9个数
		cin>>q.data[q.tail];
		q.tail++; 
	}
	while(q.head<q.tail)
	{
    
    
		//打印队首并将队首出队
		cout<<q.data[q.head]<<" ";
		q.head++;
		q.data[q.tail]=q.data[q.head];
		q.tail++;
		q.head++; 
	}
	return 0;
}

Trois, la pile

Pile dernier entré premier sorti, il y a de nombreux exemples dans la vie :

1. Pour parcourir la page Web et revenir à une page Web précédente, vous devez cliquer sur le bouton de retour étape par étape
2. Chargez la balle dans le chargeur, la dernière balle chargée est la première à être tirée ou la première à être éjectée
3 . Et Par exemple, dans un petit seau, le diamètre du petit seau ne peut contenir qu'une balle et mettre les balles 2, 1 et 3 dans l'ordre. Si vous voulez retirer la balle 2, vous devez d'abord retirer la balle 3, puis sortez la balle 1, et enfin Afin de prendre la balle n ° 2 qui a été mise en premier

insérez la description de l'image ici
Le principal problème dans cette section de la pile est de juger la chaîne de palindrome. En fait, j'ai écrit ce sujet dès que j'apprenais le langage C. Niuke a ce sujet.

Idées de résolution de problèmes :
divisez la chaîne en deux, définissez le point médian sur le milieu, poussez la chaîne à gauche du milieu dans la pile, puis laissez les lettres de la pile correspondre aux caractères après le milieu après avoir été poussées dans la pile, et définir Top , chaque fois que la correspondance est réussie Top–, enfin vérifier si Top vaut 0, si c'est 0, cela signifie que c'est un palindrome, sinon ce n'est pas un caractère palindrome

Opération d'empilement : s[++top] = a[i] ;
obtenir la longueur de chaîne len à strlen(a), mid = len / 2 - 1 ;

code afficher comme ci-dessous:

#include<iostream>
#include<cstring>
using namespace std;

char a[110],s[110];
int len,mid,next,top;

int main()
{
    
    
	cin.get(a,110);//读入字符串 
	len=strlen(a);//求字符串长度 
	mid=len/2-1;//求字符串的中点
	//入栈操作
	for(int i=0;i<=mid;++i)
	{
    
    
		s[++top]=a[i];
	}
	//判断字符串的长度是奇数还是偶数,并找出需要进行字符匹配的下标
	if(len%2==0) next=mid+1;
	else next=mid+2; 
	
	//开始匹配
	for(int i=next;i<=len-1;++i)
	{
    
    
		if(a[i]!=s[top]) break;
		top--;
	}
	
	if(top==0)	cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
	return 0;
}

exemple d'instance

输入:nihaooahin
输出:Yes

Expliquons l'idée de ne pas utiliser la pile :

arithmétique à double pointeur, pointant respectivement vers les côtés gauche et droit de la chaîne pour aller l'un vers l'autre, correspondance un par un, lorsque les caractères pointés par les deux pointeurs sont différents, sortie NON, lorsque les deux pointeurs se rencontrent ou se croisent, sortie Oui

code afficher comme ci-dessous:

#include<iostream>
#include<cstring>
using namespace std;
char a[110];
int is_huiwen(int left,int right)
{
    
    
	while(left<right)
	{
    
    
		if(a[left++]!=a[right--]) return 0;
		else continue;
	}
	return 1;
}
int main()
{
    
    
	cin.get(a,110);
	int right=strlen(a)-1;
	if(is_huiwen(0,right)) cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
	return 0;
}

4. Liste liée

Définition de liste chaînée

链表Il s'agit d'une structure de stockage 物理存储结构supérieure 非连续et supérieure, et les éléments de données sont réalisés via l'ordre des liens .非顺序逻辑顺序链表中的指针

insérez la description de l'image ici

Implémenter la liste chaînée

Utilisez des pointeurs et la fonction d'allocation de mémoire dynamique malloc pour obtenir

1. Pour les pointeurs
, voir le blog pour plus de détails : Langage C—débutants des pointeurs—résumé

2. La fonction malloc
1 malloc(sizeof(int))
est équivalente à malloc(4); appliquer pour allouer un espace mémoire de 4 octets à partir de la mémoire
2 Maintenant, nous avons appliqué avec succès un espace de 4 octets à partir de la mémoire pour stocker un entier, comment opérer sur cet espace ?
Cela nécessite un pointeur pour pointer vers cet espace, c'est-à-dire pour stocker la première adresse de cet espace
3 (int *) le type de retour de la fonction malloc () est de type void *, indiquant un type de pointeur indéterminé, qui peut être converti en n'importe quel autre type de pointeur , ici nous devons forcer la conversion en entier, donc c'est (int *)

int *p; //定义指针p
p = (int *)malloc(sizeof(int));

La fonction malloc() s'applique dynamiquement pour l'espace :

#include<iostream>
#include<cstdlib> //malloc()
using namespace std;
int main()
{
    
    
    int *p; //定义指针p
    //指针p获取动态分配的内存地址
    p = (int *)malloc(sizeof(int));
    *p = 10; //向p所指向的内存存入10
    cout<<*p<<endl; //输出p指向内存中的值
    return 0;
}

Chaque nœud est composé de deux parties. La partie gauche stocke des valeurs spécifiques et la partie droite stocke l'adresse du nœud suivant (appelé le pointeur successeur). Ici, nous définissons un type de structure pour stocker ce nœud. Voir mon blog sur la structure de données [ données]
insérez la description de l'image ici
pour plus de détails Structure] 10 000 caractères expliquent la liste à liaison unique en termes simples (avec code d'origine | explication super détaillée)

Problème : Créer une liste chaînée

#include<iostream>
#include<cstdlib> //malloc()
using namespace std;
struct node
{
    
    
    int data;
    struct node *next;
};
int main()
{
    
    
    struct node *head, *p, *q, *t;
    int i, n, a;
    cin>>n;
    head = NULL; //头指针初始为空
    for(i = 1; i <= n; ++i) {
    
    
        cin>>a;
        //动态申请一个空间存放节点,临时指针p指向这个节点
        p = (struct node *)malloc(sizeof(struct node));
        p->data = a; //数据存储到数据域
        p->next = NULL; //后继指针指向空
        if(head == NULL)
            head = p; //第一个节点让头指针指向
        else
            q->next = p; //否则上一节点后继指针指向当前节点
        q = p; //上一节点指针指向当前节点
    }
 
    //输出链表中所有数
    t = head;
    while(t != NULL) {
    
    
        cout<<t->data<<" ";
        t = t->next; //继续下一节点
    }
    return 0;
}

Problème : insertion de données

#include<iostream>
#include<cstdlib> //malloc()
using namespace std;
 
//创建一个结构体表示节点
struct node
{
    
    
    int data;
    struct node *next;
};
 
int main()
{
    
    
    struct node *head, *p, *q, *t; //p,q,t都是临时指针
    int i, n, a;
    cin>>n; //n个数
    head = NULL; //头指针初始为空
    for(i = 1; i <= n; ++i) {
    
    
        cin>>a;
        //动态申请空间存放一个节点,临时指针p指向该节点
        p = (struct node *)malloc(sizeof(struct node));
        p->data = a;
        p->next = NULL; //当前节点下一节点为空
        if(head == NULL)
            head = p; //若为第一个创建的,头指针指向该节点
        else
            q->next = p; //上一节点后继指针指向当前节点
        q = p; //指针q指向当前节点
    }
 
    cin>>a; //待插入的数
    t = head; //从链表头部开始遍历
    while(t != NULL) {
    
    
        if(t->next == NULL || t->next->data > a) {
    
    
            p = (struct node *)malloc(sizeof(struct node));
            p->data = a;
            //新增节点后继指针指向当前节点后继指针所指向的节点
            p->next = t->next;
            t->next = p; //当前节点后继指针指向新增节点
            break; //插入完退出循环
        }
        t = t->next; //继续下一节点
    }
 
    //输出链表所有数
    t= head;
    while(t != NULL) {
    
    
        cout<<t->data<<" ";
        t = t->next; //继续下一节点
    }
    return 0;
}

Résumer

Allez d'abord ici et continuez à ajouter plus tard

Je suppose que tu aimes

Origine blog.csdn.net/congfen214/article/details/131754463
conseillé
Classement