Рефераты. Аркадна гра "гольф" з елементами трьохвимірної поверхні

Індексне збереження використовується для зменшення часу пошуку потрібного елемента в списку і полягає в наступному. Вихідний список B = розбивається на трохи підсписків У1,У2, ...,Вм таким чином, що кожен елемент списку В попадає тільки в один з підсписків, і додатково використовується індексний список з М елементами, що вказують на початок списків У1,У2, ...,Ум.

Вважається, що список зберігається індексно за допомогою підсписків B1,B2, ...,Bm і індексного списку X = , де ADGj - адреса початку підсписка Bj, j=1,M.

При індексному збереженні елемент До підсписка Bj має індекс j. Для одержання індексного збереження вихідний список У часто перетвориться в список В' шляхом включення в кожен вузол ще і його порядкового номера у вихідному списку В, а в j-ий елемент індексного списку Х, крім ADGj, може включатися деяка додаткова інформація про підсписок Bj. Розбивка списку В на підсписки здійснюється так, щоб всі елементи В, що володіють визначеною властивістю Рj, попадали в один підсписок Bj.

Достоїнством індексного збереження є те, що для перебування елемента К с заданою властивістю Pj досить переглянути тільки елементи підсписка Bj; його початок знаходиться по індексному списку Х, тому що для кожного ДО, що належить Bi, при і не рівному j властивість Pj не виконується.

У розбивці В часто використовується індексна функція G(K), що обчислює по елементі До його індекс j, тобто G(K)=j. Функція G звичайно залежить від позиції ДО, що позначається поз.K, у підсписку В або від значення визначеної частини компоненти ДО - її ключа.

Розглянемо список B= з елементами

ДО1=(17,Y), K2=(23,H), K3=(60,I), K4=(90,S), K5=(66,T),

K6=(77,T), K7=(50,U), K8=(88,W), K9=(30,S).

Якщо для розбивки цього списку на підсписки як індексну функцію взяти Ga(K)=1+(поз.K-1)/3, то список розділиться на три підсписка:

B1a=<(17,Y),(23,H),(60,I)>,

B2a=<(90,S),(66,T),(77,T)>,

B3a=<(50,U),(88,W),(30,S)>.

Додаючи усюди ще і початкову позицію елемента в списку, одержуємо:

B1a'=<(1,17,Y),(2,23,H),(3,60,I)>,

B2a'=<(4,90,S),(5,66,T),(6,77,T)>,

B3а'=<(7,50,U),(8,88,W),(9,30,S)>.

Якщо як індексну функцію вибрати іншу функцію Gb(K)=1+(поз.K-1)%3, то одержимо списки:

B1b"=<(1,17,Y),(4,90,S),(7,50,U)>,

B2b"=<(2,23,H),(5,66,T),(8,88,U)>,

B3b"=<(3,60,I),(6,77,T),(9,30,S)>.

Тепер для перебування вузла K6 досить переглянути тільки одну з трьох послідовностей (списків). При використанні функції Ga(K) це список B2а', а при функції Gb(K) список B3b".

Для індексної функції Gc(K)=1+K1/100, де K1 - перший компонент елемента ДО, знаходимо:

B1=<(17,Y),(23,H),(60,I),(90,S)>,

B2=<(66,T),(77,T)>,

B3=<(50,U),(88,W)>,

B4=<(30,S)>.

Щоб знайти тут вузол К с першим компонентом-ключем ДО1=77, досить переглянути список B2.

При реалізації індексного збереження застосовується методика А для збереження індексного списку Х (функція Ga(X) ) і методика C для збереження підсписків B1,B2,...,Bm (функція Gc(Bi)), тобто використовується, так називане, A-C індексне збереження.

У практиці часто використовується послідовно-зв'язане індексне збереження. Тому що звичайно довжина списку індексів відома, те його зручно зберігати послідовно, забезпечуючи прямій доступ до будь-якого елемента списку індексів. Підсписки B1,B2,...,Bm зберігаються пов'язано, що спрощує вставку і видалення вузлів(елементів). Зокрема, подібний метод збереження використовується в ЄС ЕОМ для організації, так званих, індексно-послідовних наборів даних, у яких доступ до окремих записів можливий як послідовно, так і за допомогою ключа.

