La permutation de nœuds en double liste chaînée
Je suis en train de mettre en œuvre une fonction swap de deux nœuds de mon double liste chaînée, afin de trier le contenu du répertoire courant. Mais ma fonction semble "supprimer" certains éléments de ma liste, voici le code :
void node_swap(struct s_node *left, struct s_node *right)
{
struct s_node *tmp;
tmp = left->prev;
if (tmp)
{
tmp->next = right;
right->prev = tmp;
}
else
right->prev = NULL;
left->prev = right;
left->next = right->next;
right->next = left;
right->next->prev = left->prev;
}
Je ne vois pas où est le mal dans tout cela ?
- Pourquoi ne pas juste changer les données?
- Pourquoi ne pouvez-vous pas juste changer le contenu des données des deux nœuds?
- J'ai pu, mais n'est-ce pas de cette façon plus lente ?
- Dépend des données. Quel est votre de données de type?
- Mes nœuds sont composées d'un char *nom, et les deux pointeurs *prev, *suivant.
- Puis il suffit de passer d'un
char *
est clairement plus rapide que le remplacement de 4struct s_node *
s. - BTW: Êtes-vous permutation des nœuds pour être capable de trier la liste?
- Oui, je suis en train de trier ma liste.
- Alors vous devriez plutôt regarder mergesort, et de diviser la liste en deux, à l'aide d'un fast-pointeur (un pointeur de marcher deux nœuds) et une lente pointeur en sautant juste un nœud dans la liste. Quand le jeûne pointeur est à la fin de la liste, la lenteur de pointeur est au milieu de la liste. C'est là que vous diviser et conquérir.
Vous devez vous connecter pour publier un commentaire.
Dire que c'est de votre structure initiale
TMP -> L -> R -> X
Vous n'êtes pas la mise à jour de la X->prev correctement. Dans votre dernière ligneright->next->prev = left->prev;
droit->suivant est à gauche. Si vous êtes à la mise à jour de la précédent de la gauche qui est faux. Au lieu de cela, vous devriez faireDonc, je pense que cela va fonctionner
Du code affiché dans votre question, je suis en déduire que votre fonction est en supposant que vous échangez nœuds adjacents.
Essayez ce qui suit:
EDIT: à la Suite de votre commentaire dans la question d'origine, il est beaucoup plus rapide pour effectuer les opérations suivantes:
x - A - B -y
mais pasx - A - y - B - z
)left
etright
ne sont pasNULL
à la première ligne de votre fonction. Si l'un (ou les deux) estNULL
, l'affichage d'une erreur et retour.Si vous écrivez ce que vous voulez faire, vous pouvez réaliser un vraiment simple et directe de la solution.
[[code de travail est à la fin de la réponse]]
Par exemple, si vous avez deux nœuds que vous voulez échanger (disons A et B), il y a deux possibilités en fonction de la position des nœuds. Ils pourraient être adjacentes ou non.
Adjacentes cas
Dans les autres cas, vous pouvez écrire:
Si vous échangez avec B, vous obtiendrez ceci:
C'est ce que vous voulez obtenir. Vous devez réorganiser les pointeurs pour permuter les deux nœuds A et B.
Si vous utilisez une matrice de la forme de la règle sera plus intuitif:
Ou tout simplement écrire les matrices seul:
Avis, que la matrice de permutation pivote de 90 degrés dans le sens horaire. Si vous indexez les éléments dans la matrice, vous pouvez faire une assotiation table:
Donc, si vous stocker les pointeurs dans un tableau, vous pouvez facilement réorganiser:
Non adjacentes cas
Que vous pouvez faire une règle similaire pour les non adjacentes cas ainsi:
Swap de A par B:
Pointeurs vers les nœuds
Parce que nous avons affaire à des listes liées, il ne suffit pas de changer les pointeurs dans les nœuds. Nous venons de mettre à jour les pointeurs pointant vers notre nœuds que nous voulons inverser. Ce pointeurs sont situés dans le quartier de la swapable objets.
Avis, que les pointeurs qui sont situés dans les ganglions que nos pointeurs points sont toujours dirigées à nous-mêmes.
Donc après la mise à jour des pointeurs de fonction de la règle d'association, vous n'avez qu'à pointer l'extérieur des pointeurs vers le nœud donné, et vous avez terminé! Assurez-vous, que le voisin existe bien sûr.
Vous devez également vérifier si le nœud est lié avant que le nœud B. Si non, vous devez permuter les deux paramètres. Grâce kralyk pour le heads up.
C'est assez d'informations pour écrire les fonctions qui ne l'échange.
Permutation de fonction et de ses fonctions d'assistance
Programme de travail pour la présentation
La optput du programme suivant:
Vous pouvez exécuter le code en une seconde, en suivant ce lien:http://codepad.org/UHcmmag1
Lien mis à jour avec la nouvelle fonction de permutation: http://codepad.org/LbRYjvPr
[2] <-> [1]
). Dans ce cas, vous devez faire pivoter votre matrice de -90°, ou de détecter que B est précédente Une et swap A et B pointeurs en premier. Honnêtement, je pense que les matrices de compliquer le code. Je venais d'utiliser un swapper fonction/macro.Très court code qui fonctionne de manière très efficace, a passé 2 heures sur ce:
Vous devez remplacer les deux nœuds...
Mais aussi assurez-vous de conserver les liens qui existent entre les 2 échangé des nœuds et le troisième et dernier, dans les deux directions.
J'espère que cela peut aider.
ps : dans le cas où vous vous demandez: