// 1.FileIO: Character statistics.

#include<stdlib.h>
#include<stdio.h>

#define MAX 26
#define MAXHEAP (MAX+1)

struct  { 
  int stat,let; // stat: the counted number, let: letter.
} heap[MAXHEAP]; // heap index starts at 1 !
int N; // N : current end of heap.
int f,c,i; // f for father, c for child and char, i for loops.

void swap(int i, int j) { 
  int t; //printf("swap: i=%d j=%d\n",i,j);
  t=heap[i].stat; heap[i].stat=heap[j].stat; heap[j].stat=t; 
  t=heap[i].let; heap[i].let=heap[j].let; heap[j].let=t; 
}

void SiftUp() { 
  for(c=N;(c>1)&&(heap[c].stat<heap[(f=c/2)].stat);c=f) swap(c,f); 
}

void SiftDown() {
  for(f=1;(c=2*f)<=N;f=c) {
    if(c+1<=N) if(heap[c+1].stat<heap[c].stat) c++; // Find smaller brother.
    if(heap[f].stat<=heap[c].stat) break;
    swap(f,c); 
  }
}

void HeapSort(int *stat) {
  // Init heap.
  for(i=1;i<MAXHEAP;i++) { heap[i].stat=stat[i-1]; heap[i].let=i-1; } 
  // Sort, smallest stat up.
  for(N=2;N<MAXHEAP;N++) SiftUp();
  for(N=MAXHEAP-2;N>0;N--) { swap(N+1,1); SiftDown(); }
}


main(int argc, char *argv[]) {
  FILE *f; int stat[MAX];
  for(i=0;i<MAX;i++) stat[i]=0;
  if(argc!=2) { printf("usage: a.out file\n"); exit(1); }
  if(!(f=fopen(argv[1],"r"))) { printf("open in-file error!\n"); exit(1); }
  while(c!=EOF) {
    c=fgetc(f); if(isalpha(c)) { if(islower(c)) c-=32; stat[c-65]++; } }
  // Close and error check.
  close(f); printf("Error: %d , EOF: %d\n",ferror(f),feof(f));

  HeapSort(stat); // NEW (rest old)!!!
  
  // Test results (before -- after sort).
  for(i=1;i<MAXHEAP;i++) 
    printf("%c:%d \t-- -%d-%c:%d\n",
	   i-1+65,stat[i-1],i,heap[i].let+65,heap[i].stat);
}