Послідовно-зв`язане індексне збереження для приведеного приклада зображене на мал.24, де X=.

Розглянемо ще одну задачу. На вході задана послідовність цілих позитивних чисел, що закінчується нулем. Скласти процедуру для введення цієї послідовності й організації її індексного збереження таким чином, щоб числа, що збігаються в двох останніх цифрах, містилися в один підсписок.

Виберемо як індексну функцію G(K)=K%100+1, а як індексний список Х - масив з 100 елементів. Наступна функція вирішує поставлену задачу:

#include

#include

typedef struct nd

{ float val;

struct nd *n; } ND;

int index (ND *x[100])

{ ND *p;

int i,j=0;

float inp;

for (i=0; i<100; i++) x[i]="NULL;" scanf("%d",&inp); while (inp!="0)" { j++; p="malloc(sizeof(ND));" i="inp%100+1;" p->val=inp;

p->n=x[i];

x[i]=p;

scanf("%d",&inp);

}

return j;

}

Значенням функції, що повертається, index буде число оброблених елементів списку.

Для індексного списку також може використовуватися індексне збереження. Нехай, наприклад, мається список B= з елементами

K1=(338,Z), K2=(145,A), K3=(136,H), K4=(214,I), K5 =(146,C),

K6=(334,Y), K7=(333,P), K8=(127,G), K9=(310,O), K10=(322,X).

Потрібно розділити його на сімох підсписків, тобто X= таким чином, щоб у кожен список B1,B2,...,B7 попадали елементи, що збігаються в першому компоненті першими двома цифрами. Список Х, у свою чергу, будемо індексувати списком індексів Y=, щоб у кожен список Y1,Y2,Y3 попадали елементи з X, у яких у першому компоненті збігаються перші цифри. Якщо списки B1,B2,...,B7 зберігати пов'язано, а списки індексів X,Y індексно, те такий спосіб збереження списку B називається зв'язаним індексним збереженням. Графічне зображення цього збереження приведене на мал.25.

Практична частина

Лістінг програми

Основний модуль golf.c

#include <time.h>

#include <stdlib.h>

#include <dos.h>

#include <conio.h>

#include <math.h>

#include <malloc.h>

#define GRIDSIZE 80 /* Must be bigger than VIEWSIZE */

#define VIEWSIZE 61 /* MUST be odd */

#define DIFF (GRIDSIZE-VIEWSIZE)

#define DEF_DIST -1100

#define DEF_PITCH 122

#define DEF_HEIGHT 120

#define DEF_ROLL 315

#define sine(X) ((long)(sn_tbl[X]))

#define cosine(X) ((long)(sn_tbl[((X)+90) % 360]))

#define C_Plot(X,Y,C) pokeb(0xa000, (X) + 320U*(Y), C)

#define SHIFT 14

#define MASK (GRIDSIZE*GRIDSIZE)

/*

#define GetGrid(X,Y) ((unsigned)grid[((X) + GRIDSIZE*(Y) +idx) % MASK])

#define PutGrid(X,Y,C) grid[((X) + GRIDSIZE*(Y) +idx) % MASK] = (unsigned char)(C)

*/

#define CalcAddress(X,Y) (&grid[((X) + GRIDSIZE*(Y) + idx) % MASK])

extern void far *view_screen;

extern void far *screen;

extern int sn_tbl[360];

extern unsigned char grid[GRIDSIZE*GRIDSIZE];

extern unsigned rand_seed;

unsigned idx = 0;

extern long pitch_sine;

extern long pitch_cosine;

extern long roll_sine;

extern long roll_cosine;

int num_points = GRIDSIZE*GRIDSIZE;

#define START (DIFF/2)

int gx = START,gy = START;

unsigned char *gp;

int cz = DEF_DIST;

int cy = DEF_HEIGHT;

int roll = DEF_ROLL;

int cpitch = DEF_PITCH;

extern void SetMyMode(void);

extern void ClearMyScreen(void);

extern void Project(void);

extern void SwapScreens(void);

extern void DoPlasma(int,int,int,int);

extern int GetRand(void);

extern unsigned GetGrid(void);

extern void PutGrid(void);

#define _GetGrid(X,Y) (_AX = (X), _BX = (Y), GetGrid())

#define _PutGrid(X,Y,C) { _CX = (C); _AX = (X); _BX = (Y); PutGrid(); }

void SetMode(void)

{

struct REGPACK regs;

regs.r_ax = 0x13;

intr(0x10, &regs);

}

void SetTextMode(void)

{

struct REGPACK regs;

regs.r_ax = 0x3;

intr(0x10, &regs);

}

void SetPalette(void)

{

register int i;

register int j;

#define DEPTH(X) max((((X)*(3-j))/3), 3)

for (j = 0; j<4; j++)

for (i = 0; i<64; i+=4)

{

if (i+j > 0)

{

disable();

outportb(0x3c8, (i >> 2)+64*j);

outportb(0x3c9, 0);

outportb(0x3c9, 0);

outportb(0x3c9, DEPTH(2*i/3));

enable();

}

disable();

outportb(0x3c8, (i >> 2)+64*j+16);

outportb(0x3c9, DEPTH(i/2+10));

outportb(0x3c9, DEPTH(i/4+10));

outportb(0x3c9, DEPTH(i/6+10));

enable();

disable();

outportb(0x3c8, (i >> 2)+64*j+32);

outportb(0x3c9, DEPTH(max(63/2+10-i,0)));

outportb(0x3c9, DEPTH(min(64/4+10+3*i/4,63)));

outportb(0x3c9, DEPTH(max(63/6+10-i,0)));

enable();

disable();

outportb(0x3c8, (i >> 2)+64*j+48);

outportb(0x3c9, DEPTH(i));

Страницы: 1, 2, 3, 4



2012 © Все права защищены
При использовании материалов активная ссылка на источник обязательна.