数据结构与算法专题实验实验报告文档格式.docx

上传人:b****7 文档编号:22255652 上传时间:2023-02-03 格式:DOCX 页数:56 大小:993.73KB
下载 相关 举报
数据结构与算法专题实验实验报告文档格式.docx_第1页
第1页 / 共56页
数据结构与算法专题实验实验报告文档格式.docx_第2页
第2页 / 共56页
数据结构与算法专题实验实验报告文档格式.docx_第3页
第3页 / 共56页
数据结构与算法专题实验实验报告文档格式.docx_第4页
第4页 / 共56页
数据结构与算法专题实验实验报告文档格式.docx_第5页
第5页 / 共56页
点击查看更多>>
下载资源
资源描述

数据结构与算法专题实验实验报告文档格式.docx

《数据结构与算法专题实验实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构与算法专题实验实验报告文档格式.docx(56页珍藏版)》请在冰豆网上搜索。

数据结构与算法专题实验实验报告文档格式.docx

#include<

stdio.h>

conio.h>

typedefstruct

{

intlast;

intdata[maxsize];

}seqlist;

//定义顺序表结构体

inttop;

intsum;

}seqstack;

//定义栈结构体

seqstack*init_seqstack()

seqstack*s;

s=newseqstack;

if(!

s)

{

printf("

空间不足"

);

returnnull;

}

else

s->

top=-1;

sum=0;

returns;

}//栈初始化

intempty_seqstack(seqstack*s)

if(s->

top==-1)

return1;

return0;

}//判断空栈

intpush_seqstack(seqlist*l,inti,seqstack*s)//入栈

if(s->

top==maxsize-1)

top++;

data[s->

top]=i;

//顺序表中第i个元素,i入栈

sum=s->

sum+l->

data[i];

//栈中sum加和!

intpop_seqstack(seqlist*l,seqstack*s,int*x)//出栈

if(empty_seqstack(s))

*x=s->

top];

sum-l->

top]];

top--;

seqlist*init_seqlist()

seqlist*l;

intx=1;

l=newseqlist;

l->

last=0;

请依次输入个物品的大小,输入0结束。

\n"

scanf("

%d"

&

x);

while(x!

=0)

data[l->

last]=x;

last++;

returnl;

}//创建数组,储存物品体积

voidknapsk(intn,seqlist*l)

intflag=1;

inti=0;

intt;

s=init_seqstack();

//初始化栈命名为S

while(flag!

while(i<

=l->

last)

push_seqstack(l,i,s);

sum==n)

可行的解是:

"

for(t=0;

t<

=s->

top;

t++)

%d"

l->

data[t]]);

pop_seqstack(l,s,&

i);

i++;

sum>

n)

elsei++;

while(i==l->

last+1)

flag=pop_seqstack(l,s,&

if(flag==0)

执行完毕"

5.运行结果

实验二:

八皇后问题

设在初始状态下在国际象棋的棋盘上没有任何棋子(这里的棋子指皇后棋子)。

然后顺序在第1行,第2行……第8行上布放棋子。

在每一行中共有8个可选择的位置,但在任一时刻棋盘的合法布局都必须满足3个限制条件

(1)任意两个棋子不得放在同一行

(2)任意两个棋子不得放在同一列上(3)任意棋子不得放在同一正斜线和反斜线上。

2.设计要求

编写求解并输出此问题的一个合法布局的程序。

3.解题思路

在第i行布放棋子时,从第1列到第8列逐列考察。

当在第i行第j列布放棋子时,需要考察布放棋子后在行方向、列方向、正斜线和反斜线方向上的布局状态是否合法,若该棋子布放合法,再递归求解在第i+1行布放棋子;

若该棋子布放不合法,移去这个棋子,恢复布放该棋子前的状态,然后再试探在第i行第j+1列布放棋子。

4.算法设计

s1

数据初始化。

s2

从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领)。

如果是,摆放第n个皇后,并宣布占领(记得姚横列竖列斜列一起设置),接着进行递归;

如果不是,测试下一个位置(n,m+1),但是如果当n<

=8,m=8时,发现此时已无法摆放时,便要进行回溯。

从问题的某一种可能出发,搜索从这种情况能出发,继续搜索,这种不断“回溯”的寻找解的方法,称为“回溯法”。

s3

使用数组实现回溯法的思想。

s4

当n>

8时,便打印出结果。

输出函数我使用printf输出,运行形式为:

第m种方法为:

00000*00

5.程序源码

staticboard[8][8];

intknock(inti,intj)//放置棋子

inttemp_i,temp_j,k;

temp_i=i;

temp_j=j;

for(i=i-1;

i>

=0;

i--)

if(board[i][j]==1)

for(i=temp_i-1,k=temp_j+1,j=temp_j-1;

i--,j--,k++)

if(j>

=0&

&

board[i][j]==1)

if(k<

8&

board[i][k]==1)

return0;

}

voidchess(inti)//设置棋盘

intj;

for(i=i;

i<

8;

i++)

for(j=0;

j<

j++)

board[i][j]=0;

voiddisplay(void)//输出

inti,j;

staticintn=1;

\n第%d种\n"

n++);

for(i=0;

*"

0"

voidfun(inti,intj)

if(i<

8)

for(j=j;

chess(i);

if(knock(i,j)==1)

continue;

board[i][j]=1;

fun(i+1,0);

else

display();

voidmain()

fun(0,0);

6.运行结果(部分)

实验三:

哈夫曼压缩/解压缩算法(编译码器)

利用哈夫曼编码进行信息通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。

但是,要求在发送端通过一个编码系统对传输数据预先编码(压缩);

在接收端将传来的数据进行译码(解压缩复原)。

试为这样的通信站编写一个哈夫曼编译码系统---哈夫曼压缩/解压缩算法。

1)通信内容可以是任意的多媒体文件;

2)自己设定字符大小,统计该文件中不同字符的种类(字符集、个数)、出现频率(在该文件中);

3)构建相应的哈夫曼树,并给出个字符的哈夫曼编码;

4)对源文件进行哈夫曼压缩编码形成新的压缩后文件(包括哈夫曼树);

5)编写解压缩文件对压缩后文件进行解码还原成源文件。

不同源文件形成的压缩文件中应该包含相应的哈夫曼树结构,以便解压缩系统直接译码还原之。

参考哈夫曼树一节内容,但要求编写的软件能完整的对任意文件完成压缩/解压缩。

(1)压缩文件

压缩文件时要先对源文件进行统计,统计字符的种类及出现的次数(即权值)。

统计完成之后,建立哈弗曼树:

每次选取权值最小且无parent的结点作为左右孩子,建成一棵二叉树,且设置新的二叉树的根结点的权值为其左右孩子的权值之和。

直至建成含有2*n-1个结点的哈弗曼树。

编码完成之后,开始对源文件进行压缩。

从源文件读一个字符,从叶子结点中找出和此字符相同的字符结点,将其编码写入一个临时字符组codes;

当codes的长度大于等于8时,将其前8位转换成字符写入目标文件中;

重复1和2此过程,直至读完源文件中的所有字符;

若codes最后还有剩余的不足8位的01代码,则将其低位补0至8位,再写入目标文件。

(2)解压文件

从被压缩的文件中读出FileLength、n的值,以及每个叶子结点的信息:

字符、字符对应的编码。

从被压缩的文件编码区读出一个字符,将其值转化成二进制形式(不足8位的高位要补0),存入codes中,直至codes的长度不小于所有叶子结点的编码的长度;

用for循环查找出第一个和codes的01字符串匹配的叶子结点编码,将该叶子结点的字符写入目标文件,并将codes的字符串前移,前移位数=该叶子结点编码的长度。

重复1和2过程,直至写入的字符数与源文件的长度FileLength相同。

#include<

string.h>

stdlib.h>

time.h>

structnode{

longweight;

//权值

unsignedcharch;

//字符

intparent,lchild,rchild;

charcode[256];

//编码的位数最多为256位

intCodeLength;

//编码长度

}hfmnode[512];

voidcompress();

voiduncompress();

//主函数

intchoice;

请选择1~3:

1.压缩文件\n"

2.解压文件\n"

3.退出\n"

scanf("

choice);

if(choice==1)compress();

elseif(choice==2)uncompress();

elseif(choice==3)return;

elseprintf("

输入错误!

//压缩函数

voidcompress()

charinfile[20],outfile[20];

FILE*ifp,*ofp;

unsignedcharc;

//

longFileLength,filelength=0;

intn,m;

//叶子数和结点数

ints1,s2;

//权值最小的两个结点的标号

charcodes[256];

longsumlength=0;

floatrate,speed;

intcount=0;

clock_tstart1,start2,finish1,finish2;

doubleduration1,duration2;

voidencode(structnode*nodep,intn);

//编码函数

intselect(structnode*nodep,intpose);

//用于建哈弗曼树中选择权值最小的结点的函数

请输入要压缩的文件名:

%s"

infile);

