Le deuxième chapitre de la liste chaînée

insérer la description de l'image ici

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 !


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


insérer la description de l'image ici
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 :

insérer la description de l'image ici

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;
insérer la description de l'image ici

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 ;

insérer la description de l'image ici

Il se termine jusqu'à ce que pHhead soit vide et renvoie finalement un nouveau nœud ;

insérer la description de l'image ici

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


insérer la description de l'image ici

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 :

insérer la description de l'image ici

Voici deux cas de test

Le premier : C’est équivalent au deuxième cas :

insérer la description de l'image ici

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 ;

insérer la description de l'image ici

Jusqu'à ce que toutes les têtes de l'intervalle soient insérées :

insérer la description de l'image ici
Enfin, connectez-vous, laissez prve->next pointer vers newnode, ret->next pointer vers cur, et enfin revenez à head ;
insérer la description de l'image ici

Il existe également un cas de test :

insérer la description de l'image ici

Ceci est équivalent au cas 1 :
tout est inversé :

insérer la description de l'image ici

Une fois toutes les têtes insérées, pointez la tête vers le nouveau nœud.

insérer la description de l'image ici

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


insérer la description de l'image ici

  • 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 ;

insérer la description de l'image ici

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.

Je suppose que tu aimes

Origine blog.csdn.net/m0_66780695/article/details/132322161
conseillé
Classement