編寫報(bào)告能讓我們對(duì)自己未來(lái)的工作有更透徹的理解,隨著人們自身素質(zhì)提升。我們通常會(huì)使用到報(bào)告,撰寫報(bào)告需要注意哪些內(nèi)容呢?出國(guó)留學(xué)網(wǎng)的編輯認(rèn)真整理了大量信息推出了這篇數(shù)據(jù)結(jié)構(gòu)報(bào)告,本文供你參考,希望能幫到你!
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇1】
一、實(shí)驗(yàn)?zāi)康募耙?/strong>
1)掌握棧和隊(duì)列這兩種特殊的線性表,熟悉它們的特性,在實(shí)際問(wèn)題背景下靈活運(yùn)用它們。
本實(shí)驗(yàn)訓(xùn)練的要點(diǎn)是“?!焙汀瓣?duì)列”的觀點(diǎn);
二、實(shí)驗(yàn)內(nèi)容
1) 利用棧,實(shí)現(xiàn)數(shù)制轉(zhuǎn)換。
2) 利用棧,實(shí)現(xiàn)任一個(gè)表達(dá)式中的語(yǔ)法檢查(選做)。
3) 編程實(shí)現(xiàn)隊(duì)列在兩種存儲(chǔ)結(jié)構(gòu)中的基本操作(隊(duì)列的初始化、判隊(duì)列空、入隊(duì)列、出隊(duì)列);
三、實(shí)驗(yàn)流程、操作步驟或核心代碼、算法片段
順序棧:
Status InitStack(SqStack &S)
{
S.base=(ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemType));
if(!S.base)
return ERROR;
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status DestoryStack(SqStack &S)
{
free(S.base);
return OK;
}
Status ClearStack(SqStack &S)
{
S.top=S.base;
return OK;
}
Status StackEmpty(SqStack S)
{
if(S.base==S.top)
return OK;
return ERROR;
}
int StackLength(SqStack S)
{
return S.top-S.base;
}
Status GetTop(SqStack S,ElemType &e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(ElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemType));
if(!S.base) return ERROR;
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return OK;
}
Status Push(SqStack &S,ElemType e)
{
if(S.top-S.base>=S.stacksize)
{
S.base=(ElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemType));
if(!S.base)
return ERROR;
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top++=e;
return OK;
}
Status Pop(SqStack &S,ElemType &e)
{
if(S.top==S.base)
return ERROR;
e=*--S.top;
return OK;
}
Status StackTraverse(SqStack S)
{
ElemType *p;
p=(ElemType *)malloc(sizeof(ElemType));
if(!p) return ERROR;
p=S.top;
while(p!=S.base)//S.top上面一個(gè)...
{
p--;
printf("%d ",*p);
}
return OK;
}
Status Compare(SqStack &S)
{
int flag,TURE=OK,FALSE=ERROR;
ElemType e,x;
InitStack(S);
flag=OK;
printf("請(qǐng)輸入要進(jìn)?;虺鰲5脑兀?);
while((x= getchar())!='#'&&flag)
{
switch (x)
{
case '(':
case '[':
case '{':
if(Push(S,x)==OK)
printf("括號(hào)匹配成功!\n\n");
break;
case ')':
if(Pop(S,e)==ERROR || e!='(')
{
printf("沒(méi)有滿足條件\n");
flag=FALSE;
}
break;
case ']':
if ( Pop(S,e)==ERROR || e!='[')
flag=FALSE;
break;
case '}':
if ( Pop(S,e)==ERROR || e!='{')
flag=FALSE;
break;
}
}
if (flag && x=='#' && StackEmpty(S))
return OK;
else
return ERROR;
}
鏈隊(duì)列:
Status InitQueue(LinkQueue &Q)
{
Q.front =Q.rear=
(QueuePtr)malloc(sizeof(QNode));
if (!Q.front) return ERROR;
Q.front->next = NULL;
return OK;
}
Status DestoryQueue(LinkQueue &Q)
{
while(Q.front)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
return OK;
}
Status QueueEmpty(LinkQueue &Q)
{
if(Q.front->next==NULL)
return OK;
return ERROR;
}
Status QueueLength(LinkQueue Q)
{
int i=0;
QueuePtr p,q;
p=Q.front;
while(p->next)
{
i++;
p=Q.front;
q=p->next;
p=q;
}
return i;
}
Status GetHead(LinkQueue Q,ElemType &e)
{
QueuePtr p;
p=Q.front->next;
if(!p)
return ERROR;
e=p->data;
return e;
}
Status ClearQueue(LinkQueue &Q)
{
QueuePtr p;
while(Q.front->next )
{
p=Q.front->next;
free(Q.front);
Q.front=p;
}
Q.front->next=NULL;
Q.rear->next=NULL;
return OK;
}
Status EnQueue(LinkQueue &Q,ElemType e)
{
QueuePtr p;
p=(QueuePtr)malloc(sizeof (QNode));
if(!p)
return ERROR;
p->data=e;
p->next=NULL;
Q.rear->next = p;
Q.rear=p; //p->next 為空
return OK;
}
Status DeQueue(LinkQueue &Q,ElemType &e)
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇2】
一、實(shí)驗(yàn)?zāi)康模?BR> 了解哈夫曼樹(shù)的思想和相關(guān)概念;
1.初始化:能夠?qū)斎氲娜我忾L(zhǎng)度的字符串s進(jìn)行統(tǒng)計(jì),統(tǒng)計(jì)每個(gè)字符的頻度,并建立哈夫曼樹(shù)。
2.建立編碼表:利用已經(jīng)建好的哈夫曼樹(shù)進(jìn)行編碼,并將每個(gè)字符的編碼輸出。
3.編碼:根據(jù)編碼表對(duì)輸入的字符串進(jìn)行編碼,并將編碼后的字符串輸出。
4.譯碼:利用已經(jīng)建好的哈夫曼樹(shù)對(duì)編碼后的字符串進(jìn)行譯碼,并輸出譯碼結(jié)果。
6.計(jì)算輸入的字符串編碼前和編碼后的長(zhǎng)度,并進(jìn)行分析,討論哈夫曼編碼的壓縮效果。
7.用戶界面可以設(shè)計(jì)成“菜單”方式,能進(jìn)行交互,根據(jù)輸入的字符串中每個(gè)字符出現(xiàn)的次數(shù)統(tǒng)計(jì)頻度,對(duì)沒(méi)有出現(xiàn)的字符一律不用編碼。
Data:
哈夫曼樹(shù)類的數(shù)據(jù)域,繼承節(jié)點(diǎn)類型為int的二叉樹(shù) class HuffmanTree:public BiTree
data:
struct BiNode //二叉樹(shù)的結(jié)點(diǎn)結(jié)構(gòu) {
};
待編碼字符串由鍵盤輸入,輸入時(shí)用鏈表存儲(chǔ),鏈表節(jié)點(diǎn)為 struct Node
1.初始化函數(shù)(void HuffmanTree::Init(string Input))
2.獲得輸入字符串的第一個(gè)字符,并將其插入到鏈表尾部,n=1(n記錄的是鏈表
3.1 將當(dāng)前取出的字符與鏈表中已經(jīng)存在的字符逐個(gè)比較,如果當(dāng)前取出
的字符與鏈表中已經(jīng)存在的某個(gè)字符相同,則鏈表中該字符的權(quán)值加1。
3.2 如果當(dāng)前取出的字符與鏈表中已經(jīng)存在的字符都不相同,則將其加入
到鏈表尾部,同時(shí)n++
4.tSize=n(tSize記錄鏈表中字符總數(shù),即哈夫曼樹(shù)中葉子節(jié)點(diǎn)總數(shù))
源代碼:
{
Node *front=new Node; //初始化鏈表的頭結(jié)點(diǎn)
throw exception(“堆空間用盡”);
front->next=NULL;
front->character=NULL;
front->count=0;
Node *pfront=front;
Node* New1=new Node;
throw exception(“堆空間用盡”);
New1->character=ch; //將第一個(gè)字符插入鏈表
New1->count=1;
New1->next=pfront->next;
pfront->next=New1;
bool replace=0; //判斷在已經(jīng)寫入鏈表的字符中是否有與當(dāng)前讀出的字符相同的字符 int n=1; //統(tǒng)計(jì)鏈表中字符個(gè)數(shù)
{
pfront=pfront->next;
if((int)pfront->character == (int)ch) //如果在鏈表中有與當(dāng)前字符相同的字符,
{
pfront->count++;
replace=1;
break;
}
}while(pfront->next);
if(!replace) //如果在鏈表中沒(méi)找到與當(dāng)前字符相同的字符,則將該字符作為新成 員插入鏈表
{
Node* New=new Node;
throw exception(“堆空間用盡”);
New->character=ch;
New->count=1;
New->next=pfront->next;
pfront->next=New;
n++;
}
pfront=front; //重置pfront和replace變量為默認(rèn)值 replace=0;
}
pfront=front;
{
front=pfront;
pfront=pfront->next;
front;
}
時(shí)間復(fù)雜度:
2.創(chuàng)建哈夫曼樹(shù)(void HuffmanTree::CreateCodeTable(Node *p))
算法偽代碼:
2. 將存儲(chǔ)字符及其權(quán)值的鏈表中的字符逐個(gè)寫入三叉鏈表的前tSize個(gè)結(jié)點(diǎn)
3.1 從存儲(chǔ)字符及其權(quán)值的鏈表中取出兩個(gè)權(quán)值最小的結(jié)點(diǎn)x,y,記錄其
下標(biāo)x,y。
3.3 將下標(biāo)為x的結(jié)點(diǎn)設(shè)置為i結(jié)點(diǎn)的左孩子,將下標(biāo)為y的結(jié)點(diǎn)設(shè)置為
源代碼:
void HuffmanTree::CreateHTree(Node *p,int n)
{
root= new BiNode[2*n-1]; //初始化哈夫曼樹(shù)
Node *front=p->next;
throw exception(“沒(méi)有輸入字符”);
root[i].data=front->count;
root[i].lchild=-1;
root[i].rchild=-1;
root[i].parent=-1;
front=front->next;
}
front=p;
int New1,New2;
{
SelectMin(New1,New2,0,i); //從0~i中選出兩個(gè)權(quán)值最小的結(jié)點(diǎn)
root[New1].parent=root[New2].parent=i; //用兩個(gè)權(quán)值最小的結(jié)點(diǎn)生成新結(jié)點(diǎn),
root[i].data=root[New1].data+root[New2].data;//新結(jié)點(diǎn)的權(quán)值為其孩子的權(quán)值的和 root[i].lchild=New1;
root[i].rchild=New2;
root[i].parent=-1;
}
}
時(shí)間復(fù)雜度:
在選取兩個(gè)權(quán)值最小的結(jié)點(diǎn)的函數(shù)中要遍歷鏈表,時(shí)間復(fù)雜度為O(n),故該函數(shù)
3.創(chuàng)建編碼表(void HuffmanTree::CreateCodeTable(Node *p))
2.4.1 如果當(dāng)前葉子結(jié)點(diǎn)是其雙親的左孩子,則其對(duì)應(yīng)的編碼為0,否
2.4.2 child指針指向葉子結(jié)點(diǎn)的雙親,parent指針指向child指針的雙親,
源代碼:
void HuffmanTree::CreateCodeTable(Node *p)
{
HCodeTable=new HCode[tSize]; //初始化編碼表
Node *front=p->next;
{
HCodeTable[i].data=front->character; //將第i個(gè)字符寫入編碼表
int parent=root[i].parent; //得到第i個(gè)字符對(duì)應(yīng)的葉子節(jié)點(diǎn)的雙親
int k=0;
if(tSize==1) //如果文本中只有一種字符,它的編碼為0
{
HCodeTable[i].code[k]='0';
k++;
}
while(parent!=-1) //從第i個(gè)字符對(duì)應(yīng)的葉子節(jié)點(diǎn)開(kāi)始,尋找它到根結(jié)點(diǎn)的路徑
{
if(child==root[parent].lchild) //如果當(dāng)前結(jié)點(diǎn)為雙親的左孩子,則編碼為0,
HCodeTable[i].code[k]='0';
HCodeTable[i].code[k]='1';
k++;
child=parent;
parent=root[child].parent;
}
HCodeTable[i].code[k]='';
Reverse(HCodeTable[i].code); //將編碼逆置
}
{
cout
parent=root[parent].lchild;
parent=root[parent].rchild;
i++;
}
if(tSize==1) //如果編碼表只有一個(gè)字符,則根結(jié)點(diǎn)即為葉子結(jié)點(diǎn) i++;
d.append(1,HCodeTable[parent].data);//將葉子節(jié)點(diǎn)對(duì)應(yīng)的字符追加到解碼串中 }
cout
}
時(shí)間復(fù)雜度:
8. 計(jì)算哈夫曼編碼的壓縮比(void HuffmanTree::Calculate(string s1,string s2)) 算法偽代碼:
2. 獲得編碼后的字符串的長(zhǎng)度,將其除以8然后向上取整,得到其占用的字
源代碼:
void HuffmanTree::Calculate(string s1,string s2)
{
int cal1=s1.length();
int cal2=s2.length();
cal2=ceill((float)cal2/8); //將編碼串的比特?cái)?shù)轉(zhuǎn)化為字節(jié)數(shù) cout
cout
cout
9. 打印哈夫曼樹(shù)(void HuffmanTree::PrintTree(int TreeNode,int layer) ) 算法偽代碼:
3. 根據(jù)當(dāng)前結(jié)點(diǎn)所在的層次確定其前面要輸出多少空格,先輸出空格,在打
源代碼:
void HuffmanTree::PrintTree(int TreeNode,int layer)
{
if(TreeNode==-1) //如果待打印結(jié)點(diǎn)為空,則返回 return;
{
PrintTree(root[TreeNode].rchild,layer+1); //先打印該結(jié)點(diǎn)的右子樹(shù),layer記錄
cout
cout
PrintTree(root[TreeNode].lchild,layer+1); //打印該結(jié)點(diǎn)的左子樹(shù)
}
}
10. 菜單函數(shù)(void HuffmanTree::Menu())
算法偽代碼:
1. 逐一讀取鍵盤緩存區(qū)中的字符,并將它們逐一追加到記錄輸入字符串的
3.利用string變量創(chuàng)建哈夫曼樹(shù),初始化編碼表。
cout
string Input;
char letter;
{
letter=cin.get();
Input.append(1,letter);
}while(letter!=' ');
Input.erase(Input.length()-1,1); //去掉Input末尾的回車符
Init(Input); //根據(jù)輸入的字符串創(chuàng)建哈夫曼樹(shù)及其編碼表 cout
PrintTree(2*tSize-1-1,1); //打印哈夫曼樹(shù)
cout
string d1,d2;
cout
cout
cout
Calculate(Input,d1); //計(jì)算編碼前后的壓縮比
1.由于題目要求能輸入任意長(zhǎng)的字符串,所以本程序采用了string變量來(lái)記錄輸入
2.打印哈夫曼樹(shù)時(shí)采用了遞歸函數(shù),且采用了凹凸表的形式打印哈夫曼樹(shù)。
主函數(shù)流程圖:
經(jīng)過(guò)這次實(shí)驗(yàn),我了解了哈夫曼樹(shù)的創(chuàng)建過(guò)程,了解了一種不等長(zhǎng)編碼的方法,用設(shè)斷點(diǎn)調(diào)試的方法更加熟練,同時(shí)熟悉了STL中string類型的用法,對(duì)C++更加熟悉
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇3】
二.實(shí)驗(yàn)?zāi)康模?BR> 1、使學(xué)生熟練掌握哈夫曼樹(shù)的生成算法。
2、熟練掌握哈夫曼編碼的方法。
三.問(wèn)題描述:
已知n個(gè)字符在原文中出現(xiàn)的頻率,求它們的哈夫曼編碼。
1、讀入n個(gè)字符,以及字符的權(quán)值,試建立一棵Huffman樹(shù)。
2、根據(jù)生成的Huffman樹(shù),求每個(gè)字符的Huffman編碼。并對(duì)給定的待編碼字符序列進(jìn)行編碼,并輸出。
typedef struct{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; //動(dòng)態(tài)分配數(shù)組存儲(chǔ)郝夫曼樹(shù)
typedef char* *HuffmanCode;//動(dòng)態(tài)分配數(shù)組存儲(chǔ)郝夫曼編碼
(2)主要的實(shí)現(xiàn)思路:
1.基本上沒(méi)有什么太大的問(wèn)題,在調(diào)用select這個(gè)函數(shù)時(shí),想把權(quán)值最小的兩個(gè)結(jié)點(diǎn)的序號(hào)帶回HuffmanCoding,所以把那2個(gè)序號(hào)設(shè)置成了引用。
2.在編程過(guò)程中,在什么時(shí)候分配內(nèi)存,什么時(shí)候初始化花的時(shí)間比較長(zhǎng)
3.最后基本上實(shí)現(xiàn)后,發(fā)現(xiàn)結(jié)果仍然存在問(wèn)題,經(jīng)過(guò)分步調(diào)試,發(fā)現(xiàn)了特別低級(jí)的輸入錯(cuò)誤。把HT[i].weight=HT[s1].weight+HT[s2].weight;中的s2寫成了i
typedef struct{
int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char* *HuffmanCode;
void Select(HuffmanTree &HT,int k,int &s1,int &s2)
{ int i;
i=1;
while(i
s1=i;
{
if(HT[i].parent==0&&HT[i].weight
{
if(HT[i].parent==0&&i!=s1)break;
}
s2=i;
{
if(HT[i].parent==0&&i!=s1&&HT[i].weight
}
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)
{
int m,c,f,s1,s2,i,start;
char *cd;
if(n
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); //0號(hào)單元未用,預(yù)分配m+1個(gè)單元
HuffmanTree p=HT+1;
{
p->weight=*w;
p->parent=p->rchild=p->lchild=0;
{
p->weight=p->parent=p->rchild=p->lchild=0;
{
Select(HT,i-1,s1,s2); //選出當(dāng)前權(quán)值最小的
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
HC=(HuffmanCode)malloc((n+1)*sizeof(char*)); //分配n個(gè)字符編碼的頭指針變量
cd=(char*)malloc(n*sizeof(char)); //分配求編碼的工作空間
for(i=1;i
for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent) //從葉子到根逆向求編碼
{
if(HT[f].lchild==c)cd[--start]='0';
cd[--start]='1';
}
HC[i]=(char*)malloc((n-start)*sizeof(char)); //為第i個(gè)字符編碼分配空間
strcpy(HC[i],&cd[start]);//從cd復(fù)制編碼到HC
HuffmanTree HT;
HuffmanCode HC;
cout
cin>>n;
w=(int*)malloc((n+1)*sizeof(int)); //記錄權(quán)值,號(hào)單元未用
ch=(char*)malloc((n+1)*sizeof(char));//記錄字符,號(hào)單元未用
cout
{
cout
}
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇4】
首先你要知道什么是數(shù)據(jù)結(jié)構(gòu),學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)的意義。這將是你學(xué)習(xí)的動(dòng)力所在。計(jì)算機(jī)軟件都用到了數(shù)據(jù)結(jié)構(gòu)。所以,學(xué)好數(shù)據(jù)結(jié)構(gòu)對(duì)于你將來(lái)從事計(jì)算機(jī)編程類的工作有十分重要的作用。
數(shù)據(jù)結(jié)構(gòu)中的基本概念,你要一定清楚。平時(shí)要多看書,要在計(jì)算機(jī)上去調(diào)試程序,在調(diào)試的過(guò)程中,你才能發(fā)現(xiàn)自己的問(wèn)題,然后及時(shí)解決。在上機(jī)調(diào)試的過(guò)程中,更要大膽嘗試,注重運(yùn)用。拿到一個(gè)題時(shí),更要深入分析,嘗試用不同的算法去設(shè)計(jì)。當(dāng)然編程的時(shí)候,要注意格式。比如:變量一定要先定義后使用。變量的定義不要定義在中間。
算法與數(shù)據(jù)結(jié)構(gòu)是緊密聯(lián)系,所以你算法一定要會(huì)。如果你是學(xué)生,只需把課本上出現(xiàn)的搞懂就好了,比如線性表的插入,刪除,查找算法,它都是固定的。你就要理解,當(dāng)然你要學(xué)會(huì)畫圖。對(duì)于書中的內(nèi)容要熟悉。
數(shù)據(jù)結(jié)構(gòu)的大綱如下:線性表、棧和隊(duì)列,串、數(shù)組和廣義表、樹(shù)與森林、圖、還有就是查找和排序。簡(jiǎn)單的總結(jié)一下也就是它的邏輯結(jié)構(gòu):線性結(jié)構(gòu)和非線性結(jié)構(gòu)。這些基本的內(nèi)容你如果搞懂了,你的數(shù)據(jù)結(jié)構(gòu)也就學(xué)好了。
要嚴(yán)格要求自己。在學(xué)習(xí)算法的過(guò)程中,你要想它為什么要這樣設(shè)計(jì)?它的優(yōu)點(diǎn)在哪里?想著去改進(jìn)算法,慢慢的的你的邏輯思維能力也就提高了。你會(huì)發(fā)現(xiàn)其實(shí)數(shù)據(jù)結(jié)構(gòu)也就那么回事,不是很難。
有不懂得地方要及時(shí)請(qǐng)教老師,不要不懂裝懂。不要放過(guò)任何一個(gè)細(xì)節(jié),因?yàn)槲业膶I(yè)就是計(jì)算機(jī),所以有很多都是深有體會(huì)。
首先你要清楚一周內(nèi)所要做的事情,然后制定一張作息時(shí)間表。在表上填上那些非花不可的時(shí)間,如吃飯、睡覺(jué)、上課、娛樂(lè)等。安排這些時(shí)間之后,選定合適的、固定的時(shí)間用于學(xué)習(xí),必須留出足夠的時(shí)間來(lái)完成正常的閱讀和課后作業(yè)。當(dāng)然,學(xué)習(xí)不應(yīng)該占據(jù)作息時(shí)間表上全部的空閑時(shí)間,總得給休息、業(yè)余愛(ài)好、娛樂(lè)留出一些時(shí)間,這一點(diǎn)對(duì)學(xué)習(xí)很重要。一張作息時(shí)間表也許不能解決你所有的問(wèn)題,但是它能讓你了解如何支配你這一周的時(shí)間,從而使你有充足的時(shí)間學(xué)習(xí)和娛樂(lè)。
這就意味著在你認(rèn)真投入學(xué)習(xí)之前,先把要學(xué)習(xí)的內(nèi)容快速瀏覽一遍,了解學(xué)習(xí)的大致內(nèi)容及結(jié)構(gòu),以便能及時(shí)理解和消化學(xué)習(xí)內(nèi)容。當(dāng)然,你要注意輕重詳略,在不太重要的地方你可以花少點(diǎn)時(shí)間,在重要的地方,你可以稍微放慢學(xué)習(xí)進(jìn)程。
學(xué)習(xí)成績(jī)好的學(xué)生很大程度上得益于在課堂上充分利用時(shí)間,這也意味著在課后少花些功夫。課堂上要及時(shí)配合老師,做好筆記來(lái)幫助自己記住老師講授的內(nèi)容,尤其重要的是要積極地獨(dú)立思考,跟得上老師的思維。
課堂上做的筆記你要在課后及時(shí)復(fù)習(xí),不僅要復(fù)習(xí)老師在課堂上講授的重要內(nèi)容,還要復(fù)習(xí)那些你仍感模糊的認(rèn)識(shí)。如果你堅(jiān)持定期復(fù)習(xí)筆記和課本,并做一些相關(guān)的習(xí)題,你定能更深刻地理解這些內(nèi)容,你的記憶也會(huì)保持更久。定期復(fù)習(xí)能有效地提高你的考試成績(jī)。
選擇某個(gè)地方作你的學(xué)習(xí)之處,這一點(diǎn)很重要。它可以是你的單間書房或教室或圖書館,但是它必須是舒適的,安靜而沒(méi)有干擾。當(dāng)你開(kāi)始學(xué)習(xí)時(shí),你應(yīng)該全神貫注于你的功課,切忌“身在曹營(yíng)心在漢”。
平時(shí)測(cè)驗(yàn)的目的主要看你掌握功課程度如何,所以你不要弄虛作假,而應(yīng)心平氣和地對(duì)待它。或許,你有一兩次考試成績(jī)不盡如人意,但是這不要緊,只要學(xué)習(xí)扎實(shí),認(rèn)真對(duì)待,下一次一定會(huì)考出好成績(jī)來(lái)。通過(guò)測(cè)驗(yàn),可讓你了解下一步學(xué)習(xí)更需要用功夫的地方,更有助于你把新學(xué)的知識(shí)記得牢固。
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇5】
一、需求分析1、程序所實(shí)現(xiàn)的功能;2、程序的輸入,包含輸入的數(shù)據(jù)格式和說(shuō)明;3、程序的輸出,程序輸出的形式;4、測(cè)試數(shù)據(jù),如果程序輸入的數(shù)據(jù)量比較大,需要給出測(cè)試數(shù)據(jù);5、合作人及其分工二、設(shè)計(jì)說(shuō)明1、主要的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)說(shuō)明;2、程序的主要流程圖;3、程序的主要模塊,要求對(duì)主要流程圖中出現(xiàn)的模塊進(jìn)行說(shuō)明4、程序的主要函數(shù)及其偽代碼說(shuō)明(不需要完整的代碼);5、合作人設(shè)計(jì)分工三、上機(jī)結(jié)果及體會(huì)1、合作人編碼分工2、實(shí)際完成的情況說(shuō)明(完成的功能,支持的數(shù)據(jù)類型等);3、程序的性能分析,包括時(shí)空分析;4、上機(jī)過(guò)程中出現(xiàn)的問(wèn)題及其解決方案;5、程序中可以改進(jìn)的地方說(shuō)明;6、程序中可以擴(kuò)充的功能及設(shè)計(jì)實(shí)現(xiàn)假想;說(shuō)明:1、如果程序比較大,可以將設(shè)計(jì)說(shuō)明分為概要設(shè)計(jì)和詳細(xì)設(shè)計(jì)兩部分。概要設(shè)計(jì)主要負(fù)責(zé)程序的流程、模塊、抽象數(shù)據(jù)類型設(shè)計(jì);詳細(xì)設(shè)計(jì)負(fù)責(zé)程序的數(shù)據(jù)類型定義和主要函數(shù)的說(shuō)明。2、設(shè)計(jì)說(shuō)明中,不需要寫出代碼或者模塊的詳細(xì)代碼,只需要寫出主要函數(shù)的偽代碼說(shuō)明。
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇6】
1)掌握棧和隊(duì)列這兩種特殊的線性表,熟悉它們的特性,在實(shí)際問(wèn)題背景下靈活運(yùn)用它們。
本實(shí)驗(yàn)訓(xùn)練的要點(diǎn)是“?!焙汀瓣?duì)列”的觀點(diǎn);
1) 利用棧,實(shí)現(xiàn)數(shù)制轉(zhuǎn)換。
2) 利用棧,實(shí)現(xiàn)任一個(gè)表達(dá)式中的語(yǔ)法檢查(選做)。
3) 編程實(shí)現(xiàn)隊(duì)列在兩種存儲(chǔ)結(jié)構(gòu)中的基本操作(隊(duì)列的初始化、判隊(duì)列空、入隊(duì)列、出隊(duì)列);
順序棧:
Status InitStack(SqStack &S)
{
S.base=(ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemType));
return ERROR;
=S.base;
S.stacksize=STACK_INIT_SIZE;
return OK;
}
Status DestoryStack(SqStack &S)
{
free(S.base);
return OK;
}
Status ClearStack(SqStack &S)
{
=S.base;
return OK;
}
return OK;
return ERROR;
}
{
return -S.base;
}
Status GetTop(SqStack S,ElemType &e)
{
if(-S.base>=S.stacksize)
{
S.base=(ElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemType));
if(!S.base) return ERROR;
=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*++=e;
return OK;
}
Status Push(SqStack &S,ElemType e)
{
if(-S.base>=S.stacksize)
{
S.base=(ElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(ElemType));
return ERROR;
=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*++=e;
return OK;
}
Status Pop(SqStack &S,ElemType &e)
return ERROR;
e=*--;
return OK;
}
{
ElemType *p;
p=(ElemType *)malloc(sizeof(ElemType));
if(!p) return ERROR;
p=;
while(p!=S.base)//上面一個(gè)...
{
p--;
printf(“%d ”,*p);
}
return OK;
}
{
int flag,TURE=OK,FALSE=ERROR;
ElemType e,x;
InitStack(S);
flag=OK;
while((x= getchar)!='#'&&flag)
case '{':
printf(“括號(hào)匹配成功!nn”);
break;
printf(“沒(méi)有滿足條件n”);
flag=FALSE;
}
break;
break;
break;
}
}
if (flag && x=='#' && StackEmpty(S))
return ERROR;
}
鏈隊(duì)列:
Status InitQueue(LinkQueue &Q)
{
Q.front =Q.rear=
(QueuePtr)malloc(sizeof(QNode));
if (!Q.front) return ERROR;
Q.front->next = NULL;
return OK;
}
Status DestoryQueue(LinkQueue &Q)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
return OK;
}
Status QueueEmpty(LinkQueue &Q)
{
return OK;
return ERROR;
}
{
int i=0;
QueuePtr p,q;
p=Q.front;
{
i++;
p=Q.front;
q=p->next;
p=q;
}
return i;
}
Status GetHead(LinkQueue Q,ElemType &e)
{
QueuePtr p;
p=Q.front->next;
return ERROR;
e=p->data;
return e;
}
Status ClearQueue(LinkQueue &Q)
{
QueuePtr p;
{
p=Q.front->next;
free(Q.front);
Q.front=p;
}
Q.front->next=NULL;
Q.rear->next=NULL;
return OK;
}
Status EnQueue(LinkQueue &Q,ElemType e)
{
QueuePtr p;
p=(QueuePtr)malloc(sizeof (QNode));
return ERROR;
p->data=e;
p->next=NULL;
Q.rear->next = p;
return OK;
}
Status DeQueue(LinkQueue &Q,ElemType &e)
{
QueuePtr p;
return ERROR;
p = Q.front->next;
e = p->data;
Q.front->next = p->next;
Q.rear = Q.front; //只有一個(gè)元素時(shí)(不存在指向尾指針)
free (p);
return OK;
}
Status QueueTraverse(LinkQueue Q)
{
QueuePtr p,q;
{
printf(“這是一個(gè)空隊(duì)列!n”);
return ERROR;
}
p=Q.front->next;
{
q=p;
printf(“%ddata);
q=p->next;
p=q;
}
return OK;
}
循環(huán)隊(duì)列:
Status InitQueue(SqQueue &Q)
{
Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
exit(OWERFLOW);
Q.front=Q.rear=0;
return OK;
}
Status EnQueue(SqQueue &Q,QElemType e)
{
if((Q.rear+1)%MAXQSIZE==Q.front)
return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
Status DeQueue(SqQueue &Q,QElemType &e)
return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
{
return(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}
Status DestoryQueue(SqQueue &Q)
{
free(Q.base);
return OK;
}
Status QueueEmpty(SqQueue Q) //判空
return OK;
return ERROR;
}
printf(“這是一個(gè)空隊(duì)列!”);
Q.front++;
}
return OK;
}
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇7】
1、進(jìn)一步掌握指針變量的含義及應(yīng)用。
2、掌握二叉樹(shù)的結(jié)構(gòu)特征,以及各種存儲(chǔ)結(jié)構(gòu)的`特點(diǎn)及使用范圍。
3、掌握用指針類型描述、訪問(wèn)和處理二叉樹(shù)的運(yùn)算。
題目1:編寫一個(gè)程序,采用一棵二叉樹(shù)表示一個(gè)家譜關(guān)系。要求程序具有如下功能:
(1)用括號(hào)表示法輸出家譜二叉樹(shù),
(2)查找某人的所有兒子,
為了能夠用二叉樹(shù)表示配偶、子女、兄弟三種關(guān)系,特采用以下存儲(chǔ)關(guān)系,則能在二叉樹(shù)上實(shí)現(xiàn)家譜的各項(xiàng)運(yùn)算。
二叉樹(shù)型存儲(chǔ)結(jié)構(gòu)定義為:
struct SNODE *right; //指向兄弟或子女結(jié)點(diǎn)
實(shí)驗(yàn)由主函數(shù)、家譜建立函數(shù)、家譜輸出函數(shù)、兒子查找函數(shù)、祖先查找函數(shù)、結(jié)點(diǎn)定位函數(shù)、選擇界面函數(shù)七個(gè)函數(shù)共同組成。其功能描述如下:
void InitialFamily(FNODE *&head) //家譜建立函數(shù)
輸出形式為:父和母(子1和子妻1(孫1),子2和子妻2(孫2))
void PrintFamily(FNODE *head) //家譜輸出函數(shù)
(4)兒子查找函數(shù):在家譜中查找到某人所有的子女并輸出,同時(shí)也能辨別出其是否為家族成員與是否有子女
void FindSon(FNODE *b,char p[]) //兒子查找函數(shù)
(5)祖先查找函數(shù):在家譜中查找到某人所有的祖先并輸出,同時(shí)也能辨別出其是否為家族中成員。
int FindAncestor(FNODE *head,char son[ ]) //祖先查找函數(shù)
FNODE *findnode(FNODE *b,char p[]) //結(jié)點(diǎn)定位函數(shù)
(7)選擇界面函數(shù):為便于編寫程序,將用戶選擇部分獨(dú)立為此函數(shù)。
(三)各函數(shù)的詳細(xì)設(shè)計(jì):
void InitialFamily(FNODE *&head) //家譜建立函數(shù)
1:首先建立當(dāng)前人的信息,將其左右結(jié)點(diǎn)置為空,
2:然后讓用戶確定其是否有配偶,如果沒(méi)有配偶,則當(dāng)前程序結(jié)束,
3:如果有則建立其配偶信息,并將配偶結(jié)點(diǎn)賦給當(dāng)前人的左結(jié)點(diǎn);
4:再讓用戶確定其是否有子女,如果有則遞歸調(diào)用家譜建立函數(shù)建立子女結(jié)點(diǎn),并將其賦給配偶結(jié)點(diǎn)的下一個(gè)右結(jié)點(diǎn)。
void PrintFamily(FNODE *head) //家譜輸出函數(shù)
1:首先判斷當(dāng)前結(jié)點(diǎn)是否為空,如果為空則結(jié)束程序;
3:然后判斷其左結(jié)點(diǎn)(配偶結(jié)點(diǎn))是否為空,如不為空則輸出“和配偶信息。
4:再判斷配偶結(jié)點(diǎn)的右結(jié)點(diǎn)是否為空,如不為空則遞歸調(diào)用輸出其子女信息,最后輸出“)”;
FNODE *findnode(FNODE *b,char p[]) //結(jié)點(diǎn)定位函數(shù)
void FindSon(FNODE *b,char p[]) //兒子查找函數(shù)
1:在家譜中定位到要查找的結(jié)點(diǎn),如無(wú)則輸出“查找不到此人”
2:判斷其配偶結(jié)點(diǎn)與子女結(jié)點(diǎn)是否為空,為空則輸出“無(wú)子女”
3:不為空則輸出其配偶結(jié)點(diǎn)的所有右結(jié)點(diǎn)(子女結(jié)點(diǎn))。
int FindAncestor(FNODE *head,char son[ ]) //祖先查找函數(shù)
1:先在家譜中定位到要查找的結(jié)點(diǎn),如為空輸出“不存在此人”,程序結(jié)束
4:訪問(wèn)過(guò),再判斷是否為查找結(jié)點(diǎn),如是則輸出棧中保存的其祖先結(jié)點(diǎn),并濾過(guò)其兄弟結(jié)點(diǎn)不輸出;不是查找結(jié)點(diǎn),則退棧一個(gè)元素
5:未訪問(wèn)過(guò),則取當(dāng)前棧頂元素,置訪問(wèn)標(biāo)志——1,同時(shí)取其右結(jié)點(diǎn)
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇8】
1.下列程序段的時(shí)間復(fù)雜度為( )。
(A) O(m*n*t) (B) O(m+n+t) (C) O(m+n*t) (D) O(m*t+n)
2.設(shè)順序線性表中有n個(gè)數(shù)據(jù)元素,則刪除表中第i個(gè)元素需要移動(dòng)( )個(gè)元素。
(A) n-i (B) n+l -i (C) n-1-i (D) i
3.設(shè)F是由T1、T2和T3三棵樹(shù)組成的森林,與F對(duì)應(yīng)的二叉樹(shù)為B,T1、T2和T3的結(jié)點(diǎn)數(shù)分別為N1、N2和N3,則二叉樹(shù)B的根結(jié)點(diǎn)的左子樹(shù)的結(jié)點(diǎn)數(shù)為( )。
(A) N1-1 (B) N2-1 (C) N2+N3 (D) N1+N3
4.利用直接插入排序法的思想建立一個(gè)有序線性表的時(shí)間復(fù)雜度為( )。
(A) O(n) (B) O(nlog2n) (C) O(n2) (D) O(1og2n)
5.設(shè)指針變量p指向雙向鏈表中結(jié)點(diǎn)A,指針變量s指向插入的結(jié)點(diǎn)X,則在結(jié)點(diǎn)A的后面插入結(jié)點(diǎn)X的操作序列為( )。
(A) p->right=s; s->left=p; p->right->left=s; s->right=p->right;
(B) s->left=p;s->right=p->right;p->right=s; p->right->left=s;
(C) p->right=s; p->right->left=s; s->left=p; s->right=p->right;
(D) s->left=p;s->right=p->right;p->right->left=s; p->right=s;
6.下列各種排序算法中平均時(shí)間復(fù)雜度為O(n2)是( )。
(A) 快速排序 (B) 堆排序 (C) 歸并排序 (D) 冒泡排序
7.設(shè)輸入序列1、2、3、…、n經(jīng)過(guò)棧作用后,輸出序列中的第一個(gè)元素是n,則輸出序列中的第i個(gè)輸出元素是( )。
(A) n-i (B) n-1-i (C) n+l -i (D) 不能確定
8.設(shè)散列表中有m個(gè)存儲(chǔ)單元,散列函數(shù)H(key)= key % p,則p最好選擇( )。
9.設(shè)在一棵度數(shù)為3的樹(shù)中,度數(shù)為3的結(jié)點(diǎn)數(shù)有2個(gè),度數(shù)為2的結(jié)點(diǎn)數(shù)有1個(gè),度數(shù)為1的結(jié)點(diǎn)數(shù)有2個(gè),那么度數(shù)為0的結(jié)點(diǎn)數(shù)有( )個(gè)。
10.設(shè)完全無(wú)向圖中有n個(gè)頂點(diǎn),則該完全無(wú)向圖中有( )條邊。
(A) n(n-1)/2 (B) n(n-1) (C) n(n+1)/2 (D) (n-1)/2
11.設(shè)順序表的長(zhǎng)度為n,則順序查找的平均比較次數(shù)為( )。
(A) n (B) n/2 (C) (n+1)/2 (D) (n-1)/2
12.設(shè)有序表中的元素為(13,18,24,35,47,50,62),則在其中利用二分法查找值為24的元素需要經(jīng)過(guò)( )次比較。
13.設(shè)順序線性表的長(zhǎng)度為30,分成5塊,每塊6個(gè)元素,如果采用分塊查找,則其平均查找長(zhǎng)度為( )。
14.設(shè)有向無(wú)環(huán)圖G中的有向邊集合E={,,,},則下列屬于該有向圖G的一種拓?fù)渑判蛐蛄械氖? )。
(A) 1,2,3,4 (B) 2,3,4,1 (C) 1,4,2,3 (D) 1,2,4,3
15.設(shè)有一組初始記錄關(guān)鍵字序列為(34,76,45,18,26,54,92),則由這組記錄關(guān)鍵字生成的二叉排序樹(shù)的深度為( )。
1.設(shè)指針p指向單鏈表中結(jié)點(diǎn)A,指針s指向插入的結(jié)點(diǎn)X,則在結(jié)點(diǎn)A的前面插入結(jié)點(diǎn)X時(shí)的操作序列為:
1) s->next=___________;2) p->next=s;3) t=p->data;
4) p->data=___________;5) s->data=t;
2.設(shè)某棵完全二叉樹(shù)中有100個(gè)結(jié)點(diǎn),則該二叉樹(shù)中有______________個(gè)葉子結(jié)點(diǎn)。
3.設(shè)某順序循環(huán)隊(duì)列中有m個(gè)元素,且規(guī)定隊(duì)頭指針F指向隊(duì)頭元素的前一個(gè)位置,隊(duì)尾指針R指向隊(duì)尾元素的當(dāng)前位置,則該循環(huán)隊(duì)列中最多存儲(chǔ)_______隊(duì)列元素。
4.對(duì)一組初始關(guān)鍵字序列(40,50,95,20,15,70,60,45,10)進(jìn)行冒泡排序,則第一趟需要進(jìn)行相鄰記錄的比較的次數(shù)為_(kāi)_________,在整個(gè)排序過(guò)程中最多需要進(jìn)行__________趟排序才可以完成。
5.在堆排序和快速排序中,如果從平均情況下排序的速度最快的角度來(lái)考慮應(yīng)最好選擇_________排序,如果從節(jié)省存儲(chǔ)空間的.角度來(lái)考慮則最好選擇________排序。
6.設(shè)一組初始記錄關(guān)鍵字序列為(20,12,42,31,18,14,28),則根據(jù)這些記錄關(guān)鍵字構(gòu)造的二叉排序樹(shù)的平均查找長(zhǎng)度是_______________________________。
7.設(shè)一棵二叉樹(shù)的中序遍歷序列為BDCA,后序遍歷序列為DBAC,則這棵二叉樹(shù)的前序序列為_(kāi)___________________。
8.設(shè)用于通信的電文僅由8個(gè)字母組成,字母在電文中出現(xiàn)的頻率分別為7、19、2、6、32、3、21、10,根據(jù)這些頻率作為權(quán)值構(gòu)造哈夫曼樹(shù),則這棵哈夫曼樹(shù)的高度為_(kāi)_______________。
9.設(shè)一組記錄關(guān)鍵字序列為(80,70,33,65,24,56,48),則用篩選法建成的初始堆為_(kāi)______________________。
10. 10. 設(shè)無(wú)向圖G(如右圖所示),則其最小生成樹(shù)上所有邊的權(quán)值之和為_(kāi)________________。
3.子串“ABC”在主串“AABCABCD”中的位置為2。( )
4.若一個(gè)葉子結(jié)點(diǎn)是某二叉樹(shù)的中序遍歷序列的最后一個(gè)結(jié)點(diǎn),則它必是該二叉樹(shù)的先序遍歷序列中的最后一個(gè)結(jié)點(diǎn)。( )
6.用鄰接矩陣作為圖的存儲(chǔ)結(jié)構(gòu)時(shí),則其所占用的存儲(chǔ)空間與圖中頂點(diǎn)數(shù)無(wú)關(guān)而與圖中邊數(shù)有關(guān)。( )
8.入棧操作和入隊(duì)列操作在鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)上實(shí)現(xiàn)時(shí)不需要考慮棧溢出的情況。( )
1.設(shè)計(jì)計(jì)算二叉樹(shù)中所有結(jié)點(diǎn)值之和的算法。
2.設(shè)計(jì)將所有奇數(shù)移到所有偶數(shù)之前的算法。
3.設(shè)計(jì)判斷單鏈表中元素是否是遞增的算法。
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇9】
1.判斷鏈表是否存在環(huán)型鏈表問(wèn)題:判斷一個(gè)鏈表是否存在環(huán),例如下面這個(gè)鏈表就存在一個(gè)環(huán):
例如N1->N2->N3->N4->N5->N2就是一個(gè)有環(huán)的鏈表,環(huán)的開(kāi)始結(jié)點(diǎn)是N5這里有一個(gè)比較簡(jiǎn)單的解法,設(shè)置兩個(gè)指針p1,p2。每次循環(huán)p1向前走一步,p2向前走兩步。直到p2碰到NULL指針或者兩個(gè)指針相等結(jié)束循環(huán)。如果兩個(gè)指針相等則說(shuō)明存在環(huán)。
{
int data;
link* next;
};
{
link* p1=head, *p2 = head;
if (head ==NULL || head->next ==NULL)
{
return false;
}
do{
p1= p1->next;
p2 = p2->next->next;
} while(p2 && p2->next && p1!=p2);
return false;
}
2,鏈表反轉(zhuǎn) 單向鏈表的反轉(zhuǎn)是一個(gè)經(jīng)常被問(wèn)到的一個(gè)面試題,也是一個(gè)非常基礎(chǔ)的問(wèn)題。比如一個(gè)鏈表是這樣的: 1->2->3->4->5 通過(guò)反轉(zhuǎn)后成為5->4->3->2->1。最容易想到的方法遍歷一遍鏈表,利用一個(gè)輔助指針,存儲(chǔ)遍歷過(guò)程中當(dāng)前指針指向的下一個(gè)元素,然后將當(dāng)前節(jié)點(diǎn)元素的指針?lè)崔D(zhuǎn)后,利用已經(jīng)存儲(chǔ)的指針往后面繼續(xù)遍歷。源代碼如下:
struct linka {
int data;
linka* next;
};
return;
linka*pre, *cur, *ne;
pre=head;
cur=head->next;
{
ne = cur->next;
cur->next = pre;
pre = cur;
cur = ne;
}
head->next = NULL;
head = pre;
}
還有一種利用遞歸的方法。這種方法的基本思想是在反轉(zhuǎn)當(dāng)前節(jié)點(diǎn)之前先調(diào)用遞歸函數(shù)反轉(zhuǎn)后續(xù)節(jié)點(diǎn)。源代碼如下。不過(guò)這個(gè)方法有一個(gè)缺點(diǎn),就是在反轉(zhuǎn)后的最后一個(gè)結(jié)點(diǎn)會(huì)形成一個(gè)環(huán),所以必須將函數(shù)的返回的節(jié)點(diǎn)的next域置為NULL。因?yàn)橐淖僪ead指針,所以我用了引用。算法的源代碼如下:
linka* reverse(linka* p,linka*& head)
{
if(p == NULL || p->next == NULL)
{
head=p;
{
linka* tmp = reverse(p->next,head);
tmp->next = p;
return p;
}
}
3,判斷兩個(gè)數(shù)組中是否存在相同的數(shù)字 給定兩個(gè)排好序的數(shù)組,怎樣高效得判斷這兩個(gè)數(shù)組中存在相同的數(shù)字?
這個(gè)問(wèn)題首先想到的是一個(gè)O(nlogn)的算法。就是任意挑選一個(gè)數(shù)組,遍歷這個(gè)數(shù)組的所有元素,遍歷過(guò)程中,在另一個(gè)數(shù)組中對(duì)第一個(gè)數(shù)組中的每個(gè)元素進(jìn)行binary search。用C++實(shí)現(xiàn)代碼如下:
bool findcommon(int a[],int size1,int b[],int size2)
{
int i;
for(i=0;i
{
int start=0,end=size2-1,mid;
{
mid=(start+end)/2;
return true;
else if (a[i]
start=mid+1;
}
}
return false;
}
后來(lái)發(fā)現(xiàn)有一個(gè) O(n)算法,
因?yàn)閮蓚€(gè)數(shù)組都是排好序的。所以只要一次遍歷就行了。首先設(shè)兩個(gè)下標(biāo),分別初始化為兩個(gè)數(shù)組的起始地址,依次向前推進(jìn)。推進(jìn)的規(guī)則是比較兩個(gè)數(shù)組中的數(shù)字,小的那個(gè)數(shù)組的下標(biāo)向前推進(jìn)一步,直到任何一個(gè)數(shù)組的下標(biāo)到達(dá)數(shù)組末尾時(shí),如果這時(shí)還沒(méi)碰到相同的數(shù)字,說(shuō)明數(shù)組中沒(méi)有相同的數(shù)字。
bool findcommon2(int a[], int size1, int b[], int size2)
{
int i=0,j=0;
while(ireturn true;j++;if(a[i]i++;}return false;}4,最大子序列 問(wèn)題:給定一整數(shù)序列A1, A2,... An (可能有負(fù)數(shù)),求A1~An的一個(gè)子序列Ai~Aj,使得Ai到Aj的和最大例如:整數(shù)序列-2, 11, -4, 13, -5, 2, -5, -3, 12, -9的最大子序列的和為21。對(duì)于這個(gè)問(wèn)題,最簡(jiǎn)單也是最容易想到的那就是窮舉所有子序列的方法。利用三重循環(huán),依次求出所有子序列的和然后取最大的那個(gè)。當(dāng)然算法復(fù)雜度會(huì)達(dá)到O(n^3)。顯然這種方法不是最優(yōu)的,下面給出一個(gè)算法復(fù)雜度為O(n)的線性算法實(shí)現(xiàn),算法的來(lái)源于Programming Pearls一書。 在給出線性算法之前,先來(lái)看一個(gè)對(duì)窮舉算法進(jìn)行優(yōu)化的算法,它的算法復(fù)雜度為O(n^2)。其實(shí)這個(gè)算法只是對(duì)對(duì)窮舉算法稍微做了一些修改:其實(shí)子序列的和我們并不需要每次都重新計(jì)算一遍。假設(shè)Sum(i, j)是A[i] ... A[j]的和,那么Sum(i, j+1) = Sum(i, j) + A[j+1]。利用這一個(gè)遞推,我們就可以得到下面這個(gè)算法:{int i,j,v,max=a[0];for(i=0;i{v=0;for(j=i;j{v=v+a[j];//Sum(i, j+1) = Sum(i, j) + A[j+1]max=v;}}return max;}那怎樣才能達(dá)到線性復(fù)雜度呢?這里運(yùn)用動(dòng)態(tài)規(guī)劃的思想。先看一下源代碼實(shí)現(xiàn):{int i,max=0,temp_sum=0;for(i=0;i{temp_sum+=a[i];max=temp_sum;temp_sum=0;}return max;}在這一遍掃描數(shù)組當(dāng)中,從左到右記錄當(dāng)前子序列的和temp_sum,若這個(gè)和不斷增加,那么最大子序列的和max也不斷增加(不斷更新max)。如果往前掃描中遇到負(fù)數(shù),那么當(dāng)前子序列的和將會(huì)減小。此時(shí)temp_sum 將會(huì)小于max,當(dāng)然max也就不更新。如果temp_sum降到0時(shí),說(shuō)明前面已經(jīng)掃描的那一段就可以拋棄了,這時(shí)將temp_sum置為0。然后,temp_sum將從后面開(kāi)始將這個(gè)子段進(jìn)行分析,若有比當(dāng)前max大的子段,繼續(xù)更新max。這樣一趟掃描結(jié)果也就出來(lái)了。5, 找出單向鏈表的中間結(jié)點(diǎn) 這道題和解判斷鏈表是否存在環(huán),我用的是非常類似的方法,只不過(guò)結(jié)束循環(huán)的條件和函數(shù)返回值不一樣罷了。設(shè)置兩個(gè)指針p1,p2。每次循環(huán)p1向前走一步,p2向前走兩步。當(dāng)p2到達(dá)鏈表的末尾時(shí),p1指向的時(shí)鏈表的中間。{link* p1,*p2;p1=p2=head;if(head==NULL || head->next==NULL)return head;do {p1=p1->next;p2=p2->next->next;} while(p2 && p2->next);return p1;}來(lái)自:akalius.blog/163319
數(shù)據(jù)結(jié)構(gòu)報(bào)告【篇10】
實(shí)驗(yàn)報(bào)告;課程名稱:數(shù)據(jù)結(jié)構(gòu)班級(jí):軟件工程實(shí)驗(yàn)成績(jī):;1206;實(shí)驗(yàn)名稱:打印機(jī)隊(duì)列模擬學(xué)號(hào):4848批;程序的設(shè)計(jì);實(shí)驗(yàn)編號(hào):實(shí)驗(yàn)一姓名:實(shí)驗(yàn)日期:5月2;一、實(shí)驗(yàn)?zāi)康?對(duì)隊(duì)列的理解;對(duì)STL中的queue的使用;實(shí)驗(yàn)仿真一個(gè)網(wǎng)絡(luò)打印過(guò)程;二、實(shí)驗(yàn)內(nèi)容與實(shí)驗(yàn)步驟流程圖;這個(gè)任務(wù)隊(duì)列的測(cè)試使用STL隊(duì)列適配器;具體地說(shuō),每一行中包含的信息是
這個(gè)任務(wù)隊(duì)列的測(cè)試使用STL隊(duì)列適配器。程序要求完成模擬的實(shí)現(xiàn)共享打印機(jī)。這個(gè)打印機(jī)使用先進(jìn)先出隊(duì)列。仿真是通過(guò)讀取和處理事件數(shù)據(jù)文件的列表。一個(gè)有效的數(shù)據(jù)文件中的每一行包含信息打印作業(yè)和提交這份工作的時(shí)間。
具體地說(shuō),每一行中包含的信息是提交工作的時(shí)間(以秒為單位),和在頁(yè)面的工作長(zhǎng)及工作的計(jì)算機(jī)的名稱。在模擬的開(kāi)始,每個(gè)這些事件的每一個(gè)應(yīng)該被程序所讀,存儲(chǔ)在繼承工作負(fù)載隊(duì)列。程序應(yīng)該通過(guò)循環(huán)遞增計(jì)數(shù)器或while-loop模擬時(shí)間的流逝。程序應(yīng)該將計(jì)數(shù)器初始化為零,然后依次增加1秒。當(dāng)模擬等于當(dāng)前時(shí)間的打印作業(yè)的提交時(shí)間在工作隊(duì)列的前面,一個(gè)打印作業(yè)完成。當(dāng)這一切發(fā)生的時(shí)候,從工作隊(duì)列取出這個(gè)事件,然后把它放在另一個(gè)隊(duì)列對(duì)象。這個(gè)隊(duì)列對(duì)象存儲(chǔ)已完成的打印作業(yè)。當(dāng)程序仿真其他的打印工作的時(shí)候,這些工作在隊(duì)列等待。
#include “simulator.h”
protected:
queue waiting;
priority_queue priority_waiting;
public:
fifo(int seconds_per_page);
void simulate(string file);
};
bool operator
using namespace std;
fifo::fifo(int seconds_per_page):simulator(seconds_per_page){ }
void fifo::simulate(string file){
int finish_time = 0;
float agg_latency = 0;
int totaljob =0;
event evt;
if(file.find(“arbitrary”)!= string::npos){
string outfile =“arbitrary.out”;
ofstream osf(outfile.c_str());
loadworkload(file);
osf
for(int time =1;!waiting.empty()||!workload.empty();time++){ while(!workload.empty() && time ==
workload.front().arrival_time()){
evt= workload.front();
osf
workload.pop();
}
if(!waiting.empty() && time >= finish_time){
totaljob ++;
evt = waiting.front();
agg_latency += time - evt.arrival_time();
osf
finish_time = time + evt.getjob().getnumpages() * seconds_per_page;
}
}
osf
osf
osf
return;
}
if(file.find(“bigfirst”) != string::npos){
string outfile = “bigfirst.out”;
ofstream osf(outfile.c_str());
loadworkload(file);
=1;!priority_waiting.empty()||!workload.empty();time++){
while(!workload.empty() && time ==
workload.front().arrival_time()){
evt= workload.front();
osf
workload.pop();
}
if(!priority_waiting.empty() && time >= finish_time){
totaljob ++;
evt = priority_();
agg_latency += time - evt.arrival_time();
osf
finish_time = time + evt.getjob().getnumpages() * seconds_per_page; }
}
osf
osf
osf
return;
}
cerr
cerr
bool operator
return evtleft.getjob().getnumpages()
evtright.getjob().getnumpages();
經(jīng)測(cè)試,功能較為完整。代碼流程簡(jiǎn)圖如下:
通過(guò)這次實(shí)驗(yàn),我了解了有關(guān)隊(duì)列方面的知識(shí)。掌握了隊(duì)列的邏輯結(jié)構(gòu),抽象數(shù)據(jù)類型,隊(duì)列的存儲(chǔ)方式等。運(yùn)用先進(jìn)先出表,仿真了網(wǎng)絡(luò)打印隊(duì)列。這都使我對(duì)數(shù)據(jù)結(jié)構(gòu)的學(xué)習(xí)有了新的認(rèn)識(shí)與幫助。在實(shí)驗(yàn)過(guò)程中,我也遇到了許多困難,從開(kāi)始時(shí)對(duì)隊(duì)列運(yùn)算的不熟悉,到逐漸查找資料,從而完成了實(shí)驗(yàn);六、附錄;-《數(shù)據(jù)結(jié)構(gòu)與算法分析》以及網(wǎng)上資料;
逐漸查找資料,從而完成了實(shí)驗(yàn)。在今后的學(xué)習(xí)中,我將繼續(xù)努力,加強(qiáng)對(duì)堆棧,隊(duì)列等知識(shí)的學(xué)習(xí),以達(dá)到精益求精。

