Bienvenue dans mon : monde
La colonne des revenus de cet article : liste chaînée
J'espère que l'article de l'auteur vous sera utile. Veuillez me corriger s'il y a des lacunes. Apprenons et communiquons ensemble !
Table des matières
Préface
Pour moi, ce blog est un lieu d'apprentissage. Tout comme mon dernier article, j'ai le soutien et la compagnie de vétérans, j'en suis très satisfait. Je continuerai à m'en tenir à cette chronique pendant 108 chapitres, tout comme mes 108 difficultés sont les pareil, mais tant que vous survivez à l’épreuve, vous obtiendrez certainement la véritable écriture ;
----------------------------- Faites tout votre possible pour le processus et soyez indifférent aux résultats.
Question 1 : Inverser une liste chaînée
Adresse : adresse jo
Idées de résolution de problèmes :
Idée : pour retourner la liste chaînée, vous pouvez d'abord créer une nouvelle liste chaînée avec un pointeur de tête pointant vers null, puis insérer la liste chaînée d'origine dans les nouveaux pointeurs un par un, puis revenir à la position de départ de la liste chaînée nouvellement créée. liste chaînée. Le long de ces lignes;
Nous devons créer une nouvelle variable pointeur pointant vers null :
Ensuite, l'étape suivante consiste à insérer l'en-tête de liste chaînée d'origine dans le nouveau nœud ;
Quelque chose à noter ici: Si vous insérez un nouveau nœud en fonction de la tête, si le pointeur pHead insère le nœud, le prochain nœud pointé par pHead sera perdu, donc ici vous devez créer un nouveau pointeur à côté pour stocker le prochain nœud pointé par pHead, donc pour récupérer;
Dans les étapes suivantes, les en-têtes suivants sont insérés dans l'ordre, il y a une étape qui nécessite votre attention ici. N'oubliez pas de laisser cur trouver le nœud suivant, puis de faire pointer le point suivant vers le nœud suivant de cur ;
Il se termine jusqu'à ce que pHhead soit vide et renvoie finalement un nouveau nœud ;
Code:
struct ListNode* ReverseList(struct ListNode* head ) {
// write code here
struct ListNode* newnode = NULL;
struct ListNode* cur = head;
//头插
while (cur) {
//为了cur能够找回下一个结点
struct ListNode* next = cur->next;
//头插
cur->next = newnode;
newnode = cur;
//cur指针找回到下一个结点
cur = next;
}
return newnode;
}
Question 2 : inverser l'intervalle spécifié dans la liste chaînée
Adresse : adresse jo
Version améliorée de la liste chaînée inversée ;
Idée :
utilisez d'abord le pointeur cur pour pointer sur la position de la tête de la liste chaînée, puis recherchez vers le bas jusqu'à ce que vous rencontriez la position de départ de l'intervalle à inverser. Le pointeur ret enregistre la position (qui sera utilisée plus tard dans le lien); puis laissez aller à En descendant, vous devez faire attention ici à utiliser le pointeur prve pour déterminer s'il y a des nœuds dans la liste chaînée d'origine. Qu'il y ait des nœuds est lié à la méthode de lien suivante (soit head, soit prve ->next). Ceci est très important ; puis commencez à partir de la position actuelle de cur . Insérez la tête (afin de revenir à la liste chaînée d'intervalle) dans un nouveau nœud de liste chaînée, jusqu'à ce que la fin de l'intervalle soit atteinte (y compris le nœud final); après cela vient l'étape de liaison, et la tête et le nouveau nœud doivent être liés, donc prve est utilisé ici à des fins de jugement;
les détails sont expliqués en détail ci-dessous :Ici, je voudrais me concentrer sur l'explication de pourquoi prve doit être défini :
Voici deux cas de test
Le premier : C’est équivalent au deuxième cas :
Le pointeur cur est créé pour pointer vers la tête, prve le premier pointe vers null et commence à trouver la position de départ de l'intervalle. Selon la valeur m (m est 2, le deuxième nœud doit être trouvé), chaque fois qu'un nœud est trouvé, cur est donné à prve( Ceci permet de déterminer si l'insertion est démarrée depuis le début. Il sera utilisé pour déterminer la méthode de liaison lors de la liaison ultérieure (expliquée en détail ci-dessus) jusqu'à ce que le début de l'intervalle soit trouvé (si m =1, puis démarrez directement à partir du premier Effectuez d'abord l'insertion de la tête, prve à ce moment pointe toujours vers vide), réglez ret à cette position et effectuez l'insertion de la tête en séquence ;
Jusqu'à ce que toutes les têtes de l'intervalle soient insérées :
Enfin, connectez-vous, laissez prve->next pointer vers newnode, ret->next pointer vers cur, et enfin revenez à head ;
Il existe également un cas de test :
Ceci est équivalent au cas 1 :
tout est inversé :
Une fois toutes les têtes insérées, pointez la tête vers le nouveau nœud.
Code:
#include <math.h>
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) {
// write code here
if (head == NULL || head->next == NULL || m == n)
return head;
struct ListNode* cur = head;
struct ListNode* newnode = NULL, * tail = NULL;
newnode = (struct ListNode*)malloc(sizeof(struct ListNode));
newnode->next = tail = NULL;
//找到m的最后一个
int count=m;
struct ListNode*prev=NULL;
while(count-->1)
{
prev=cur;
cur=cur->next;
}
struct ListNode*ret=cur;
//进行头插反转
int len=n-m+1;
while(len--)
{
struct ListNode*next=cur->next;
cur->next=newnode->next;
newnode->next=cur;
cur=next;
}
//链接
if(prev==NULL)
{
head=newnode->next;
ret->next=cur;
}
else {
prev->next=newnode->next;
ret->next=cur;
}
return head;
}
Question 3 : Déterminer si une liste chaînée est une structure palindrome
Adresse : adresse jo
- Nous devons d’abord savoir ce qu’est une structure palindrome :
- comme
Palindrome pair : 1 2 2 1
Palindrome impair : 1 2 3 2 1
Idées de résolution de problèmes :
Idée : Trouvez le nœud du milieu, puis inversez tous les nœuds après le nœud du milieu. Ensuite, comparez les valeurs du rever du nœud du milieu renvoyé avec le premier nœud de la liste chaînée dans l'ordre. S'ils sont égaux, continuez jusqu'à ce qu'ils pointer versLe noeud central rever pointe vers null;
Ici, nous utiliserons la fonction qui renvoie le nœud intermédiaire ; et la fonction d'inversion d'une liste chaînée (qui est la première question de cet article) ; nous avons déjà écrit ces deux-là : les vétérans peuvent le vérifier : Return to the middle node ;
Code:
struct ListNode* middleNode(struct ListNode* head) {
// write code here
//返回中间结点的地址
//设置快慢指针
struct ListNode* sur = head, * dst = head;
//当dst指针为空或dst指向的next为空就停下
while (dst && dst->next) {
sur = sur->next;
dst = dst->next->next;
}
return sur;
}
//反转一串链表并返回该链表的头地址
struct ListNode* ReverseList(struct ListNode* head ) {
// write code here
struct ListNode* newnode=NULL;
struct ListNode* cur = head;
while (cur) {
struct ListNode* next = cur->next;
//头插
cur->next = newnode;
newnode = cur;
cur = next;
}
return newnode;
}
//实现判断是否为回文结构
bool isPail(struct ListNode* head ) {
// write code here
struct ListNode* mid = middleNode(head);
struct ListNode* rever = ReverseList(mid);
while (rever) {
if (head->val != rever->val) {
return false;
}
rever = rever->next;
head = head->next;
}
return true;
}
Résumer
Pour chaque question, il est peut-être encore possible d'optimiser. S'il existe une meilleure méthode, vous pouvez en discuter ensemble dans la zone de commentaires. À l'avenir, à mesure que les réserves de connaissances de l'enfant augmenteront, l'enfant l'optimisera certainement. ! !
À la fin : merci pour le soutien
Ce que je veux aussi vous dire, c'est :
---------- Mettez-vous à fond dans le processus et soyez indifférent aux résultats. C'est
aussi ce que je me dis.