Новичок
Профиль
Группа: Участник
Сообщений: 3
Регистрация: 23.3.2007
Репутация: нет Всего: нет
|
Здравствуйте. Не могу разобраться, что в программе не так. Надо описать работу алгоритма пирамидальной сортировки. Проверить правильность работы алгоритма сортировки распечаткой ключей(строки конечной длины) отсортированного массива. Файлы heap, type и print писал сам учитель, а компилятор выдаёт ошибку в файле heap.h , пишет, что templates must be classes or functions.  Помогите разобраться плиз. Код | #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <dos.h>
# define LEN_STR 25 # define _STR_N #include "type.h" #include "heap.h" #include "print.h"
void main(void) { clrscr(); Record<int> mas[] ={ {"word"}, {"time"}, {"absolute"}, {"drive"} }; long n =sizeof(mas)/sizeof(mas[0]); heap_sort(mas, n); prn(mas, n); getch(); return 0; }
|
файл type.h выглядит так Код | //Структуры для хранения данных и ключей в массиве, позволяющие применять одни и //те же функции сортировки для различных типов ключей и данных. # ifndef _DATA // защита от повторного включения этого файла # define _DATA // в другой # include <iostream.h> # ifdef _NUMBER //ключ - число (типа int, long, float и т.д.) //шаблоны позволяют использовать один и тот же код //для различных типов данных и ключей template <class Key, class Data> struct Record {Key key; Data data; // следующий оператор приведения типа // дает возможность избежать перегузки многочисленных //операций сравнения operator Key() {return key ;} // перегрузка операции = для ключа void operator = (Key n){key=n;} //следующая пергрузка необходима!!! компилятору Borland 3.1, //поскольку без нее поле data не копируется. //Вообще говоря, перегрузка копирования структуры - излишняя операция, //но в данном случае, по-видимому, играет роль наличие шаблона //и ошибка в компиляторе void operator = ( Record & b ){key=b.key;data =b.data;} //печать ключа void PrnKey (){ cout << key<<' ';} }; //обменять template <class Key, class Data> inline void swap(Record<Key, Data> & a, Record<Key, Data> & b ) {Record<Key, Data> t; t=a;a=b;b=t; } //обменять, если ключ 1-го аргумента больше 2-го template <class Key, class Data> inline void IfMoreThenSwap(Record<Key, Data> & a, Record<Key, Data> & b ) {if (a > b) { Record<Key, Data> t; t=a;a=b;b=t;} } //обменять, если ключ 1-го аргумента меньше 2-го template <class Key, class Data> inline void IfLessThenSwap(Record<Key, Data> & a, Record<Key, Data> & b ) {if (a < b) { Record<Key, Data> t; t=a;a=b;b=t;} } //сравнить ключи template <class Key, class Data> inline int compare (Record<Key, Data> & a, Record<Key, Data> & b ) {return a>b?1:a==b?0:-1; } # elif defined _STR_N //ключ - строка длиной LEN_STR # include <string.h> //перед # include <type.h> определять const LEN_STR = ; typedef char Key[LEN_STR+1]; //+1 для хранения признака конца строки - '\0' template <class Data> struct Record {Key key; Data data; //перегрузка операций > и < для сравнения ключей структур int operator > ( Record & b) {return _fstrcmp(key, b.key)>0; } int operator > (char* b ) {return _fstrcmp(key, b)>0; } int operator < ( Record & b) {return _fstrcmp(key, b.key)<0; } int operator >= (char* b ) {return _fstrcmp(key, b)>=0; } int operator <= ( Record & b) {return _fstrcmp(key, b.key)<=0; } int operator >= ( Record & b) {return _fstrcmp(key, b.key)>=0; } int operator == ( Record & b) {return _fstrcmp(key, b.key) == 0; } int operator != ( Record & b) {return _fstrcmp(key, b.key) != 0; } int operator == ( char*b) {return _fstrcmp(key, b) == 0; } void operator = ( char *s); //запись ключа в структуру типа Record void PrnKey() { char *w=key; cout << w <<' ';} } ; template <class Data> int compare ( Record<Data> & a, Record<Data> & b) {return _fstrcmp(a.key, b.key);} template <class Data> void Record<Data> :: operator = ( char *s) { int j=0; for(;j<LEN_STR && *s !='\0';j++) key[j] =*s++; key[j]='\0'; } # elif defined _CHAR_PTR //ключ - строка Си # include <string.h> // т.к. С++ не допускает перегрузки операций для встроенных типов // создадим обертку для char * -структуру Key только с одним полем typedef struct Key { char * key_ptr; void operator = (char *b){key_ptr=b;} }; template <class Data> struct Record {Key key; //ключ Data data; //данные //перегрузка операций > и < для сравнения ключей структур int operator > ( Record & b) {return _fstrcmp(key.key_ptr, b.key.key_ptr)>0; } int operator >= ( Record & b) {return _fstrcmp(key.key_ptr, b.key.key_ptr)>=0; } int operator < ( Record & b) {return _fstrcmp(key.key_ptr, b.key.key_ptr)<0; } int operator == ( Record & b) {return _fstrcmp(key.key_ptr, b.key.key_ptr) == 0; } int operator <= ( Record & b) {return _fstrcmp(key.key_ptr, b.key.key_ptr)<=0; } int operator <= (Key b ) {return _fstrcmp(key.key_ptr, b.key_ptr)<=0; } int operator >= (Key b ) {return _fstrcmp(key.key_ptr, b.key_ptr)>=0; } int operator > (Key b ) {return _fstrcmp(key.key_ptr, b.key_ptr)>0; } int operator == ( Key b) {return _fstrcmp(key.key_ptr, b.key_ptr) == 0;} int operator == (char* b) {return _fstrcmp(key.key_ptr, b) == 0;} int operator > (char* b) {return _fstrcmp(key.key_ptr, b) > 0;} int operator < (char* b) {return _fstrcmp(key.key_ptr, b) < 0;} int operator != (char* b) {return _fstrcmp(key.key_ptr, b) != 0;} void operator = (char *s) { key.key_ptr =s;}//запись ключа в структуру типа Record void PrnKey() { cout << key.key_ptr <<' ';} }//struc Record template <class T> inline int compare (Record<T> & a, Record<T> & b ) {return a>b?1:(a==b)?0:-1; } # endif //функции обмена для строк //если ключ - строка длиной LEN_STR или указатель на char # if defined _STR_N || defined _CHAR_PTR //обменять template <class Data> inline void swap(Record<Data> & a, Record<Data> & b ) {Record<Data> t; t=a;a=b;b=t; } //обменять, если ключ 1-го аргумента больше 2-го template <class Data> inline void IfMoreThenSwap(Record<Data> & a, Record<Data> & b ) {if (a > b) { Record<Data> t; t=a;a=b;b=t;} } //обменять, если ключ 1-го аргумента меньше 2-го template <class Data> inline void IfLessThenSwap(Record<Data> & a, Record<Data> & b ) {if (a < b) { Record<Data> t; t=a;a=b;b=t;} } # endif # endif
|
файл heap.h такой Код | #ifndef _HEAPDOWNDOWN #define _HEAPDOWNDOWN template <class T> void far heap_down_down( T * huge Item, long left, long right) {long j; T tmp = Item[left]; for(;;) {j = 2 * left +1; if ( j <= right) // Разместить в j указатель на большего потомка. {if ( j < right && Item[j + 1] < Item[j])j ++; if ( Item[j] < tmp) // Потомок больше. Поменять его местами с предком. {Item[left] = Item[j]; //Перемещение этого потомка вниз. left = j; }//if #2 else //Предок больше. Процедура закончена. break; } // if #1 else break; } //for Item[left] = tmp; } template <class T> void far heap_down( T * huge Item, long left, long right) {long j; T tmp = Item[left]; for(;;) {j = 2 * left +1; if ( j <= right) // Разместить в j указатель на большего потомка. {if ( j < right && Item[j + 1] > Item[j])j ++; if ( Item[j] > tmp) // Потомок больше. Поменять его местами с предком. {Item[left] = Item[j]; //Перемещение этого потомка вниз. left = j; }//if #2 else //Предок больше. Процедура закончена. break; } // if #1 else break; } //for Item[left] = tmp; } template <class T> void swap(T & a, T & b) {T t =a;a=b;b=t;} template <class T> void far heap_sort(T* huge Item, long count, int down =0) { long i, right=--count; // Создать пирамиду (кроме корневого узла). if(down) //по убыванию {for (i = right / 2; i>=1;i--) heap_down_down (Item, i, right); for (i = right ;i>=1;i--) // Продвинуться вниз по пирамиде, {heap_down_down (Item, 0L, i); // переместиь корень в отсортированную часть swap(Item[0], Item[i]); }//for }//if else //по возрастанию {for (i = right / 2; i>=1;i--) heap_down (Item, i, right); for (i = right ;i>=1;i--) // Продвинуться вниз по пирамиде, {heap_down (Item, 0L, i); // переместиь корень в отсортированную часть swap(Item[0], Item[i]); }//for }//else
} #endif
|
а print.h следующий Код | template <class T> void main() { void far prn (T item[], long count ); template <class T> void far SortInsert0 (T * huge item, long * huge ind, long count ) {for(long i = 1;i<count;i++) //цикл сортировки массива с элемента №1 -т.е. второго {//запомним в переменной x элемент, который надо вставить в нужное место T x = item[ind[i]];//i и слева от i - часть массива, куда надо вставить x long j = i;//j - индекс места вставки while (j != 0 && item[ind[j-1]]>x) //цикл поиска места вставки {//после следующего оператора 2 соседних элемента одинаковы //один из них при возможном выходе из цикла заменится на x ind[j ] = ind[j-1]; j--; //просмотр левой части массива } ind[j ] = i; //вставка x = item[i] на нужное место } } }
|
|