#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/* #define DEBUG*/
#if defined(DEBUG)
#include "qzmalloc.h"
#else
#define qzmallocdump()
#define qzmalloc(a, b) malloc(a)
#define qzfree(a, b) free(a)
#endif
#define ID_NODE 1001
#define ID_DATA 1002
/*=========================================================================*/
/* 双方向リスト*/
struct node {
void *data;
struct node *next;
struct node *before;
};
/*=========================================================================*/
int add_node(struct node **root, void *data) {
struct node *new_node;
if (root == 0)
return 0;
if (*root == 0) {
if ((new_node = qzmalloc(sizeof(struct node), ID_NODE)) != 0) {
new_node->next = new_node->before = new_node;
*root = new_node;
new_node->data = data;
return 1;
} else {
return 0;
}
} else {
if ((new_node = qzmalloc(sizeof(struct node), ID_NODE)) != 0) {
(*root)->before->next = new_node;
new_node->before = (*root)->before;
(*root)->before = new_node;
new_node->next = *root;
(*root) = new_node;
new_node->data = data;
return 1;
} else
return 0;
}
}
void dump(struct node *root, void (*dump_data)(void *)) {
if (root == 0) {
return;
}
if (root != 0) {
struct node *p = root;
do {
if (p->data) (*dump_data)(p->data);
p = p->next;
} while (p != root);
}
}
void release(struct node **root, void(*release_data)(void *)) {
if (*root == 0)
return;
struct node *p = *root, *q;
do {
if (p->data != 0) {
release_data(p->data);
p->data = 0;
}
p->next->before = 0;
p->before = 0;
q = p;
p = p->next;
q->next = 0;
qzfree(q, ID_NODE);
} while (p != *root);
*root = 0;
}
struct node *search(struct node *root, int (*cmp_data)(void *, void *), void *data) {
if (root == 0)
return 0;
struct node *p = root;
do {
if ((*cmp_data)(p->data, data) == 1)
return p;
p = p->next;
} while (p != root);
return 0;
}
/*=========================================================================*/
/* リンクリストの要素数にかかわらず、O(1) でノードを削除する */
void delete(struct node **root, struct node *del_node, void (*release_data)(void *)) {
if (root == 0)
return;
if (*root != del_node) {
del_node->before->next = del_node->next;
del_node->next->before = del_node->before;
del_node->next = del_node->before = 0;
release_data(del_node->data);
del_node->data = 0;
qzfree(del_node, ID_NODE);
del_node = 0;
} else {
del_node = del_node->next;
(*root)->before->next = (*root)->next;
(*root)->next->before = (*root)->before;
(*root)->next = (*root)->before = 0;
release_data((*root)->data);
(*root)->data = 0;
qzfree(*root, ID_NODE);
if (del_node == *root) {
*root = 0;
} else {
*root = del_node;
}
}
}
/*=========================================================================*/
int add_node_data(struct node **root, int data) {
int *data_pack;
if ((data_pack = qzmalloc(sizeof(struct node), ID_DATA)) != 0) {
} else {
fprintf(stderr
, "Cannnot allocate data-area.\n"); return 0;
}
*data_pack = data;
if (add_node(root, data_pack) == 0) {
fprintf(stderr
, "Cannnot allocate node.\n"); qzfree(data_pack, ID_DATA);
return 0;
}
return 1;
}
void dump_data
(int *data_pack
) { printf("<%d>", *data_pack
); fflush(stdout
); } void release_data(int *data_pack) { qzfree(data_pack, ID_DATA); }
int cmp_data(int *a, int *b) { return (a == 0) ? 0 : (b == 0) ? 0 : (*a == *b) ? 1 : 0; }
int main() {
struct node *root = 0;
int data_set[] = {31, 41, 59, 26, 53, 58, 97, 93, 23, 84, 62, -1};
/* int data_set[] = {62, -1}; */
for (int i = 0; data_set[i] > 0; i++) {
printf("add data: %d\n", data_set
[i
]); add_node_data(&root, data_set[i]);
}
dump(root, (void (*)(void *))dump_data);
/*-----------------------------------------------------*/
/* 削除するノードを探す。この部分は O(N) なのは当然である. */
struct node *node;
int target = 62;
if ((node = search(root, (int (*)(void *, void *))cmp_data, &target)) != 0) {
printf("found & deleting! : %d\n", *(int *)node
->data
); } else {
}
/*-----------------------------------------------------*/
/* リンクリストの要素数にかかわらず、O(1) でノードを削除する */
delete(&root, node, (void (*)(void *))release_data);
/*-----------------------------------------------------*/
dump(root, (void (*)(void *))dump_data);
release(&root, (void (*)(void *))release_data);
qzmallocdump();
return 0;
}
/* end */
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgovKiAjZGVmaW5lIERFQlVHKi8KI2lmIGRlZmluZWQoREVCVUcpCiNpbmNsdWRlICJxem1hbGxvYy5oIgojZWxzZQojZGVmaW5lIHF6bWFsbG9jZHVtcCgpCiNkZWZpbmUgcXptYWxsb2MoYSwgYikgbWFsbG9jKGEpCiNkZWZpbmUgcXpmcmVlKGEsIGIpIGZyZWUoYSkKI2VuZGlmCgoKI2RlZmluZSBJRF9OT0RFIDEwMDEKI2RlZmluZSBJRF9EQVRBIDEwMDIKCi8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCi8qIOWPjOaWueWQkeODquOCueODiCovCnN0cnVjdCBub2RlIHsKICB2b2lkICpkYXRhOwogIHN0cnVjdCBub2RlICpuZXh0OwogIHN0cnVjdCBub2RlICpiZWZvcmU7Cn07Ci8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCgppbnQgYWRkX25vZGUoc3RydWN0IG5vZGUgKipyb290LCB2b2lkICpkYXRhKSB7CiAgc3RydWN0IG5vZGUgKm5ld19ub2RlOwogIGlmIChyb290ID09IDApCiAgICByZXR1cm4gMDsKICBpZiAoKnJvb3QgPT0gMCkgewogICAgaWYgKChuZXdfbm9kZSA9IHF6bWFsbG9jKHNpemVvZihzdHJ1Y3Qgbm9kZSksIElEX05PREUpKSAhPSAwKSB7CiAgICAgIG5ld19ub2RlLT5uZXh0ID0gbmV3X25vZGUtPmJlZm9yZSA9IG5ld19ub2RlOwogICAgICAqcm9vdCA9IG5ld19ub2RlOwogICAgICBuZXdfbm9kZS0+ZGF0YSA9IGRhdGE7CiAgICAgIHJldHVybiAxOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIDA7CiAgICB9CiAgfSBlbHNlIHsKICAgIGlmICgobmV3X25vZGUgPSBxem1hbGxvYyhzaXplb2Yoc3RydWN0IG5vZGUpLCBJRF9OT0RFKSkgIT0gMCkgewogICAgICAoKnJvb3QpLT5iZWZvcmUtPm5leHQgPSBuZXdfbm9kZTsKICAgICAgbmV3X25vZGUtPmJlZm9yZSA9ICgqcm9vdCktPmJlZm9yZTsKICAgICAgKCpyb290KS0+YmVmb3JlID0gbmV3X25vZGU7CiAgICAgIG5ld19ub2RlLT5uZXh0ID0gKnJvb3Q7CiAgICAgICgqcm9vdCkgPSBuZXdfbm9kZTsKICAgICAgbmV3X25vZGUtPmRhdGEgPSBkYXRhOwogICAgICByZXR1cm4gMTsKICAgIH0gZWxzZQogICAgICByZXR1cm4gMDsKICB9Cn0KCnZvaWQgZHVtcChzdHJ1Y3Qgbm9kZSAqcm9vdCwgdm9pZCAoKmR1bXBfZGF0YSkodm9pZCAqKSkgewogIGlmIChyb290ID09IDApIHsKICAgIHByaW50ZigiPG51bGw+XG4iKTsKICAgIHJldHVybjsKICB9CiAgaWYgKHJvb3QgIT0gMCkgewogICAgc3RydWN0IG5vZGUgKnAgPSByb290OwogICAgZG8gewogICAgICBpZiAocC0+ZGF0YSkgKCpkdW1wX2RhdGEpKHAtPmRhdGEpOyAgICAgIAogICAgICBhc3NlcnQocC0+bmV4dC0+YmVmb3JlID09IHApOwogICAgICBhc3NlcnQocC0+YmVmb3JlLT5uZXh0ID09IHApOwogICAgICBwID0gcC0+bmV4dDsKICAgIH0gd2hpbGUgKHAgIT0gcm9vdCk7CiAgfQogIHB1dGNoYXIoJ1xuJyk7Cn0KCnZvaWQgcmVsZWFzZShzdHJ1Y3Qgbm9kZSAqKnJvb3QsIHZvaWQoKnJlbGVhc2VfZGF0YSkodm9pZCAqKSkgewogIGlmICgqcm9vdCA9PSAwKQogICAgcmV0dXJuOwogIHN0cnVjdCBub2RlICpwID0gKnJvb3QsICpxOwogIGRvIHsKICAgIGlmIChwLT5kYXRhICE9IDApIHsKICAgICAgcmVsZWFzZV9kYXRhKHAtPmRhdGEpOwogICAgICBwLT5kYXRhID0gMDsKICAgIH0KICAgIHAtPm5leHQtPmJlZm9yZSA9IDA7CiAgICBwLT5iZWZvcmUgPSAwOwogICAgcSA9IHA7CiAgICBwID0gcC0+bmV4dDsKICAgIHEtPm5leHQgPSAwOwogICAgcXpmcmVlKHEsIElEX05PREUpOwogIH0gd2hpbGUgKHAgIT0gKnJvb3QpOwogICpyb290ID0gMDsKfQoKCnN0cnVjdCBub2RlICpzZWFyY2goc3RydWN0IG5vZGUgKnJvb3QsIGludCAoKmNtcF9kYXRhKSh2b2lkICosIHZvaWQgKiksIHZvaWQgKmRhdGEpIHsKICBpZiAocm9vdCA9PSAwKQogICAgcmV0dXJuIDA7CiAgc3RydWN0IG5vZGUgKnAgPSByb290OwogIGRvIHsKICAgIGlmICgoKmNtcF9kYXRhKShwLT5kYXRhLCBkYXRhKSA9PSAxKQogICAgICByZXR1cm4gcDsKICAgIHAgPSBwLT5uZXh0OwogIH0gd2hpbGUgKHAgIT0gcm9vdCk7CiAgcmV0dXJuIDA7Cn0KCi8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCi8qIOODquODs+OCr+ODquOCueODiOOBruimgee0oOaVsOOBq+OBi+OBi+OCj+OCieOBmuOAgU8oMSkg44Gn44OO44O844OJ44KS5YmK6Zmk44GZ44KLICovCnZvaWQgZGVsZXRlKHN0cnVjdCBub2RlICoqcm9vdCwgc3RydWN0IG5vZGUgKmRlbF9ub2RlLCB2b2lkICgqcmVsZWFzZV9kYXRhKSh2b2lkICopKSB7CiAgaWYgKHJvb3QgPT0gMCkKICAgIHJldHVybjsKICBpZiAoKnJvb3QgIT0gZGVsX25vZGUpIHsKICAgIGRlbF9ub2RlLT5iZWZvcmUtPm5leHQgPSBkZWxfbm9kZS0+bmV4dDsKICAgIGRlbF9ub2RlLT5uZXh0LT5iZWZvcmUgPSBkZWxfbm9kZS0+YmVmb3JlOwogICAgZGVsX25vZGUtPm5leHQgPSBkZWxfbm9kZS0+YmVmb3JlID0gMDsKICAgIHJlbGVhc2VfZGF0YShkZWxfbm9kZS0+ZGF0YSk7CiAgICBkZWxfbm9kZS0+ZGF0YSA9IDA7CiAgICBxemZyZWUoZGVsX25vZGUsIElEX05PREUpOwogICAgZGVsX25vZGUgPSAwOwogIH0gZWxzZSB7CiAgICBhc3NlcnQoZGVsX25vZGUgPT0gKnJvb3QpOwogICAgZGVsX25vZGUgPSBkZWxfbm9kZS0+bmV4dDsKICAgICgqcm9vdCktPmJlZm9yZS0+bmV4dCA9ICgqcm9vdCktPm5leHQ7CiAgICAoKnJvb3QpLT5uZXh0LT5iZWZvcmUgPSAoKnJvb3QpLT5iZWZvcmU7CiAgICAoKnJvb3QpLT5uZXh0ID0gKCpyb290KS0+YmVmb3JlID0gMDsKICAgIHJlbGVhc2VfZGF0YSgoKnJvb3QpLT5kYXRhKTsKICAgICgqcm9vdCktPmRhdGEgPSAwOwogICAgcXpmcmVlKCpyb290LCBJRF9OT0RFKTsKICAgIGlmIChkZWxfbm9kZSA9PSAqcm9vdCkgewogICAgICAqcm9vdCA9IDA7CiAgICB9IGVsc2UgewogICAgICAqcm9vdCA9IGRlbF9ub2RlOwogICAgfQogIH0KfQovKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwppbnQgYWRkX25vZGVfZGF0YShzdHJ1Y3Qgbm9kZSAqKnJvb3QsIGludCBkYXRhKSB7CiAgaW50ICpkYXRhX3BhY2s7CiAgaWYgKChkYXRhX3BhY2sgPSBxem1hbGxvYyhzaXplb2Yoc3RydWN0IG5vZGUpLCBJRF9EQVRBKSkgIT0gMCkgewogIH0gZWxzZSB7CiAgICAKICAgIGZwcmludGYoc3RkZXJyLCAiQ2Fubm5vdCBhbGxvY2F0ZSBkYXRhLWFyZWEuXG4iKTsKICAgIHJldHVybiAwOwogIH0KICAqZGF0YV9wYWNrID0gZGF0YTsKICBpZiAoYWRkX25vZGUocm9vdCwgZGF0YV9wYWNrKSA9PSAwKSB7CiAgICBmcHJpbnRmKHN0ZGVyciwgIkNhbm5ub3QgYWxsb2NhdGUgbm9kZS5cbiIpOwogICAgcXpmcmVlKGRhdGFfcGFjaywgSURfREFUQSk7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIDE7Cn0KCnZvaWQgZHVtcF9kYXRhKGludCAqZGF0YV9wYWNrKSB7IHByaW50ZigiPCVkPiIsICpkYXRhX3BhY2spOyBmZmx1c2goc3Rkb3V0KTsgfQp2b2lkIHJlbGVhc2VfZGF0YShpbnQgKmRhdGFfcGFjaykgeyBxemZyZWUoZGF0YV9wYWNrLCBJRF9EQVRBKTsgfQppbnQgY21wX2RhdGEoaW50ICphLCBpbnQgKmIpIHsgcmV0dXJuIChhID09IDApID8gMCA6IChiID09IDApID8gMCA6ICgqYSA9PSAqYikgPyAxIDogMDsgfQoKaW50IG1haW4oKSB7CiAgc3RydWN0IG5vZGUgKnJvb3QgPSAwOwogIGludCBkYXRhX3NldFtdID0gezMxLCA0MSwgNTksIDI2LCA1MywgNTgsIDk3LCA5MywgMjMsIDg0LCA2MiwgLTF9OwovKiAgaW50IGRhdGFfc2V0W10gPSB7NjIsIC0xfTsgKi8KICBmb3IgKGludCBpID0gMDsgZGF0YV9zZXRbaV0gPiAwOyBpKyspIHsKICAgIHByaW50ZigiYWRkIGRhdGE6ICVkXG4iLCBkYXRhX3NldFtpXSk7CiAgICBhZGRfbm9kZV9kYXRhKCZyb290LCBkYXRhX3NldFtpXSk7CiAgfQogIGR1bXAocm9vdCwgKHZvaWQgKCopKHZvaWQgKikpZHVtcF9kYXRhKTsKCiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCiAgLyog5YmK6Zmk44GZ44KL44OO44O844OJ44KS5o6i44GZ44CC44GT44Gu6YOo5YiG44GvIE8oTikg44Gq44Gu44Gv5b2T54S244Gn44GC44KLLiAqLwoKICBzdHJ1Y3Qgbm9kZSAqbm9kZTsKICBpbnQgdGFyZ2V0ID0gNjI7CiAgaWYgKChub2RlID0gc2VhcmNoKHJvb3QsIChpbnQgKCopKHZvaWQgKiwgdm9pZCAqKSljbXBfZGF0YSwgJnRhcmdldCkpICE9IDApIHsKICAgIHByaW50ZigiZm91bmQgJiBkZWxldGluZyEgOiAlZFxuIiwgKihpbnQgKilub2RlLT5kYXRhKTsKICB9IGVsc2UgewogICAgcHJpbnRmKCJub3QgZm91bmQuLlxuIik7CiAgfQoKICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KICAvKiDjg6rjg7Pjgq/jg6rjgrnjg4jjga7opoHntKDmlbDjgavjgYvjgYvjgo/jgonjgZrjgIFPKDEpIOOBp+ODjuODvOODieOCkuWJiumZpOOBmeOCiyAqLwogIGRlbGV0ZSgmcm9vdCwgbm9kZSwgKHZvaWQgKCopKHZvaWQgKikpcmVsZWFzZV9kYXRhKTsKCiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCiAgZHVtcChyb290LCAodm9pZCAoKikodm9pZCAqKSlkdW1wX2RhdGEpOwogIAogIHJlbGVhc2UoJnJvb3QsICh2b2lkICgqKSh2b2lkICopKXJlbGVhc2VfZGF0YSk7CiAgcXptYWxsb2NkdW1wKCk7CiAgcmV0dXJuIDA7Cn0KLyogZW5kICovCg==