菜单演示程序

/*
    菜单演示程序
    《C高级实用程序设计》 王士元编著 清华大学出版社 p304 - p320
    TC3.0 下编译通过.对源代码略有修改。
    2005-5-21 1:11
*/
#include<graphics.h>
#include<alloc.h>
#include<process.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<dos.h>
#include<bios.h>
#include<conio.h>
#include<ctype.h>

#define INSERT  0x5200
#define ESC     0x001b
#define TAB     0x0f09
#define RETURN  0x000d
#define RIGHT   0x4d00
#define LEFT    0x4b00
#define UP      0x4800
#define DOWN    0x5000
#define BS      0x0e08
#define HOME    0x4700
#define END     0x4f00
#define PGUP    0x4900
#define PGDN    0x5100
#define DEL     0x5300
#define F1      0x3b00
#define F2      0x3c00
#define F3      0x3d00
#define F4      0x3e00
#define F5      0x3f00
#define F6      0x4000
#define F7      0x4100
#define F8      0x4200
#define F9      0x4300
#define F10     0x4400

#define MenuInGround        1
#define MenuActiveGround    2
#define MenuActiveItem      3
#define MenuInItem          4
#define MenuEdge            5
#define WindowEdge          6
#define WindowGround        7
#define PopWindow           8

#define WindowMinX 1
#define WindowMinY 25
#define WindowMaxX 638
#define WindowMaxY 478

void getitemcount(char **,int *,int *,int *);
void InitialGraphics(void);
void LoadMainMenu(void);
void LoadSubMenu(char **name,int ord);
int ManageSubMenu(void);
void ManageMainMenu(void);
void DisplayMainMenu(void);
int DisplaySubMenu(int ord);
void FuncProc(int ID);
void GoodBye(char *pcInf1,char *pcInf2);
void In_ActiveMainMenuItem(int select,char In_Active);
void In_ActiveSubMenuItem(int ord,int select,char In_Active);
int GetKey(void);
void MessageBox(char *Message);
void About(void);
void MoveText(void);
void Draw(void);
void GoodBye(char *pcInf1,char *pcInf2);
void ExitMenu(int ord);
int DisplaySubMenu(int ord);
void Help_page_show(void){return;};

unsigned char AllColors[20]={0,CYAN,LIGHTRED,YELLOW,BLACK,WHITE,LIGHTRED,BLUE,CYAN,9,10,11,12,13,14,15};

#define INUM    10  /* maximum 10 items in each MENU */
typedef struct _menu
{
    int coor[4];            /* The menu's area */
    int itemcoor[4*INUM];   /* max 10 item,each with x1,y1,x2,y2 */
    int itemdispxy[2*INUM]; /* Actually disp item name's X coor */
    char select;            /* selected item's ord */
    char itemnum;           /* The number of items in this menu */
    char **itemname;        /* item's name(point to static data) */
    int COMMAND_ID[INUM];   /* Key number */
}MENUTYPE;

MENUTYPE MainMenu,SubMenu[INUM];

static char *MainMenuItem[]={"File","Menu1","Menu2","Menu3","Menu4","Quit",0};

static char *SubMenuItem1[]=
{
    "Item11",
        "Item12",
        "Item13",
        "Item14",
        "Item15",
        "Item16",
        "Quit",
        0
};

static char *SubMenuItem2[]=
{
    "Item21",
        "Draw",
        "Item23",
        "Item24",
        "Item25",
        "Item26",
        "Item27",
        "Item28",
        0
};

static char *SubMenuItem3[]=
{
    "Item31...",
        "Item32...",
        "Item add......",
        "Item33",
        0
};

static char *SubMenuItem4[]=
{
    "Item41...",
        "Item42...",
        "Moving Text",
        "Item44",
        "Item45",
        "iteme**",
        0
};

static char *SubMenuItem5[]=
{
    "Item51...",
        "About...",
        "Item53",
        0
};

static char *SubMenuItem6[]=
{
    0
};

int maxx,texth,textw;
void * MenuImageBuf;

void main( )
{
    InitialGraphics();
    maxx=getmaxx();
    texth=textheight("text");
    textw=textwidth("t");

    LoadMainMenu();

    LoadSubMenu(SubMenuItem1,0);
    LoadSubMenu(SubMenuItem2,1);
    LoadSubMenu(SubMenuItem3,2);
    LoadSubMenu(SubMenuItem4,3);
    LoadSubMenu(SubMenuItem5,4);
    LoadSubMenu(SubMenuItem6,5);

    ManageMainMenu();
}

/*checked 2005年5月20日 23:58:03 */
void ManageMainMenu(void)
{
    unsigned key;
    int ID;

    DisplayMainMenu();

    for(key=0;;)
    {
        key=GetKey();
        switch(key)
        {
        case LEFT:
            In_ActiveMainMenuItem(MainMenu.select,0);
            if(MainMenu.select<1)   /*Already leftest item in mainmenu */
                MainMenu.select=MainMenu.itemnum-1;
            else
                MainMenu.select--;
            In_ActiveMainMenuItem(MainMenu.select,1);/* checked 2005年5月20日 23:58:03*/
            break;

        case RIGHT:
            In_ActiveMainMenuItem(MainMenu.select,0);
            if(MainMenu.select>MainMenu.itemnum-2)  /*already rightest */
                MainMenu.select=0;
            else
                MainMenu.select++;
            In_ActiveMainMenuItem(MainMenu.select,1);
            break;

        case DOWN:
        case RETURN:
            switch(MainMenu.COMMAND_ID[MainMenu.select])
            {
            case 5:     /* Exit to DOS */
                if(key==DOWN)
                    break;
                closegraph();
                GoodBye("Goodbye from","the MENU DEMO in graphics mode.");
                break;
            default:
                ID=ManageSubMenu();
                if(ID>=0)
                    FuncProc(ID);
                break;
            }
        }
    }
}


