#include <iostream>
#include <new>
#include <stdio.h>
#include <stdlib.h>
struct supernode {
int id;
unsigned int size;
void *data;
struct supernode *next;
struct supernode *before;
};
void xmallocdump(void);
void *xmalloc(unsigned int, int);
void xfree(void *, int);
void *xrealloc(void *, unsigned int, int);
static struct supernode *superrootS = NULL;
#define N 16
void xmallocdump(void)
{
int i;
unsigned char c;
struct supernode *p;
if (superrootS == NULL) {
fprintf(stderr, "xmallocdump(): root is NULL.\n"); fflush(stderr);
} else {
p = superrootS;
fprintf(stderr, "ERROR: Memory leak occured!\n");
do {
fprintf(stderr, "Memory Leak >%p %p %p(%d):%d: ", (void *)p, (void *)p->next, (void *)p->data, p->size, p->id);
for (i = 0; i < N; i++) {
c = *(unsigned char *)((char *)(p->data) + i);
printf("%02x(%c) ", c , (isprint(c)) ? c : '.');
}
putchar('\n');
p = p->next;
} while (p != superrootS);
}
}
void *xmalloc(unsigned int n, int id)
{
unsigned int i;
struct supernode *p;
rand();
if (!(p = (struct supernode *)malloc(sizeof(struct supernode)))) {
fprintf(stderr, "xmalloc(): cannot malloc() in xmalloc()\n");
abort();
}
if (superrootS == NULL) {
superrootS = p;
p->size = n;
p->next = p;
p->before = p;
} else {
p->size = n;
p->next = superrootS->next;
p->before = superrootS;
superrootS->next = p;
p->next->before = p;
}
if (!(p->data = malloc(n))) {
fprintf(stderr, "xmalloc(): cannot malloc() in malloc()\n");
abort();
} else {
/* nothing */
}
for (i = 0; i < n; i++)
*(char *)((char *)(p->data) + i) = rand() & 0xff;
p->id = id;
/*printf("xmalloc():malloc id = %d(%p)\n", p->id, p->data); */
return p->data;
}
void xfree(void *p, int id)
{
unsigned int flag, i;
struct supernode *q;
/*printf("xfree():free id = %d(%p)\n", id, p); */
if (p == NULL)
return;
if (superrootS == NULL) {
fprintf(stderr, "xfree(): root is null.\n");
abort();
}
rand();
flag = 0;
q = superrootS;
for (;;) {
if (q->data == p) {
if (q->id != id) {
fprintf(stderr, "xfree(): bad ID. %d <- %d\n", q->id, id);
abort();
}
if (q->next == q) {
for (i = 0; i < q->size; i++)
*(char *)((char *)(q->data) + i) = rand() & 0xff;
free(q->data);
free(q);
flag = 1;
superrootS = NULL;
break;
} else {
q->before->next = q->next;
q->next->before = q->before;
if (q == superrootS)
superrootS = q->next;
for (i = 0; i < q->size; i++)
*(char *)((char *)(q->data) + i) = rand() & 0xff;
free(q->data);
free(q);
flag = 1;
break;
}
}
if (q->next == superrootS)
break;
q = q->next;
}
if (flag != 1) {
fprintf(stderr, "xfree(): cannot xfree(), no data.(id = %d, %p)\n", id, p);
abort();
}
}
/*------------------*/
#define ID_NODE 1001
/*------------------*/
template <class T>
class Node {
private:
T key;
Node *left, *right;
public:
Node(T key) {
this->left = this->right = nullptr;
this->key = key;
}
void *operator new(size_t size) { return xmalloc(size, ID_NODE); }
void operator delete(void *p) { xfree(p, ID_NODE); }
static void insertNode(Node<T> *&root, T key) {
if (root == nullptr) {
root = new Node<T>(key);
return;
}
if (key < root->key)
insertNode(/*ref*/root->left, key);
else
insertNode(/*ref*/root->right, key);
}
static bool deleteNode(Node<T> *&root, T key) {
if (root == nullptr) return false;
if (key < root->key)
return deleteNode(/*ref*/root->left, key);
else if (key > root->key)
return deleteNode(/*ref*/root->right, key);
else {
if (root->left == nullptr) {
Node<T> *p;
p = root;
root = root->right;
delete p;
} else if (root->right == nullptr) {
Node *p;
p = root;
root = root->left;
delete p;
} else { // root->left != 0 && root->right != 0
Node *p, *q;
for (p = root->left; p->right != nullptr; p = p->right)
;
p->right = root->right;
q = root;
root = root->left;
delete q;
}
}
return true;
}
#if defined(N)
#undef N
#endif
#define N 3
void vomitTree(int c) {
if (this == nullptr)
return;
this->left->vomitTree(c + N);
for (int i = 0; i < c; i++) std::cout << ' ';
std::cout << this->key << std::endl;
this->right->vomitTree(c + N);
}
static void release(Node<T> *&root) {
if (root != nullptr) {
release(/*ref*/root->left);
release(/*ref*/root->right);
delete root;
root = nullptr;
}
}
};
template <class T>
class BinaryTree {
private:
Node<T> *root;
public:
BinaryTree<T>() { this->root = nullptr; }
~BinaryTree<T>() { Node<T>::release(/*ref*/this->root); }
void insertNode(T key) { try { Node<T>::insertNode(/*ref*/this->root, key);
} catch (std::bad_alloc) { std::cerr << "memory full." << std::cerr; }
}
bool deleteNode(T key) { return Node<T>::deleteNode(/*ref*/this->root, key); }
void vomitTree() { this->root->vomitTree(0); }
};
int main() {
auto tree = new BinaryTree<int>();
for (;;) {
auto input = 0;
//std::cout << "> ";
std::cin >> input;
if (input < 0)
break;
tree->insertNode(input);
tree->vomitTree();
}
std::cout << "deleting" << std::endl;
for (;;) {
auto input = 0;
//std::cout << "> ";
std::cin >> input;
if (input < 0)
break;
if (tree->deleteNode(input))
std::cout << "deleted." << std::endl;
else
std::cout << "not found." << std::endl;
tree->vomitTree();
}
delete tree;
xmallocdump();
}
/* end */