ifp=fopen(infile,"

rb"

if(ifp==NULL)

printf("

文件名输入错误,文件不存在!

return;

请输入目标文件名:

outfile);

ofp=fopen(outfile,"

wb"

if(ofp==NULL)

}

start1=clock();

//开始计时1

//统计文件中字符的种类以及各类字符的个数

//先用字符的ASCII码值代替结点下标

FileLength=0;

while(!

feof(ifp))

{

fread(&

c,1,1,ifp);

hfmnode[c].weight++;

FileLength++;

FileLength--;

//文件中最后一个字符的个数会多统计一次,所以要减一

hfmnode[c].weight--;

//再将ASCII转换为字符存入到结点的ch成员里,同时给双亲、孩子赋初值-1

n=0;

256;

if(hfmnode[i].weight!

{

hfmnode[i].ch=(unsignedchar)i;

n++;

//叶子数

hfmnode[i].lchild=hfmnode[i].rchild=hfmnode[i].parent=-1;

}

m=2*n-1;

//哈弗曼树结点总数

j=0;

i++)//去掉权值为0的结点

if(hfmnode[i].weight!

hfmnode[j]=hfmnode[i];

j++;

for(i=n;

m;

i++)//初始化根结点

hfmnode[i].lchild=hfmnode[i].rchild=-1;

hfmnode[i].parent=-1;

//建立哈弗曼树

for(i=n;

s1=select(hfmnode,i-1);

hfmnode[i].lchild=s1;

hfmnode[s1].parent=i;

s2=select(hfmnode,i-1);

hfmnode[i].rchild=s2;

hfmnode[s2].parent=i;

hfmnode[i].weight=hfmnode[s1].weight+hfmnode[s2].weight;

//编码

encode(hfmnode,n);

finish1=clock();

duration1=(double)(finish1-start1)/CLOCKS_PER_SEC;

/*printf("

哈弗曼树编码用时为:

%fseconds\n"

duration1);

*/

编码完成,是否查看编码信息:

yorn?

c=getch();

if(c=='

y'

{printf("

叶子数为%d,结点数为%d\n"

n,m);

for(i=0;

n;

printf("

%d号叶子结点的权值为:

%ld,双亲为:

%d,左右孩子:

%d,编码为:

%s\n"

i,hfmnode[i].weight,hfmnode[i].parent,hfmnode[i].lchild,hfmnode[i].code);

}

start2=clock();

//开始计时2

fseek(ifp,0,SEEK_SET);

//将ifp指针移到文件开头位置

fwrite(&

FileLength,4,1,ofp);

//将FileLength写入目标文件的前4个字节的位置

fseek(ofp,8,SEEK_SET);

//再将目标文件指针ofp移到距文件开头8个字节位置

codes[0]=0;

//将编码信息写入目标文件

feof(ifp))

filelength++;

for(i=0;

if(c==hfmnode[i].ch)break;

//ch必须也为unsigned型

strcat(codes,hfmnode[i].code);

while(strlen(codes)>

=8)

i++)//将codes的前8位01代码表示的字符存入c

{

if(codes[i]=='

1'

c=(c<

<

1)|1;

elsec=c<

1;

}

c,1,1,ofp);

//将新的字符写入目标文件

sumlength++;

strcpy(codes,codes+8);

//更新codes的值

if(filelength==FileLength)break;

//再将剩余的不足8位的01代码补全8位,继续写入

if(strlen(codes)>

0)

strcat(codes,"

00000000"

c=(c<

sumlength++;

sumlength+=8;

printf("

编码区总长为:

%ld个字节\n"

sumlength-8);

//将sumlength和n的值写入目标文件,为的是方便解压

fseek(ofp,4,SEEK_SET);

sumlength,4,1,ofp);

//把sumlength写进目标文件的第5-8个字节里

fseek(ofp,sumlength,SEEK_SET);

n,4,1,ofp);

//把叶子数n写进编码段后面的4个字节的位置

//为方便解压,把编码信息存入n后面的位置

//存储方式为:

n*(字符值(1个字节)+该字符的01编码的位数(1个字节)+编码(字节数不确定,用count来计算总值))

(hfmnode[i].ch),1,1,ofp);

c=hfmnode[i].CodeLength;

//编码最长为256位,因此只需用一个字节存储

//写入字符的编码

if(hfmnode[i].CodeLength%8!

=0)

for(j=hfmnode[i].CodeLength%8;

j++)//把编码不足8位的在低位补0,赋值给C,再把C写入

strcat(hfmnode[i].code,"

0"

while(hfmnode[i].code[0]!

=0)//开始存入编码,每8位二进制数存入一个字节

c=0;

if(hfmnode[i].code[j]=='

strcpy(hfmnode[i].code,hfmnode[i].code+8);

//编码前移8位,继续存入编码

count++;

//编码占的字节数的总值

finish2=clock();

duration2=(double)(finish2-start2)/CLOCKS_PER_SEC;

写入目标文件用时为:

duration2);

printf("

压缩用时为:

duration1+duration2);

speed=(float)FileLength/(duration1+duration2)/1000;

\n压缩速率为:

%5.2fKB/S\n"

speed);

源文件长度为:

FileLength);

sumlength=sumlength+4+n*2+count;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1