void FuncProc(int ID)
{
    switch(ID)
    {
    case 6:     /* 006 File|Quit */
        closegraph();
        GoodBye("GoodBye from","the MENU DEMO in graphics mode.");
        break;
    case 101:
        Draw();
        break;
    case 302:
        MoveText();
        break;
    case 401:
        About();
        break;
    default:
        /* Clear window */
        setfillstyle(SOLID_FILL,AllColors[WindowGround]);
        bar(WindowMinX,WindowMinY,WindowMaxX,WindowMaxY);

        /* dynamic show item text 2005年5月21日 1:07:50*/
        MessageBox(*(SubMenu[MainMenu.select].itemname + SubMenu[MainMenu.select].select));

        /*      MessageBox("This is an example!");*/

        break;
    }
}

 
/* 2005年5月21日 0:26:12*/
/* ManageSubMenu() return an int value that is     */
/* ==-2:If there is a error                        */
/* ==-1:Return to main menu,nothing to do          */
/* ==0 or >0:the COMMAND_ID of a menu item         */
int ManageSubMenu(void)
{
    MENUTYPE * mn=&SubMenu[MainMenu.select];

    unsigned key;

    if(DisplaySubMenu(MainMenu.select))     /*Out of memery */
        return -2;

    for(key=0;;)
    {
        key=GetKey();

        switch(key)
        {
        case ESC:           /* return to MainMenu */
            ExitMenu(MainMenu.select);
            return -1;
        case UP:
            In_ActiveSubMenuItem(MainMenu.select,mn->select,0);
            if(mn->select>0)
                mn->select--;
            else
                mn->select=mn->itemnum-1;
            In_ActiveSubMenuItem(MainMenu.select,mn->select,1);
            break;
        case DOWN:
            In_ActiveSubMenuItem(MainMenu.select,mn->select,0);
            if(mn->select<mn->itemnum-1)
                mn->select++;
            else
                mn->select=0;
            In_ActiveSubMenuItem(MainMenu.select,mn->select,1);
            break;
        case LEFT:
            ExitMenu(MainMenu.select);
            In_ActiveMainMenuItem(MainMenu.select,0); /*2005年5月21日 0:25:04*/
            if(MainMenu.select<1)                        /*Already leftest item in mainmenu */
                MainMenu.select=(MainMenu.itemnum-1);
            else
                MainMenu.select--;
            In_ActiveMainMenuItem(MainMenu.select,1);   /*Light bar */
            if(DisplaySubMenu(MainMenu.select))         /*Out of memory */
                return -2;
            mn=&SubMenu[MainMenu.select];
            break;
        case RIGHT:
            ExitMenu(MainMenu.select);
            In_ActiveMainMenuItem(MainMenu.select,0);
            if(MainMenu.select>MainMenu.itemnum-2)      /*already rightest */
                MainMenu.select=0;
            else
                MainMenu.select++;
            In_ActiveMainMenuItem(MainMenu.select,1);
            if(DisplaySubMenu(MainMenu.select))         /* Out of memory */
                return -2;
            mn=&SubMenu[MainMenu.select];
            break;
        case RETURN:
            ExitMenu(MainMenu.select);
            return mn->COMMAND_ID[mn->select];
        }
    }
}


/* Checked 2005年5月20日 21:36:47 */
void LoadMainMenu()
{
    int count,totallen,maxlen,i,j=1;

    /*主菜单的两条对角线坐标*/
    MainMenu.coor[0]=0;
    MainMenu.coor[1]=0;
    MainMenu.coor[2]=maxx;
    MainMenu.coor[3]=3*texth;

    getitemcount(MainMenuItem,&count,&totallen,&maxlen);
    MainMenu.itemnum=count;

    maxlen=(maxx/textw-totallen)/count; /*length(char)between 2 items(horiz.)  */

    for(i=0,j=0;i<count;i++)
    {
        MainMenu.itemcoor[i*4]=j*textw;             /*  x1  */
        MainMenu.itemcoor[i*4+1]=MainMenu.coor[1];  /*  y1  */
        MainMenu.itemcoor[i*4+2]=textw*(j+maxlen+strlen(MainMenuItem[i]));
        /*  x2  */
        MainMenu.itemcoor[i*4+3]=MainMenu.coor[3];

        MainMenu.itemdispxy[i*2]=textw*(j+0.5*maxlen);  /* actuall disp X */
        MainMenu.itemdispxy[i*2+1]=texth;               /*  actuall disp Y */
        MainMenu.COMMAND_ID[i]=i;
        j+=maxlen+strlen(MainMenuItem[i]);
    }
    MainMenu.itemname=MainMenuItem;
}


void LoadSubMenu(char **name,int ord)
{
    int count,i,j,maxlen;

    getitemcount(name,&count,&i,&maxlen);
    SubMenu[ord].itemname=name;
    SubMenu[ord].itemnum=count;

    j=textw*(maxlen+2);
    if(j+MainMenu.itemcoor[4*ord]<maxx)     /*  left text justification is OK  */
    {
        SubMenu[ord].coor[0]=MainMenu.itemcoor[4*ord];    /* item's x1 */
        SubMenu[ord].coor[2]=SubMenu[ord].coor[0]+j;
    }
    else                                    /* Use right justification because of space */
    {
        SubMenu[ord].coor[2]=maxx;          /* left just use X2  */
        SubMenu[ord].coor[0]=SubMenu[ord].coor[2]-j;
    }
    SubMenu[ord].coor[1]=MainMenu.itemcoor[4*ord+3];    /* The item's y2 */
    SubMenu[ord].coor[3]=SubMenu[ord].coor[1]+count*(texth+6);

    /* 6-pixel between items of vert.menu */
    for(i=0;i<count;i++)
    {
        SubMenu[ord].itemcoor[i*4]=SubMenu[ord].coor[0];
        SubMenu[ord].itemcoor[i*4+1]=SubMenu[ord].coor[1]+i*(6+texth);
        SubMenu[ord].itemcoor[i*4+2]=SubMenu[ord].coor[2];
        SubMenu[ord].itemcoor[i*4+3]=SubMenu[ord].itemcoor[i*4+1]+texth+6;

        SubMenu[ord].itemdispxy[i*2]=SubMenu[ord].itemcoor[i*4]+textw;
        SubMenu[ord].itemdispxy[i*2+1]=SubMenu[ord].itemcoor[i*4+1]+3;
        SubMenu[ord].COMMAND_ID[i]=ord*100+i;
    }
}


/* checked in 2005年5月20日 23:39:02 */

void DisplayMainMenu(void)      /* Display main menu. */
{
    unsigned i;

    setcolor(AllColors[WindowEdge]);
    rectangle(0,0,getmaxx(),getmaxy());

    setcolor(AllColors[MenuEdge]);
    setfillstyle(SOLID_FILL,AllColors[MenuInGround]);
    bar3d(MainMenu.coor[0],MainMenu.coor[1],MainMenu.coor[2],MainMenu.coor[3],0,0);
    setcolor(AllColors[2]);

    MainMenu.select = 0 ;

    for(i=0;i<MainMenu.itemnum;i++)  /* */
    {
        if(MainMenu.select==i)
            In_ActiveMainMenuItem(i,1);
        else
            setcolor(AllColors[MenuInItem]);
        outtextxy((MainMenu.itemdispxy[i*2]),MainMenu.itemdispxy[i*2+1],MainMenu.itemname[i]);
    }
}

int DisplaySubMenu(int ord)     /* Display submenu */
{
    unsigned size,i;
    MENUTYPE *mn=&SubMenu[ord];

    size=imagesize(mn->coor[0],mn->coor[1],mn->coor[2],mn->coor[3]);

    /*
    Changed farmalloc to malloc and also changed farfree to free in function ExitMenu().
    Or else it will cause CPU error!
    2005年5月21日 0:30:48
    */
    if(NULL==(MenuImageBuf=(unsigned char *)malloc(size*2)))
    {
        clearviewport();
        outtextxy(100,100,"Out of memory!");
        outtextxy(100,110,"Press any key..");
        getch();
        return 1;
    }

    getimage(mn->coor[0],mn->coor[1],mn->coor[2],mn->coor[3],MenuImageBuf);

    setfillstyle(SOLID_FILL,AllColors[MenuInGround]);

    setcolor(AllColors[MenuEdge]);
    bar3d(mn->coor[0],mn->coor[1],mn->coor[2],mn->coor[3],0,0);

    for(i=0;i<mn->itemnum;i++)
    {
        if(i==mn->select)
            In_ActiveSubMenuItem(ord,i,1);
        else
        {
            setcolor(AllColors[MenuInItem]);
            outtextxy(mn->itemdispxy[i*2],mn->itemdispxy[i*2+1],mn->itemname[i]);
        }
    }

    return 0;
}

void ExitMenu(int ord)
{
    MENUTYPE *mn=&SubMenu[ord];
    if(MenuImageBuf)
    {
        putimage(mn->coor[0],mn->coor[1],MenuImageBuf,COPY_PUT);
        free(MenuImageBuf);
    }
}

void In_ActiveMainMenuItem(int select,char In_Active)
{
    MENUTYPE *tp=&MainMenu;
    int start,end,bot,top;

    start=tp->itemcoor[select*4]+8;
    top=tp->itemcoor[select*4+1]+2;
    end=tp->itemcoor[select*4+2]-8;
    bot=tp->itemcoor[select*4+3]-2;
    if(In_Active==0)        /* off */
    {
        setfillstyle(SOLID_FILL,AllColors[MenuInGround]);
        bar(start,top,end,bot);
        setcolor(AllColors[MenuInItem]);
        outtextxy(tp->itemdispxy[select*2],tp->itemdispxy[select*2+1],tp->itemname[select]);
    }
    else
    {
        setfillstyle(SOLID_FILL,AllColors[MenuActiveGround]);
        bar(start,top,end,bot);
        setcolor(AllColors[MenuActiveItem]);
        outtextxy(tp->itemdispxy[select*2],tp->itemdispxy[select*2+1],tp->itemname[select]);
    }
}


/* 2005年5月21日 0:21:25*/
void In_ActiveSubMenuItem(int ord,int select,char In_Active)
{
    MENUTYPE *tp=&SubMenu[ord];
    int start,end,bot,top;

    start=tp->itemcoor[select*4]+2;
    top=tp->itemcoor[select*4+1]+1;
    end=tp->itemcoor[select*4+2]-2;
    bot=tp->itemcoor[select*4+3]-1;
    if(In_Active==0)                /*  off */
    {
        setfillstyle(SOLID_FILL,AllColors[MenuInGround]);
        bar(start,top,end,bot);
        setcolor(AllColors[MenuInItem]);
        outtextxy(tp->itemdispxy[select*2],tp->itemdispxy[select*2+1],tp->itemname[select]);
    }
    else
    {
        setfillstyle(SOLID_FILL,AllColors[MenuActiveGround]);/*updated 2005年5月21日 0:20:56*/
        bar(start,top,end,bot);
        setcolor(AllColors[MenuActiveItem]);/*0:21:09*/
        outtextxy(tp->itemdispxy[select*2],tp->itemdispxy[select*2+1],tp->itemname[select]);       
    }
}
 
void InitialGraphics(void)
{
    int driver=DETECT,mode=0;
    int errorcode;

    initgraph(&driver,&mode,"C://TC//BGI");
    /*  read result of initialization   */
    errorcode=graphresult();
    if(errorcode!=grOk)             /* an error occurred */
    {
        printf("Graphics error:%s/n",grapherrormsg(errorcode));
        printf("Press any key to halt:");
        getch();
        GoodBye("Graphics error.","Try again!");
    }
}

int GetKey(void)/*   */
{
    int key;

    key=bioskey(0);

    if(key==F1)
        Help_page_show();
    else if(key<<8)
    {
        key=key&0x00ff;         /* Get ASCII code  */
        if(isalpha(key))
            key=toupper(key);
    }
    return key;
}

static void getitemcount(char **s,int *count,int *len,int *maxlen)   /*   */
{
    int i,j;

    for((*maxlen)=0,(*len)=0,i=0;s[i]!=NULL;i++)
    {
        j=strlen(s[i]);
        (*len)+=j;
        if(j>(*maxlen))(*maxlen)=j;
    }
    (*count)=i;
}

void Draw(void)
{
    int x,x1,x2,y1,y2,ch;
    randomize();
    do
    {
        x1=random(WindowMaxX-WindowMinX)+WindowMinX;
        y1=random(WindowMaxY-WindowMinY)+WindowMinY;
        x2=random(WindowMaxX-WindowMinX)+WindowMinX;
        y2=random(WindowMaxY-WindowMinY)+WindowMinY;
        ch=random(16);
        setfillstyle(SOLID_FILL,ch);
        if(x1>x2)
        {
            x=x1;
            x1=x2;
            x2=x;
        }
        if(y1>y2)
        {
            x=y1;
            y1=y2;
            y2=x;
        }
        bar(x1,y1,x2,y2);
        delay(100);
    }while(!bioskey(1));
}

/* modified on 2005年5月21日 9:10:37*/
void About(void)
{
    int MidX,MidY,x1,y1,x2,y2,size;
    void *Buffer;

    MidX=(WindowMaxX-WindowMinX)/2;
    MidY=(WindowMaxY-WindowMinY)/2;

    x1=MidX-90;
    x2=MidX+90;
    y1=MidY-100;
    y2=MidY+100;
    size=imagesize(x1,y1,x2,y2);
    /*  Clear window  */
   
    setfillstyle(SOLID_FILL,AllColors[WindowGround]);
    bar(WindowMinX,WindowMinY,WindowMaxX-1,WindowMaxY-1);

    if((Buffer=malloc(size))==NULL)
    {
        outtextxy(100,100,"Out of memory!Press any key to continue.");
        getch();
    }
    else
    {
        getimage(x1,y1,x2,y2,Buffer);

        setfillstyle(SOLID_FILL,AllColors[PopWindow]);
        bar(x1,y1,x2-9,y2-9);
        setfillstyle(SOLID_FILL,BLACK);
        bar(x1+8,y2-8,x2,y2);
        bar(x2-8,y1+8,x2,y2);

        setcolor(MAGENTA);
        settextjustify(CENTER_TEXT,CENTER_TEXT);
        outtextxy(MidX-4,MidY-40,"MENU EXAMPLE");
        outtextxy(MidX-4,MidY-20,"IN GRAPHICS MODE");
        outtextxy(MidX-4,MidY+25,"10-2005 by");
        outtextxy(MidX-4,MidY+45,"XXX studio");
        getch();

        putimage(x1,y1,Buffer,COPY_PUT);
        free(Buffer);
        settextjustify(LEFT_TEXT,TOP_TEXT);
    }
}

/* modified by meteor135
2005年5月21日 0:56:55*/
void MessageBox(char *Message)
{
    int MidX,MidY,x1,y1,x2,y2,size,Len;
    void *Buffer;

    MidX=(WindowMaxX-WindowMinX)/2;
    MidY=(WindowMaxY-WindowMinY)/2;
    Len=8*(strlen(Message)+1)/2;
    x1=MidX-Len-5*8;
    x2=MidX+Len+5*8;
    y1=MidY-50;
    y2=MidY+50;

    size=imagesize(x1,y1,x2,y2);
    if((Buffer=malloc(size))==NULL)
    {
        outtextxy(100,100,"Out of memorry! Press any key to continue.");
        getch();
    }
    else
    {
        getimage(x1,y1,x2,y2,Buffer);

        setcolor(AllColors[MenuEdge]);
        rectangle(x1,y1,x2-13,y2-13);

        setfillstyle(SOLID_FILL,AllColors[PopWindow]);
        bar(x1+1,y1+1,x2-14,y2-14); //2005年5月21日 0:51:14

        setfillstyle(SOLID_FILL,DARKGRAY);//2005年5月21日 0:56:37
        bar(x1+12,y2-12,x2,y2);
        bar(x2-12,y1+12,x2,y2);

        setcolor(MAGENTA);//2005年5月21日 0:56:26
        settextjustify(CENTER_TEXT,CENTER_TEXT);
        outtextxy(MidX,MidY-20,Message);

        setfillstyle(SOLID_FILL,LIGHTRED);
        bar(MidX-3*8,MidY+16,MidX+3*8,MidY+34);
        setcolor(YELLOW);
        outtextxy(MidX,MidY+26,"OK");

        getch();
        putimage(x1,y1,Buffer,COPY_PUT);
        free(Buffer);
        settextjustify(LEFT_TEXT,TOP_TEXT);
    }
}

