Pagini recente » Cod sursa (job #1912540) | Cod sursa (job #439428) | Cod sursa (job #443744) | Cod sursa (job #3187564) | Cod sursa (job #1061034)
//
// main.c
// huffman
//
// Created by Alexandru Bâgu on 12/18/13.
// Copyright (c) 2013 Alexandru Bâgu. All rights reserved.
//
#include <stdio.h>
#define MAX_N 1000001
#define INF 0x7FFFFFFF
typedef unsigned long long ulong;
typedef struct {
int digits;
ulong value;
} huffman;
typedef struct nodeStr {
ulong value;
int ind;
struct nodeStr *left, *right;
} node;
typedef struct _heapStr {
int size;
node *nodes;
} *heap, heapStr;
int swap(node* n, node* m)
{
node p = *n;
*n = *m;
*m = p;
return 0;
}
int up(heap h, int pos)
{
while(pos != 1 && h->nodes[pos].value < h->nodes[pos / 2].value)
{
swap(h->nodes + pos, h->nodes + pos / 2);
pos /= 2;
}
return 0;
}
int down(heap h, int pos)
{
while(h->size >= 2 * pos)
{
int c1 = pos * 2, c2 = c1 + 1;
if(h->size >= c2)
if(h->nodes[c1].value > h->nodes[c2].value)
c1 = c2;
if(h->nodes[pos].value > h->nodes[c1].value)
{
swap(h->nodes + pos, h->nodes + c1);
pos = c1;
}
else
pos = h->size;
}
return 0;
}
int add(heap h, node* node)
{
h->nodes[++h->size] = *node;
up(h, h->size);
return 0;
}
node* rem(heap h, int pos)
{
node* n = malloc(sizeof(node));
*n = h->nodes[pos];
h->nodes[pos] = h->nodes[h->size--];
//up(h, pos);
down(h, pos);
return n;
}
node* paste(node* n, node* m)
{
node* mix = malloc(sizeof(node));
mix->value = n->value + m->value;
mix->left = n;
mix->right = m;
return mix;
}
int print(heap h)
{
int k = 1, j = 1, i;
for(i = 1; i <= h->size; i++)
{
printf("%d", h->nodes[i].value);
if(h->nodes[i].left != NULL)
printf("!");
if(h->nodes[i].right != NULL)
printf("!");
printf(" ");
k--;
if(k == 0)
{
k = 1 << j;
j++;
printf("\n");
}
}
printf("\n");
return 0;
}
ulong build_list(node* h, ulong value, int digits, huffman *huff)
{
ulong sum = 0;
if(h->left == NULL && h->right == NULL)
{
huff[h->ind].digits = digits;
huff[h->ind].value = value;
}
else
{
sum = h->value;
}
if(h->left != NULL)
sum += build_list(h->left, value << 1, digits + 1, huff);
if(h->right != NULL)
sum += build_list(h->right, (value << 1) | 1 , digits + 1, huff);
return sum;
}
int main(int argc, const char * argv[])
{
int i;
freopen("huffman.in", "r", stdin);
freopen("huffman.out", "w", stdout);
int n;
scanf("%d", &n);
huffman *huff = (huffman*) malloc((n+1) * sizeof(huffman));
heap heap = (heapStr*) malloc(sizeof(heapStr));
heap->nodes = (node*) malloc((n+2) * sizeof(node));
for(i = 0; i <= n; i++) heap->nodes[i].value = INF;
heap->size = n;
for(i = 1; i <= heap->size; i++) {
scanf("%llu", &heap->nodes[i].value);
heap->nodes[i].ind = i;
}
while(heap->size > 1)
{
node *min1 = rem(heap, 1);
node *min2 = rem(heap, 1);
node* mix = paste(min1, min2);
add(heap, mix);
}
node node = heap->nodes[1];
ulong sum = build_list(&node, 0, 0, huff);
printf("%llu\n", sum);
for(i = 1; i <= n; i++)
printf("%d %llu\n", huff[i].digits, huff[i].value);
return 0;
}