#include <stdio.h>
#include <stdlib.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;
};
/*=========================================================================*/
int add_node(struct node **root, void *data) {
if (root == 0)
return 0;
struct node *new_node;
if ((new_node = qzmalloc(sizeof(struct node), ID_NODE)) != 0) {
new_node->next = *root;
new_node->data = data;
*root = new_node;
return 1;
} else {
return 0;
}
}
void dump(struct node *root, void (*dump_data)(void *)) {
while (root != 0) {
if (root->data) (*dump_data)(root->data);
root = root->next;
}
}
void release(struct node **root, void(*release_data)(void *)) {
if (root == 0)
return;
while (*root != 0) {
struct node *node;
if ((*root)->data != 0) {
release_data((*root)->data);
(*root)->data = 0;
}
node = *root;
*root = (*root)->next;
qzfree(node, ID_NODE);
node = 0; /* may be no need, but... */
}
}
struct node *search(struct node *root, int (*cmp_data)(void *, void *), void *data) {
while (root != 0) {
if ((*cmp_data)(root->data, data) == 1)
return root;
root = root->next;
}
return 0;
}
struct node **search_for_delete(struct node **root, int (*cmp_data)(void *, void *), void *data) {
if (root == 0)
return 0;
while (*root != 0) {
if ((*cmp_data)((*root)->data, data) == 1)
return root;
root = &((*root)->next);
}
return 0;
}
/*=========================================================================*/
/* リンクリストの要素数にかかわらず、O(1) でノードを削除する */
void delete(struct node **del_node, void (*release_data)(void *)) {
if (del_node != 0) {
struct node *target_node;
target_node = *del_node;
*del_node = (*del_node)->next;
release_data(target_node->data);
target_node->data = 0;
qzfree(target_node, ID_NODE);
target_node = 0;/* may be no need, but... */
}
}
/*=========================================================================*/
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};
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);
struct node *node;
int target = 97;
if ((node = search(root, (int (*)(void *, void *))cmp_data, &target)) != 0) {
printf("found! : %d\n", *(int *)node
->data
); } else {
}
/*-----------------------------------------------------*/
/* 削除するノードを探す。この部分は O(N) なのは当然である. */
struct node **pnode;
if ((pnode = search_for_delete(&root, (int (*)(void *, void *))cmp_data, &target)) != 0) {
printf("deleting! : %d\n", *(int *)(*pnode
)->data
); }
/*-----------------------------------------------------*/
/* リンクリストの要素数にかかわらず、O(1) でノードを削除する */
delete(pnode, (void (*)(void *))release_data);
/*-----------------------------------------------------*/
dump(root, (void (*)(void *))dump_data);
release(&root, (void (*)(void *))release_data);
qzmallocdump();
return 0;
}
/* end */
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KLyogI2RlZmluZSBERUJVRyAqLwojaWYgZGVmaW5lZChERUJVRykKI2luY2x1ZGUgInF6bWFsbG9jLmgiCiNlbHNlCiNkZWZpbmUgcXptYWxsb2NkdW1wKCkKI2RlZmluZSBxem1hbGxvYyhhLCBiKSBtYWxsb2MoYSkKI2RlZmluZSBxemZyZWUoYSwgYikgZnJlZShhKQojZW5kaWYKCgojZGVmaW5lIElEX05PREUgMTAwMQojZGVmaW5lIElEX0RBVEEgMTAwMgoKLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KLyog5Y2Y5pa55ZCR44Oq44K544OIKi8Kc3RydWN0IG5vZGUgewogIHZvaWQgKmRhdGE7CiAgc3RydWN0IG5vZGUgKm5leHQ7Cn07Ci8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCgppbnQgYWRkX25vZGUoc3RydWN0IG5vZGUgKipyb290LCB2b2lkICpkYXRhKSB7CiAgaWYgKHJvb3QgPT0gMCkKICAgIHJldHVybiAwOwogIHN0cnVjdCBub2RlICpuZXdfbm9kZTsKICBpZiAoKG5ld19ub2RlID0gcXptYWxsb2Moc2l6ZW9mKHN0cnVjdCBub2RlKSwgSURfTk9ERSkpICE9IDApIHsKICAgIG5ld19ub2RlLT5uZXh0ID0gKnJvb3Q7CiAgICBuZXdfbm9kZS0+ZGF0YSA9IGRhdGE7CiAgICAqcm9vdCA9IG5ld19ub2RlOwogICAgcmV0dXJuIDE7CiAgfSBlbHNlIHsKICAgIHJldHVybiAwOwogIH0KfQoKdm9pZCBkdW1wKHN0cnVjdCBub2RlICpyb290LCB2b2lkICgqZHVtcF9kYXRhKSh2b2lkICopKSB7CiAgd2hpbGUgKHJvb3QgIT0gMCkgewogICAgaWYgKHJvb3QtPmRhdGEpICgqZHVtcF9kYXRhKShyb290LT5kYXRhKTsKICAgIHJvb3QgPSByb290LT5uZXh0OwogIH0KICBwdXRjaGFyKCdcbicpOwp9Cgp2b2lkIHJlbGVhc2Uoc3RydWN0IG5vZGUgKipyb290LCB2b2lkKCpyZWxlYXNlX2RhdGEpKHZvaWQgKikpIHsKICBpZiAocm9vdCA9PSAwKQogICAgcmV0dXJuOwogIHdoaWxlICgqcm9vdCAhPSAwKSB7CiAgICBzdHJ1Y3Qgbm9kZSAqbm9kZTsKICAgIGlmICgoKnJvb3QpLT5kYXRhICE9IDApIHsKICAgICAgcmVsZWFzZV9kYXRhKCgqcm9vdCktPmRhdGEpOwogICAgICAoKnJvb3QpLT5kYXRhID0gMDsKICAgIH0KICAgIG5vZGUgPSAqcm9vdDsKICAgICpyb290ID0gKCpyb290KS0+bmV4dDsKICAgIHF6ZnJlZShub2RlLCBJRF9OT0RFKTsKICAgIG5vZGUgPSAwOyAvKiBtYXkgYmUgbm8gbmVlZCwgYnV0Li4uICovCiAgfQp9CgpzdHJ1Y3Qgbm9kZSAqc2VhcmNoKHN0cnVjdCBub2RlICpyb290LCBpbnQgKCpjbXBfZGF0YSkodm9pZCAqLCB2b2lkICopLCB2b2lkICpkYXRhKSB7CiAgd2hpbGUgKHJvb3QgIT0gMCkgewogICAgaWYgKCgqY21wX2RhdGEpKHJvb3QtPmRhdGEsIGRhdGEpID09IDEpCiAgICAgIHJldHVybiByb290OwogICAgcm9vdCA9IHJvb3QtPm5leHQ7CiAgfQogIHJldHVybiAwOwp9CgpzdHJ1Y3Qgbm9kZSAqKnNlYXJjaF9mb3JfZGVsZXRlKHN0cnVjdCBub2RlICoqcm9vdCwgaW50ICgqY21wX2RhdGEpKHZvaWQgKiwgdm9pZCAqKSwgdm9pZCAqZGF0YSkgewogIGlmIChyb290ID09IDApCiAgICByZXR1cm4gMDsKICB3aGlsZSAoKnJvb3QgIT0gMCkgewogICAgaWYgKCgqY21wX2RhdGEpKCgqcm9vdCktPmRhdGEsIGRhdGEpID09IDEpCiAgICAgIHJldHVybiByb290OwogICAgcm9vdCA9ICYoKCpyb290KS0+bmV4dCk7CiAgfQogIHJldHVybiAwOwp9CgovKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwovKiDjg6rjg7Pjgq/jg6rjgrnjg4jjga7opoHntKDmlbDjgavjgYvjgYvjgo/jgonjgZrjgIFPKDEpIOOBp+ODjuODvOODieOCkuWJiumZpOOBmeOCiyAqLwp2b2lkIGRlbGV0ZShzdHJ1Y3Qgbm9kZSAqKmRlbF9ub2RlLCB2b2lkICgqcmVsZWFzZV9kYXRhKSh2b2lkICopKSB7CiAgaWYgKGRlbF9ub2RlICE9IDApIHsKICAgIHN0cnVjdCBub2RlICp0YXJnZXRfbm9kZTsKICAgIHRhcmdldF9ub2RlID0gKmRlbF9ub2RlOwogICAgKmRlbF9ub2RlID0gKCpkZWxfbm9kZSktPm5leHQ7CiAgICByZWxlYXNlX2RhdGEodGFyZ2V0X25vZGUtPmRhdGEpOwogICAgdGFyZ2V0X25vZGUtPmRhdGEgPSAwOwogICAgcXpmcmVlKHRhcmdldF9ub2RlLCBJRF9OT0RFKTsKICAgIHRhcmdldF9ub2RlID0gMDsvKiBtYXkgYmUgbm8gbmVlZCwgYnV0Li4uICovCiAgfQp9Ci8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCgppbnQgYWRkX25vZGVfZGF0YShzdHJ1Y3Qgbm9kZSAqKnJvb3QsIGludCBkYXRhKSB7CiAgaW50ICpkYXRhX3BhY2s7CiAgaWYgKChkYXRhX3BhY2sgPSBxem1hbGxvYyhzaXplb2Yoc3RydWN0IG5vZGUpLCBJRF9EQVRBKSkgIT0gMCkgewogIH0gZWxzZSB7CiAgICAKICAgIGZwcmludGYoc3RkZXJyLCAiQ2Fubm5vdCBhbGxvY2F0ZSBkYXRhLWFyZWEuXG4iKTsKICAgIHJldHVybiAwOwogIH0KICAqZGF0YV9wYWNrID0gZGF0YTsKICBpZiAoYWRkX25vZGUocm9vdCwgZGF0YV9wYWNrKSA9PSAwKSB7CiAgICBmcHJpbnRmKHN0ZGVyciwgIkNhbm5ub3QgYWxsb2NhdGUgbm9kZS5cbiIpOwogICAgcXpmcmVlKGRhdGFfcGFjaywgSURfREFUQSk7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIDE7Cn0KCnZvaWQgZHVtcF9kYXRhKGludCAqZGF0YV9wYWNrKSB7IHByaW50ZigiPCVkPiIsICpkYXRhX3BhY2spOyBmZmx1c2goc3Rkb3V0KTsgfQp2b2lkIHJlbGVhc2VfZGF0YShpbnQgKmRhdGFfcGFjaykgeyBxemZyZWUoZGF0YV9wYWNrLCBJRF9EQVRBKTsgfQppbnQgY21wX2RhdGEoaW50ICphLCBpbnQgKmIpIHsgcmV0dXJuIChhID09IDApID8gMCA6IChiID09IDApID8gMCA6ICgqYSA9PSAqYikgPyAxIDogMDsgfQoKaW50IG1haW4oKSB7CiAgc3RydWN0IG5vZGUgKnJvb3QgPSAwOwogIGludCBkYXRhX3NldFtdID0gezMxLCA0MSwgNTksIDI2LCA1MywgNTgsIDk3LCA5MywgMjMsIDg0LCA2MiwgLTF9OwogIGZvciAoaW50IGkgPSAwOyBkYXRhX3NldFtpXSA+IDA7IGkrKykgewogICAgcHJpbnRmKCJhZGQgZGF0YTogJWRcbiIsIGRhdGFfc2V0W2ldKTsKICAgIGFkZF9ub2RlX2RhdGEoJnJvb3QsIGRhdGFfc2V0W2ldKTsKICB9CiAgZHVtcChyb290LCAodm9pZCAoKikodm9pZCAqKSlkdW1wX2RhdGEpOwoKICBzdHJ1Y3Qgbm9kZSAqbm9kZTsKICBpbnQgdGFyZ2V0ID0gOTc7CiAgaWYgKChub2RlID0gc2VhcmNoKHJvb3QsIChpbnQgKCopKHZvaWQgKiwgdm9pZCAqKSljbXBfZGF0YSwgJnRhcmdldCkpICE9IDApIHsKICAgIHByaW50ZigiZm91bmQhIDogJWRcbiIsICooaW50ICopbm9kZS0+ZGF0YSk7CiAgfSBlbHNlIHsKICAgIHByaW50Zigibm90IGZvdW5kLi5cbiIpOwogIH0KICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KICAvKiDliYrpmaTjgZnjgovjg47jg7zjg4njgpLmjqLjgZnjgILjgZPjga7pg6jliIbjga8gTyhOKSDjgarjga7jga/lvZPnhLbjgafjgYLjgosuICovCiAgc3RydWN0IG5vZGUgKipwbm9kZTsKICBpZiAoKHBub2RlID0gc2VhcmNoX2Zvcl9kZWxldGUoJnJvb3QsIChpbnQgKCopKHZvaWQgKiwgdm9pZCAqKSljbXBfZGF0YSwgJnRhcmdldCkpICE9IDApIHsKICAgIHByaW50ZigiZGVsZXRpbmchIDogJWRcbiIsICooaW50ICopKCpwbm9kZSktPmRhdGEpOyAgCiAgfQogIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwogIC8qIOODquODs+OCr+ODquOCueODiOOBruimgee0oOaVsOOBq+OBi+OBi+OCj+OCieOBmuOAgU8oMSkg44Gn44OO44O844OJ44KS5YmK6Zmk44GZ44KLICovCiAgZGVsZXRlKHBub2RlLCAodm9pZCAoKikodm9pZCAqKSlyZWxlYXNlX2RhdGEpOwogIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwogIAogIGR1bXAocm9vdCwgKHZvaWQgKCopKHZvaWQgKikpZHVtcF9kYXRhKTsKICAKICByZWxlYXNlKCZyb290LCAodm9pZCAoKikodm9pZCAqKSlyZWxlYXNlX2RhdGEpOwogIHF6bWFsbG9jZHVtcCgpOwogIHJldHVybiAwOwp9Ci8qIGVuZCAqLwo=