void MoveText(void)
{
    int i;

    /* Clear window  */
    setfillstyle(SOLID_FILL,BLUE);
    bar(WindowMinX,WindowMinY,WindowMaxX,WindowMaxY);

    setcolor(YELLOW);
    for(i=300;i>1;i-=2)
    {
        outtextxy(i,100,"Menu example!");
        delay(50);
        bar(i,100,i+104,108);
    }
}

void GoodBye(char *pcInf1,char *pcInf2)
{
    int f;

    clrscr();
    window(1,1,80,1);
    textbackground(LIGHTBLUE);
    clrscr();

    highvideo();
    textcolor(WHITE);
    cprintf(pcInf1);
    textcolor(YELLOW);
    cprintf(pcInf2);
    window(1,1,80,25);
    printf("/n");

    for(f=400;f<800;f+=100)
    {
        sound(f);
        delay(100);
    }

    for(f=400;f>=200;f-=100)
    {
        sound(f);
        delay(200);
    }
    sound(1000);
    delay(1000);

    nosound();
    exit(0);
}
 

 

数据结构算法演示(Windows版) 使 用 手 册 一、 功能简介 本课件是一个动态演示数据结构算法执行过程的辅助教学软件, 它可适应读者对算法的输入数据和过程执行的控制方式的不同需求, 在计算机的屏幕上显示算法执行过程中数据的逻辑结构或存储结构的变化状况或递归算法执行过程中栈的变化状况。整个系统使用菜单驱动方式, 每个菜单包括若干菜单项。每个菜单项对应一个动作或一个子菜单。系统一直处于选择菜单项或执行动作状态, 直到选择了退出动作为止。 二、 系统内容 本系统内含84个算法,分属13部分内容,由主菜单显示,与《数据结构》教科书中自第2章至第11章中相对应。各部分演示算法如下: 1. 顺序表 (1)在顺序表中插入一个数据元素(ins_sqlist) (2)删除顺序表中一个数据元素(del_sqlist) (3)合并两个有序顺序表(merge_sqlist) 2. 链表 (1)创建一个单链表(Crt_LinkList) (2)在单链表中插入一个结点(Ins_LinkList) (3)删除单链表中的一个结点(Del_LinkList) (4)两个有序链表求并(Union) (5)归并两个有序链表(MergeList_L) (6)两个有序链表求交(ListIntersection_L) (7)两个有序链表求差(SubList_L) 3. 栈和队列 (1)计算阿克曼函数(AckMan) (2)栈的输出序列(Gen、Perform) (3)递归算法的演示  汉诺塔的算法(Hanoi)  解皇后问题的算法(Queen)  解迷宫的算法(Maze)  解背包问题的算法(Knap) (4)模拟银行(BankSimulation) (5)表达式求值(Exp_reduced) 4. 串的模式匹配 (1)古典算法(Index_BF) (2)求Next 函数值(Get_next)和按Next 函数值进行匹配 (Index_KMP(next)) (3)求 Next 修正值(Get_nextval)和按 Next 修正值进行匹配(Index_KMP(nextval)) 5. 稀疏矩阵 (1)矩阵转置 (Trans_Sparmat) (2)快速矩阵转置 (Fast_Transpos) (3)矩阵乘法 (Multiply_Sparmat) 6. 广义表 (1)求广义表的深度(Ls_Depth) (2)复制广义表(Ls_Copy) (3)创建广义表的存储结构(Crt_Lists) 7. 二叉树 (1)遍历二叉树  二叉树的线索化  先序遍历(Pre_order)  中序遍历(In_order)  后序遍历(Post_order) (2) 按先序建二叉树(CrtBT_PreOdr) (3) 线索二叉树  二叉树的线索化  生成先序线索(前驱或后继) (Pre_thre)  中序线索(前驱或后继) (In_thre)  后序线索(前驱或后继) (Post_thre)  遍历中序线索二叉树(Inorder_thlinked)  中序线索树的插入(ins_lchild_inthr)和删除(del_lchild_inthr)结点 (4)建赫夫曼树和求赫夫曼编码(HuffmanCoding) (5)森林转化成二叉树(Forest2BT) (6)二叉树转化成森林(BT2Forest) (7)按表达式建树(ExpTree)并求值(CalExpTreeByPostOrderTrav) 8. 图 (1)图的遍历  深度优先搜索(Travel_DFS)  广度优先搜索(Travel_BFS) (2)求有向图的强连通分量(Strong_comp) (3)有向无环图的两个算法  拓扑排序(Toposort)  关键路径(Critical_path) (4)求最小生成树  普里姆算法(Prim)  克鲁斯卡尔算法(Kruscal) (5)求关节点和重连通分量(Get_artical) (6)求最短路径  弗洛伊德算法(shortpath_Floyd)  迪杰斯特拉算法(shortpath_DIJ) 9. 存储管理 (1)边界标识法 (Boundary_tag_method) (2)伙伴系统 (Buddy_system) (3)紧缩无用单元 (Storage_compaction) 10. 静态查找 (1)顺序查找(Search_Seq) (2)折半查找 (Serch_Bin) (3)插值查找 (Search_Ins) (4)斐波那契查找 (Search_Fib) (5)次优查找树(BiTree_SOSTree) 11. 动态查找 (1)在二叉排序树上进行查找(bstsrch)、插入结点(ins_bstree)和删除结点(del_bstree) (2)在二叉平衡树上插入结点(ins_AVLtree) 和删除结点(del_AVLtree) (3)在 B-树上插入结点(Ins_BTree) 和 删除结点(Del_BTree) (4)在 B+树上插入结点(Ins_PBTree) 和 删除结点(Del_PBTree) 12. 内部排序 (1)简单排序法  直接插入排序(Insert_sort)  表插入排序(内含插入(Ins_Tsort) 重排(Arrange)两个算法)  起泡排序(BubbleSort)  简单选择排序(SelectSort) (2)复杂排序法  堆排序(HeapSort)  快速排序(QuickSort)  锦标赛排序(Tournament) (3)其他  快速地址排序(QkAddrst)  基数排序(RadixSort) 13. 外部排序 (1)多路平衡归并排序(K-Merge) (2)置换-选择排序(Repl_Selection) 三、 运行环境 1. 硬件:Pentium100以上PC机。 2. 软件:Windows95及以上版本的操作系统。 四、 运行 本系统的执行文件为DSDEMOW.EXE。 五、 如何使用本课件 读者可以利用鼠标移动光标选择“演示算法”或“菜单命令”来控制课件的运行过程。 1. 课件的演示算法菜单为页式菜单。第一级菜单中的各项与上述“系统内容”中各大项相对应,读者运行“算法演示课件”后, 即进入“算法选择一级菜单”画面,此时可移动光标进行选择,当光标所在菜单项改为红色时,单击鼠标即进入“算法选择二级菜单”,进行相同操作之后,或进入算法选择三级菜单(如图1所示),或进入算法演示的执行状态(如图2所示)。 图1 图2 在算法选择菜单画面中,形如 的图标意为尚有下级菜单,形如 的图标则表示将直接进入算法演示状态。此时也可直接单击一级菜单或二级菜单的标题直接返回之,注意:菜单右侧上方的“退出”按钮意为退出整个演示课件。 2. 算法演示执行状态下的屏幕分为三部分:第一行为“标题行”,第二行为“菜单命令”,以下为算法演示屏上各菜单的说明。 菜单命令中各项自左至右的功能分别为:  数据——设置算法演示的数据(数据结构)。  调用栈——察看当前函数(或过程)嵌套或递归的历程。  说明——察看算法说明。  暂停——中断演示过程。  执行——连续执行算法直至所设断点或至算法执行完毕。  单步——执行一行算法,遇到子程序调用时,连续执行完子程序。  跟踪——执行一行算法,遇到子程序调用时,进入子程序。  执行到——演示算法到当前所设最近的断点或算法窗口中的当前行。  恢复——重置屏幕为当前算法执行前的初始状态。  断点——在算法窗口的当前选择行设置断点或清除断点。  设置——设置连续演示时的速度或开/闭背景音乐(或动作音效)开关。  返回——返回算法选择菜单。 3. 断点的设置方法为:移动光标至“断点语句”所在行,点击鼠标后即出现绿色光条,之后单击“断点”菜单中的“设置断点”命令项即可,此时该断点语句所在行上将出现红色光条。 六、 算法演示屏的详细说明 本系统对屏幕设计的基本原则是集数据结构、算法和其他重要信息(如栈等)于同一屏幕。一般情况下演示屏由图示、算法和变量三个窗口组成,特殊情况下将根据演示内容适当增加。一般情况下, 左侧图示窗口显示演示数据的逻辑结构或存储结构,右侧上方窗口显示算法文本,右侧下方窗口显示当前算法中各变量的值或递归工作栈的状态。各窗口间的边界大小均可自由调节,且可按需扩大至全屏。 算法窗口显示当前演示的算法文本,并以深蓝色的光条覆盖将要执行的语句。若算法中含有函数或过程调用语句,则当光条覆盖到该过程调用语句时,随即自动隐去原算法文本而显示子过程的文本,而从此过程返回时再重新显示原算法文本。类似地,在演示递归算法执行过程时,每当执行递归调用本过程的语句时,随即隐去当前层次的算法文本而显示下一层的算法文本,并且以不同颜色的算法文本表示递归的不同层次。如第一层的算法文本为深绿色,第二层为紫色,第三层为深红色,第四层为深蓝色,第五层为浅蓝色,第六层为玫瑰红色等。 当演示递归算法执行过程中递归工作栈的变化状态时,递归工作栈显示在右侧下窗口,递归工作栈的状态和算法文本窗口中相应语句执行后的结果相对应,栈顶记录为当前递归层的参量值。每进入一层递归时,就产生一个新的工作记录(包括调用语句行号、变量参数或全程变量、数值参数和局部变量)压入栈顶;每退出一层递归时,先根据栈顶的调用语句行号返回至上层,然后在传递完变量参数的值后退栈。 各个算法演示屏的补充说明如下: 1. 顺序表和链表的插入、删除和链表的生成 算法演示屏由显示顺序表或链表的图示、算法文本及变量等三个窗口组成。在演示算法之前,需先在弹出的小窗口中输入线性表的数据元素及算法参数 i(插入或删除的位置)和 b(被插的数据元素)的值。顺序表的图示窗口在演示屏的上方,链表的图示窗口在左侧。 2. 有序表的操作 算法演示屏的状态和 1 中所述相同。 3. 汉诺塔问题 算法演示屏由4个窗口组成。右侧上方为算法文本,在算法中有4个形式参量,其中值参 n 为圆盘个数,x、y、和 z 分别表示3个塔座;右侧下方为递归工作栈,栈中每个记录包含调用语句行号 adr 及值参 n 和 x、y、z;左侧上方显示汉诺塔图形及移动操作结果;左侧下方显示移动操作的记录。 4. 迷宫问题 左侧窗口显示迷宫的逻辑结构,由 N×N 个方格组成,左上[1,1]为入口,右下[N,N]为出口,并且以红色钉子填充表示障碍,空白表示通路,红色交通灯表示已游历过的路,箭头表示继续游历的方向,演示结束时显示一条通路或迷宫不通的信息。右侧下窗口为递归工作栈,栈中每个记录含6个数据项,其中 adr 指示调用语句行号,k 指示步数,(x,y) 表示当前坐标,i 指示路径方向(起始方向为 1,顺时针方向旋转搜索)。 5. 皇后问题 左侧图示窗口包含棋盘和递归工作栈两部分,栈中记录含3个数据项,其中 adr 指示调用语句行号,k 指示列号,i 指示行号。此算法演示可求得所有可行结果,在求得每一种排布的结果之后,均会弹出一个窗口显示“找到第 j (j=1,2,…) 种排布”,单击“确定”按钮将继续进行,直至找到所有可能构成的排布。 6. 背包问题 右侧图示窗口的上方显示背包、物件及其体积。 若有解,则在求得每一组结果之后,均会弹出一个窗口提示求得一组解,单击提示窗口中的小人将继续进行。该窗口的下方为递归工作栈,栈中的记录含3个数据项,其中 adr 指示调用语句所在行号,n 指示物件个数,t 指示背包总体积。 7. 阿克曼函数 整个演示屏只有显示算法文本和显示算法执行过程中栈的状态两个窗口。在执行算法之前,首先应按照提示输入参数 m 和 n 的值。 8. 栈的输出序列 图示窗口的内容为:由算法 Gen 生成的栈的操作序列(列出在窗口的下方)、算法 Perform 执行时栈的操作过程(该窗口的上方)以及算法 Perform 执行的结果——栈的输出序列(列出在图示窗口的右侧)。 9. 表达式求值 图示窗口的内容主要为显示表达式求值过程中操作数栈和运算符栈的变化情况以及主要操作。上方的小窗口显示在算法演示之前设定的表达式。 10. 离散事件模拟 图示窗口分成3部分:中间部分或显示客户流动情况的动画,或显示程序执行过程中事件表和4个队列的数值,上方两个按钮用以切换动画或静态数据,下方则显示客户总人数、客户逗留的累计时间以及调节动画中小人移动速度的指针。 11. 串的模式匹配 上窗口显示算法文本,下窗口显示串的匹配过程或求 next 函数的过程。 12. 稀疏矩阵 图示窗口显示矩阵的状态或其三元组的表示。 13. 求广义表的深度 图示窗口显示广义表的存储结构,图中指针 ls 指向当前所求深度的广义表,值为空时不显示。演示结束时弹出窗口显示求得的深度。 14. 复制广义表 图示窗口的上方显示已知广义表的存储结构,图示窗口的下方显示复制求得的广义表的存储结构。递归工作栈中含调用语句行号 adr、变参 nls 和值参 ls。 15. 创建广义表的存储结构 图示窗口显示广义表存储结构的建立过程和算法执行过程中参数Sub的当前值。 16. 遍历二叉树 图示窗口显示二叉树的逻辑结构和遍历结果输出的结点序列,图中指针 bt 指向当前遍历的二叉树的根结点。 17. 线索二叉树 图示窗口显示二叉树的存储结构,但结点中只含标志域,而以结点间的黑色连线表示指针,红色连线表示前驱线索,蓝色连线表示后继线索。在二叉树线索化的过程中,图中指针 p 指向当前层二叉树的根结点,指针 pre 指向当前被访问的结点的前驱。在演示线索树的插入和删除过程时,图示窗口的下方还包括“输入行”和“提示行”。 18. 按先序序列建二叉链表 图示窗口显示输入的先序序列和生成二叉链表的过程。 19. 森林和二叉树的相互转换 图示窗口在显示屏的上方,其左侧为森林,右侧为二叉树。 20. 赫夫曼树和赫夫曼编码 图示窗口显示生成的赫夫曼树的逻辑结构和每个叶子结点的编码。 21. 图的深度优先搜索 图示窗口的上半部分显示图的逻辑结构,初始状态用青色圆圈表示顶点,结点间的黑色连线表示边或弧(连线上画有箭头)。演示过程中用红色覆盖已访问的顶点和边(或弧)。窗口下方显示图的邻接表,演示过程中以红色框边表示已访问过的弧。图示窗口的下方显示遍历后输出的顶点序列。 22. 图的广度优先搜索 与深度优先不同的是,在窗口的下方增加一个队列,其左端为队头,右端为队尾。 23. 求有向图的强连通分量 图示窗口自上而下分别显示有向图的逻辑结构、存储结构和 Finished 数组在算法执行过程中的变化情况。所求得的各个强连通分量,将以不同颜色的顶点组表示。 24. 求关节点和重连通分量 图示窗口的上半部分显示无向图,下半部分自上而下分别显示 Vexnum、Vexdata、Visited、Low、Squlow(求得 low 值的顺序)和 artpoint(关节点)的信息。 25. 有向图的拓扑排序 图示窗口由5部分组成。其中左上显示有向图的邻接表;左下显示有向图,其中顶点和弧的初始状态分别为绿色和黑色,从栈中退出的顶点(i)用红色表示,分别以蓝色和红色指示当前访问的邻接点(k)和它们之间的弧(ik),灰白色表示已经输出的顶点;右下显示顶点的入度;右上显示入度为零的栈。当拓扑排序不成功时,在演示屏的中央将会弹出一个窗口,显示提示信息“网中存在自环!”,此时用户可在左下显示的有向图中由绿色顶点和黑色弧构成的子图中找到这个环。 26. 有向图的关键路径 图示窗口包含5部分信息。左上显示带入度域的邻接表;左下显示有向网的逻辑结构和顶点的入度及各顶点事件的最早发生时间和最迟发生时间;右下显示拓扑排序过程中入度为零的顶点的栈S,右上显示的栈 T 存放拓扑序列,其入栈顺序和栈 S 的出栈顺序相同,从栈顶到栈底的顶点顺序即为顶点的逆拓扑序列。算法执行结束后将弹出窗口列出全部结果,其中红色字体的弧表示关键活动。 27. 普里姆算法 图示窗口包含3部分内容。右上是邻接矩阵;左上是无向网的逻辑结构,图中顶点的初始状态为黄色,算法执行过程中,红色覆盖的顶点和边则表示已加入生成树的顶点和生成树上的边;窗口的下方则显示 closedge 数组中的值。 28. 克鲁斯卡尔算法 图示窗口的左侧为无向网,以红色标定已落在生成树上的边;右侧自上而下列出各条边的信息以及选择生成树的边的执行过程。 29. 边界标识法 图示窗口的初始状态为 64KB 的模拟存储器,演示过程中,以绿色覆盖占用块。各个存储块的头部左侧所示为该块的起始地址,头部结构或其他信息参见教科书。用户可根据弹出窗口的操作提示信息进行操作,输入请求分配的空间大小或释放块的首地址。 30. 伙伴系统 在图示窗口中,左侧为可利用空间链表的逻辑结构,右侧为存储结构,其中红色覆盖部分为占用块。弹出窗口为输入窗口,由用户输入请求分配的空间大小或释放块的首地址。 31. 紧缩无用单元 右侧显示存储空间,空白表示空闲块,其他颜色覆盖表示占用块,在存储空间不足分配时将进行空闲块压缩。左侧显示存储映像。弹出窗口为输入窗口,由用户输入请求分配的空间大小和分配或释放块的块名。 32. 静态查找 上窗口为图示窗口,演示查找过程;左下和右下分别为算法文本和变量窗口。 33. B-树和B+树 整个屏幕分为上、下两个窗口,上窗口演示插入或删除结点过程中B-树或B+ 树结构的变化状况;下窗口内显示如查找关键字、插入位置、结点分裂等操作信息。下窗口上面左侧的小窗口为编辑窗口,由用户输入待插或待删的关键字,输入之后其右侧的操作命令将由隐式状态改为显式状态。 34. 内部排序 图示窗口演示排序过程以及排序过程中关键字之间进行的比较次数和记录移动的次数。 七、 用户自行输入数据指南 算法操作的对象——数据结构,或由用户自行输入,或由系统随机产生,并在获得用户的确认之前,可反复随机产生,直至用户满意,用鼠标点击“OK”按钮确认为止。 多数情况下的输入界面上有足够的提示信息,以指示用户需要进行何种操作。补充说明如下: 1. 表的数据元素为任意的单个字符。 2. 迷宫的输入界面如图3所示。图中砖墙图案表示障碍,连续点击鼠标可将光标所在位置设置成通道或者障碍,建议用户先点击“随机生成”按钮随机生成一个迷宫,然后移动鼠标调整成所需。所设迷宫可以利用“保存数据”按钮生成dat类型文件,并在需要时可以利用“取出数据”按钮读入。 图3 3. 演示背包问题的算法之前,首先需要输入物品个数,之后将出现如图4所示的输入界面,可以利用“随机生成”的按钮或各个相应的小窗口输入物品体积 wi 和背包体积 T 。背包的总体积不得超过 30 ,单个物品的体积不得超过 10 。 图4 4. “表达式求值”和“建表达式树”时的输入界面如图5所示。用户可在窗口内自行输入,并以“Enter”键为结束符;也可以连续点击左侧蓝色的表达式由系统自动生成,直至用户点击右侧的计算器表示确认为止。“求值”可实现带括弧的四则运算和幂次运算,并支持sin、cos、tan、arcsin 和 arccos 等函数计算,其操作数为实数。“建树”的表达式仅限于带括弧的四则运算,其操作数为单个字母的字符。 图5 5. 稀疏矩阵的输入界面如图6所示。用户可随意进行矩阵中任意位置元素的输入,只要将光标移动至待输入的元素位置,单击鼠标后将弹出计算器,单击数字按钮,可进行随意输入,之后点击“OK”按钮表示确认。 图6 6. 广义表的数据输入方式为自左向右顺序输入广义表的字符串。输入过程中,图7所示输入界面中的“确定”为灰色字体,只有当用户正确输入完毕时,“确定”两字才改为黑色字体,此时用户可单击此按钮表示确认。 图7 7. 图的输入界面如图8所示。之前尚需确认是否为有向图和带权图。在用户自行输入图时,首先按下“创建节点”按钮,之后可移动光标至窗口的任意位置单击鼠标创建顶点;然后单击“创建弧”按钮,可在任意两个顶点之间构建弧或边。构建弧(或边)的操作为:先将光标移动至弧尾的顶点,单击一次鼠标,然后移动光标至弧头位置,再单击一次鼠标。对于带权的图,则在构建弧(或边)的同时,在当时弹出的窗口中输入权值,权值的默认值为 1。 图8 8. 内部排序的关键字均为单个字符。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值