日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构——课程设计

發布時間:2023/12/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构——课程设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

課程設計報告

題 目 數據結構課程設計

學生姓名

學 號

院 系 計算機與軟件學院

專 業 信息安全

指導教師

二O二一年十二月二十四日
?
目 錄

一、 任務概述········································5
(一) 棧的應用——后綴表達式實現··································5
(二) 圖的應用——最小生成樹······································5
(三) 圖的應用——活動圖··········································5
(四) 堆排序的應用——Top K問題···································6
二、 算法設計思想····································6
(一) 棧的應用——后綴表達式實現··································6
(二) 圖的應用——最小生成樹······································6
(三) 圖的應用——活動圖··········································7
(四) 堆排序的應用——Top K問題···································7
三、 測試結果········································8
(一) 棧的應用——后綴表達式實現··································8
(二) 圖的應用——最小生成樹······································8
(三) 圖的應用——活動圖··········································9
(四) 堆排序的應用——Top K問題··································10

參考文獻·············································10
附件·················································11

數據結構課程設計

摘要:本文主要介紹了數據結構中的棧、圖和堆排序在具體案例中的應用:利用棧的存儲結構實現了中綴表達式的后綴表示,基于最小生成樹算法實現了無向網中代價最小的路線求解,利用AOE-網求解關鍵路徑并估算某開發項目的完成時間,最后利用堆排序算法解決Top K問題。本文針對這些具體案例,有效地組織、存儲和處理數據,正確地改進或設計滿足功能需求的算法,旨在通過實際應用案例,提升數據結構和算法的編程實現能力,增加系統全面的實踐經歷。
關鍵詞:數據結構;棧 ;圖 ;堆排序

Course design of data structure
Abstract:This paper mainly introduces the application of stack, graph and heap sorting in data structure in specific cases: the suffix representation of infix expression is realized by using the storage structure of stack, the route with the lowest cost in undirected network is solved based on the minimum spanning tree algorithm, the critical path is solved by AOE network, and the completion time of a development project is estimated, Finally, the heap sorting algorithm is used to solve the top k problem. Aiming at these specific cases, this paper effectively organizes, stores and processes data, and correctly improves or designs algorithms to meet functional requirements. The purpose is to improve the programming ability of data structure and algorithms and increase the comprehensive practical experience of the system through practical application cases.
Key words:Data structure Stack Diagram Sorting

一、任務概述

(一)棧的應用——后綴表達式實現

利用一個棧,實現中綴表達式的后綴表示。例如,輸入a+c/d*(e-f)#,輸出acd/ef-*+。其中#為表達式結束標志。要求,棧底元素為#,每次對棧操作時,均應打印輸出當前棧內情況。

(二)圖的應用——最小生成樹

基于最小生成樹算法(兩種典型算法可任選一種或兩種實現),求解無向有權圖中代價最小的路線,打印輸出結果。 請自行選擇圖的存儲結構。
測試用圖如圖1.2.1,1.2.2:

圖1.2.1 圖1.2.2
(三)圖的應用——活動圖

圖的應用。一個軟件開發項目的活動圖如下所示,弧上的數值為需要的開發天數。請用鄰接表實現該圖的存儲。(1)計算輸出每條弧最早發生時間和最遲發生時間;(2)輸出該開發項目的最短開發周期;(2)輸出一旦延期將影響開發進度的全部路徑。如圖1.3.1

圖1.3.1
(四)堆排序的應用——Top K問題
以任務3中的圖為測試例子,定義有向邊結構體(弧尾,弧頭,權值),用弧的結構體數組保存全部弧,并針對該數組,實現堆排序算法,并用其解決Top K排序問題。(2次課)
Top K排序:查找最大的(或最小的)K個元素。
要求分析算法時間復雜度,討論哪些算法適合TopK排序問題,簡述理由。
注意,算法應允許通過參數設置,選擇最大K還是最小K個元素;
二、算法設計思想

(一)棧的應用——后綴表達式實現

1.遇到操作數:直接輸出(添加到后綴表達式中);
2.棧為空時,遇到運算符,直接入棧;
3.遇到左括號:將其入棧;
4.遇到右括號:執行出棧操作,并將出棧的元素輸出,直到彈出棧的是左括號,左括號不輸出;
5.遇到其他運算符:加減乘除:彈出所有優先級大于或者等于該運算符的棧頂元素,然后將該運算符入棧;
6.最終將棧中的元素依次出棧,輸出。

(二) 圖的應用——最小生成樹

Prim(普里姆)算法:
算法思想 —— 歸并頂點
1.在圖中任取一個頂點K作為開始點。令U={k},W=V-U,其中V為圖中所有頂點的集合;
2.在U中選取一個頂點,W中選取另一個頂點,使二者對應的邊是最短的一條。將該邊作為最小生成樹的邊保存起來,并將該邊頂點全部加入U集合中,并從W中刪去這些頂點;
3.重新調整U中頂點到W中頂點的距離, 使之保持最小,再重復此過程,直到W為空集止。

(三) 圖的應用——活動圖

1)要找出一個AOE網中的關鍵路徑,就要先找出網里的關鍵活動,這些關鍵活動間的路徑就是關鍵路徑。
2)判斷一個活動是不是關鍵活動,方法是要先找到所有活動的最早開始時間和最晚開始時間,并且對它們進行比較,如果二者相等(意味著這個活動在該工程中沒有時間松動),說明這個活動是關鍵活動。
3)對于活動<Vi, Vk>,它最早的開始時間等于事件Vi最早的發生時間etv[i](事件v的最早發生時間用etv[k])。假設E[Vi]表示所有到達頂點Vi的弧的集合,len<Vi, Vk>表示活動<Vi, Vk>的持續時間,那么:如圖2.3.1

圖2.3.1
注意,這里假設頂點下標從0開始,所以Vi==0,則表示它是源點,因此最早的開始時間為0;當某個頂點不是源點,那么只有在它前面的事件都發生完后,才能輪到這個事件,所以用了max。
4)對于活動<Vk, Vj>,它最晚的開始時間等于事件Vj最晚的發生時間減去這個活動的持續事件,即ltv[j]-len<Vk, Vj>(事件v的最晚的發生時間用ltv[k])。假設S[Vk]表示所有從頂點Vk出發的弧的集合,len<Vk, Vj>表示活動<Vk, Vj>的持續時間,那么:如圖2.3.2

圖2.3.2

(四) 堆排序的應用——Top K問題

  • 采用順序表存儲表示。
  • 建堆:從最后一個非葉子結點開始,反復篩選。
  • 篩選:
    step 1 得到堆頂元素后,交換堆頂和最后一個元素,此時根結點的左右子樹均為堆; step 2 自上而下重新調整為大頂堆:首先以堆頂元素和左右子樹根節點的值進行比較,若堆頂元素小,則與左右根節點中值較大的交換,重復該步驟直至葉子結點;
    step 3 重復上述過程直至結束。
  • Top K 問題:設置函數參數flag供選擇查找最大或最小k個元素,利用堆排序結果
    輸出最大或最小k個元素。
  • 時間復雜度分析:對深度為k的堆,篩選算法中關鍵字比較次數最多2(k-1)次,故在建立含n個元素,深度為h的堆時,關鍵字總的比較次數不超過4n。而n個結點的完全二叉樹深度為(log2(n)+1)向下取整,調整建新堆時調用heapadjust過程(n-1)次,總比較次數不超過2n(log2(n)),故堆排序在最壞情況下時間復雜度為O(nlogn)。
  • Top K排序問題宜采用算法及理由:
    堆排序:用一個小頂堆維護大小為k的數組,時間復雜度為O(nlogk),該算法不需要一次將原數組中的內容全部加載到內存中,可以處理較大的數據量。
    快速排序:利用找分割點的方法,時間復雜度低。
    三、測試結果
  • (一)棧的應用——后綴表達式實現

    如圖3.1.1

    圖3.1.1

    (二)圖的應用——最小生成樹

    如圖3.2.1,3.2.2:

    圖3.2.1

    圖3.2.2

    (三)圖的應用——活動圖

    如圖3.3.1

    圖3.3.1

    (四)堆排序的應用——Top K問題

    如圖3.4.1

    圖3.4.1

    參考文獻:
    【1】 CSDN 博主遐光 《中綴表達式轉后綴表達式算法思想》
    【2】 CSDN 博主糖不苦z的原創文章
    https://blog.csdn.net/weixin_44203971/article/details/103934109
    【3】 程杰《大話數據結構》 清華大學出版社 圖
    【4】 CSDN博主「feliciafay」的原創文章
    https://blog.csdn.net/feliciafay/article/details/12252727
    【5】 嚴蔚敏 吳偉民.《數據結構(C語音版)》清華大學出版社

    附件:
    (一)棧的應用——后綴表達式實現
    代碼:

    #include<stdio.h> typedef struct{char data[50];int top; }Stack,*S_ptr;void InitStack(S_ptr S){//初始化棧 for(int i=0;i<50;i++){S->data[i]='\0';}S->top=-1; }void Push(S_ptr S,char c){//壓入棧中printf("%c入棧\n",c); if(S->top==49){printf("棧滿\n");return ; }S->top++;S->data[S->top]=c;return ; }void Pop(S_ptr S,char &c){//彈出棧 if(S->top==-1){printf("棧空\n");return;}c=S->data[S->top];printf("%c出棧\n",c);S->top--;return; }char gettop(S_ptr S){if(S->top==-1){return '\0';}return S->data[S->top]; }void OutputStack(S_ptr S,int top) { int i; for(i=top;i>=0;i--) {printf("%c",S->data[i]);printf("\n"); } }int main(){Stack s;S_ptr S=&s;InitStack(S);char e;char a[100];printf("請輸入中綴表達式:");gets(a);Push(S,'#');//棧底元素為#for(int i=0;a[i]!='#';i++){if(a[i]!='+'&&a[i]!='-'&&a[i]!='*'&&a[i]!='/'&&a[i]!='('&&a[i]!=')') {printf("打印%c\n",a[i]);printf("此時棧狀態:\n");OutputStack( S,S->top);}//非操作數直接輸出 else if(a[i]==')'){while(gettop(S)!='('&&gettop(S)!='\0'){//括號匹配 Pop(S,e);printf("%c\n",e);printf("此時棧狀態:\n");OutputStack( S,S->top);}Pop(S,e);}else if(a[i]=='+'||a[i]=='-'){if(gettop(S)=='*'||gettop(S)=='/'){while(gettop(S)!='('&&gettop(S)!='#'){Pop(S,e);printf("打印%c\n",e);printf("此時棧狀態:\n");OutputStack( S,S->top);}Push(S,a[i]);printf("此時棧狀態:\n");OutputStack( S,S->top);}else {Push(S,a[i]);printf("此時棧狀態:\n");OutputStack( S,S->top);} }else if(a[i]=='*'||a[i]=='/'){if(gettop(S)=='*'||gettop(S)=='/'){Pop(S,e);printf("打印%c\n",e);printf("此時棧狀態:\n");OutputStack( S,S->top);Push(S,a[i]);printf("此時棧狀態:\n");OutputStack( S,S->top);}else {Push(S,a[i]);printf("此時棧狀態:\n");OutputStack( S,S->top);} } else {Push(S,a[i]);printf("此時棧狀態:\n");OutputStack( S,S->top);} }while(S->data[S->top]!='#'){//將剩余的運算符號出棧Pop(S,e);printf("打印%c\n",e); printf("此時棧狀態:\n"); OutputStack( S,S->top);}return 0; }數據:a+b#(二) 圖的應用——最小生成樹 代碼: //2.圖的應用——最小生成樹 #include<iostream> #include<cstdlib> using namespace std; #define max_vertex_num 20 int max_weight=0;//記錄無向帶權圖中最大權值 typedef struct edgenode{//邊 int adjvex;//該邊所指向的頂點位置 edgenode *nextedge;//指向下一條邊的指針 int weight;//邊上的權值 }edgenode;typedef struct vnode{//頂點 int data;//頂點信息 edgenode *firstedge;//指向第一條依附該頂點的指針 }vnode,adjlist[max_vertex_num];typedef struct{//圖 adjlist vertices;//頂點向量 int vexnum,edgenum;//圖的當前頂點數和邊數 }graph;typedef struct node{//輔助數組,記錄已訪問的頂點及與其相連的邊中最小的權值 int adjvex;int lowcost; }node; node closedge[max_vertex_num];//查找頂點val在頂點向量中的位置 int local(graph G,int val) {for(int i=0;i<G.vexnum;i++){if(G.vertices[i].data==val)return i;}return -1; }//鄰接表法構造無向圖G void creatUDG(graph &G) { cout<<"請依次輸入頂點數和邊數:"<<endl;cin>>G.vexnum>>G.edgenum;for(int i=0,j=0;i<G.vexnum;i++,j++)//初始化頂點 {G.vertices[i].data=j;G.vertices[i].firstedge=NULL; }int i,j,k;int v1,v2;edgenode *e=NULL,*p=NULL,*q=NULL;cout<<"請依次輸入邊(Vi,Vj)上的頂點信息及權值:"<<endl;for(k=0;k<G.edgenum;k++)//初始化邊 {int weights=0;//暫時保存邊上的權值 cin>>v1>>v2>>weights;i=local(G,v1);//查找兩頂點在頂點向量中的位置 j=local(G,v2); if(G.vertices[i].firstedge==NULL){e=new edgenode;//新建邊結點 e->adjvex=j;e->nextedge=NULL;e->weight=weights; if(e->weight>max_weight)//尋找最大權值 max_weight=e->weight;G.vertices[i].firstedge=e;//將該邊結點接入第i個鏈表 }else{p=G.vertices[i].firstedge;while(p->nextedge!=NULL)//循環后移p指針,使其指向第i個鏈表中的最后一個結點 {p=p->nextedge;}e=new edgenode;//新建邊結點e->adjvex=j;e->nextedge=NULL;e->weight=weights; if(e->weight>max_weight)//尋找最大權值 max_weight=e->weight;p->nextedge=e;//將該邊結點接入第i個鏈表的末尾 }if(G.vertices[j].firstedge==NULL){e=new edgenode;e->adjvex=i;e->nextedge=NULL;e->weight=weights;G.vertices[j].firstedge=e;//將該邊結點接入第i個鏈表 }else{q=G.vertices[j].firstedge;while(q->nextedge!=NULL)//循環后移p指針,使其指向第i個鏈表中的最后一個結點 {q=q->nextedge;}e=new edgenode;e->adjvex=i;e->nextedge=NULL;e->weight=weights;q->nextedge=e;//將該邊結點接入第i個鏈表的末尾 }}max_weight++;for(i=0;i<G.vexnum;i++)//初始化輔助數組 closedge[i].lowcost=max_weight;//最小代價比最大權值還大,表示兩頂點無邊連接 }int findmin(graph G)//找權值最小的邊所關聯的頂點 {int i,result=-1;int min=max_weight;for(i=0;i<G.vexnum;i++)//遍歷輔助數組 {if(closedge[i].lowcost!=0&&min>closedge[i].lowcost){min=closedge[i].lowcost;result=i;}}return result; }//用普里姆算法從第u個頂點出發構造無向有權圖G的最小生成樹T并輸出代價最小的路線 void minispantree_prim(graph G,int u) {int i,j,k,t1,t2;edgenode *p=NULL;k=local(G,u);p=G.vertices[k].firstedge;while(p)//與頂點u相連的邊的權值和頂點輸入輔助數組closedge[]{i=p->adjvex; closedge[i].adjvex=u;closedge[i].lowcost=p->weight;p=p->nextedge;}closedge[k].lowcost=0;//訪問過的頂點的邊的權值標記為0for(i=1;i<G.vexnum;i++) {k=findmin(G);t1=G.vertices[k].data;t2=closedge[k].adjvex;cout<<t2<<"->"<<t1<<endl; closedge[k].lowcost=0;p=G.vertices[k].firstedge;while(p){j=p->adjvex;if(closedge[j].lowcost>p->weight)//與上一頂點比較,輸入權值小的邊的權值和與其相連接的頂點{closedge[j].adjvex=G.vertices[k].data;closedge[j].lowcost=p->weight;}p=p->nextedge;}} }int main() {graph G;creatUDG(G);cout<<endl<<"請輸入開始頂點:"<<endl;int u;cin>>u;cout<<"代價最小的路線為:"<<endl;minispantree_prim(G,u);return 0; } 輸入數據:請依次輸入頂點數和邊數:7 9 頂點信息和權值: 0 1 28 1 2 16 2 3 12 3 4 22 4 5 25 5 0 10 1 6 14 3 6 18 4 6 24 輸入開始頂點:0 (三) 圖的應用——活動圖 代碼: include<stdlib.h> #include<stdio.h> #include<malloc.h> #include<string.h> typedef int DataType; /*棧元素類型定義*/ #define MaxSize 50 /*最大頂點個數*/ #define StackSize 100 typedef struct {DataType stack[StackSize];int top; }SeqStack;void InitStack(SeqStack *S) /*將棧初始化為空棧只需要把棧頂指針top置為0*/ { S->top=0; /*把棧頂指針置為0*/ } int StackEmpty(SeqStack S) /*判斷棧是否為空,棧為空返回1,否則返回0*/ {if(S.top==0) /*判斷棧頂指針top是否為0*/return 1; /*當棧為空時,返回1;否則返回0*/elsereturn 0; } int GetTop(SeqStack S, DataType *e) /*取棧頂元素。將棧頂元素值返回給e,并返回1表示成功;否則返回0表示失敗。*/ {if(S.top<=0) /*在取棧頂元素之前,判斷棧是否為空*/ {printf("棧已經空!\n");return 0; } else {*e=S.stack[S.top-1]; /*在取棧頂元素*/return 1; } } int PushStack(SeqStack *S,DataType e) /*將元素e進棧,元素進棧成功返回1,否則返回0.*/ { if(S->top>=StackSize) /*在元素進棧前,判斷是否棧已經滿*/ {printf("棧已滿,不能進棧!\n");return 0; } else {S->stack[S->top]=e; /*元素e進棧*/S->top++; /*修改棧頂指針*/return 1; } } int PopStack(SeqStack *S,DataType *e) /*出棧操作。將棧頂元素出棧,并將其賦值給e。出棧成功返回1,否則返回0*/ {if(S->top<=0) /*元素出棧之前,判斷棧是否為空*/{printf("棧已經沒有元素,不能出棧!\n");return 0;}else {S->top--; /*先修改棧頂指針,即出棧*/*e=S->stack[S->top]; /*將出棧元素賦值給e*/return 1;} } int StackLength(SeqStack S) /*求棧的長度,即棧中元素個數,棧頂指針的值就等于棧中元素的個數*/ {return S.top; } void ClearStack(SeqStack *S) /*將棧初始化為空棧只需要把棧頂指針top置為0*/ { S->top=0; /*把棧頂指針置為0*/ }/*圖的鄰接表類型定義*/ typedef char VertexType[4]; typedef int InfoPtr; /*定義為整型,為了存放權值*/ typedef int VRType;typedef enum{DG,DN,UG,UN}GraphKind; /*圖的類型:有向圖、有向網、無向圖和無向網*/ typedef struct ArcNode /*邊結點的類型定義*/ {int adjvex; /*弧指向的頂點的位置*/InfoPtr *info; /*弧的權值*/struct ArcNode *nextarc; /*指示下一個與該頂點相鄰接的頂點*/ }ArcNode; typedef struct VNode /*頭結點的類型定義*/ {VertexType data; /*用于存儲頂點*/ArcNode *firstarc; /*指示第一個與該頂點鄰接的頂點*/ }VNode,AdjList[MaxSize]; typedef struct /*圖的類型定義*/ {AdjList vertex;int vexnum,arcnum; /*圖的頂點數目與弧的數目*/GraphKind kind; /*圖的類型*/ }AdjGraph;int ve[MaxSize]; /*ve存放事件最早發生時間*/ int TopologicalOrder(AdjGraph N,SeqStack *T) /*采用鄰接表存儲結構的有向網N的拓撲排序,并求各頂點對應事件的最早發生時間ve*/ /*如果N無回路,則用用棧T返回N的一個拓撲序列,并返回1,否則為0*/ {int i,k,count=0;int indegree[MaxSize]; /*數組indegree存儲各頂點的入度*/SeqStack S;ArcNode *p;/*將圖中各頂點的入度保存在數組indegree中*/for(i=0;i<N.vexnum;i++) /*將數組indegree賦初值*/indegree[i]=0;for(i=0;i<N.vexnum;i++){p=N.vertex[i].firstarc;while(p!=NULL){k=p->adjvex;indegree[k]++;p=p->nextarc;}}InitStack(&S); /*初始化棧S*/for(i=0;i<N.vexnum;i++)if(!indegree[i]) /*將入度為零的頂點入棧*/PushStack(&S,i);InitStack(T); /*初始化拓撲序列頂點棧*/for(i=0;i<N.vexnum;i++) /*初始化ve*/ve[i]=0;while(!StackEmpty(S)) /*如果棧S不為空*/{PopStack(&S,&i); /*從棧S將已拓撲排序的頂點j彈出*/PushStack(T,i); /*j號頂點入逆拓撲排序棧T*/count++; /*對入棧T的頂點計數*/for(p=N.vertex[i].firstarc;p;p=p->nextarc) /*處理編號為i的頂點的每個鄰接點*/{k=p->adjvex; /*頂點序號為k*/if(--indegree[k]==0) /*如果k的入度減1后變為0,則將k入棧S*/PushStack(&S,k);if(ve[i]+*(p->info)>ve[k]) /*計算頂點k對應的事件的最早發生時間*/ve[k]=ve[i]+*(p->info);}}if(count<N.vexnum){printf("該有向網有回路\n");return 0;}elsereturn 1; } int CriticalPath(AdjGraph N) /*輸出N的關鍵路徑*/ {int vl[MaxSize]; /*事件最晚發生時間*/SeqStack T;int i,j,k,e,l,dut,value,count,e1[MaxSize],e2[MaxSize];ArcNode *p;if(!TopologicalOrder(N,&T)) /*如果有環存在,則返回0*/return 0;value=ve[0];for(i=1;i<N.vexnum;i++)if(ve[i]>value)value=ve[i]; /*value為事件的最早發生時間的最大值*/for(i=0;i<N.vexnum;i++) /*將頂點事件的最晚發生時間初始化*/vl[i]=value;while(!StackEmpty(T)) /*按逆拓撲排序求各頂點的vl值*/for(PopStack(&T,&j),p=N.vertex[j].firstarc;p;p=p->nextarc)/*彈出棧T的元素,賦給j,p指向j的后繼事件k*/{k=p->adjvex;dut=*(p->info); /*dut為弧<j,k>的權值*/if(vl[k]-dut<vl[j]) /*計算事件j的最遲發生時間*/vl[j]=vl[k]-dut;}printf("\n");count=0;printf("計算輸出每條弧最早發生時間和最遲發生時間:\n 弧 e l l-e\n");for(j=0;j<N.vexnum;j++) /*求活動的最早開始時間e和最晚開始時間l*/for(p=N.vertex[j].firstarc;p;p=p->nextarc){k=p->adjvex;dut=*(p->info); /*dut為弧<j,k>的權值*/e=ve[j]; /*e就是活動<j,k>的最早開始時間*/l=vl[k]-dut; /*l就是活動<j,k>的最晚開始時間*/printf("%s→%s %3d %3d %3d\n",N.vertex[j].data,N.vertex[k].data,e,l,l-e);if(e==l) /*將關鍵活動保存在數組中*/{e1[count]=j;e2[count]=k;count++;}}printf("輸出該開發項目的最短開發周期:%d\n",ve[N.vexnum-1]);printf("計算輸出每條弧最早發生時間和最遲發生時間:");for(k=0;k<count;k++) /*輸出關鍵路徑*/{i=e1[k];j=e2[k];printf("(%s→%s) ",N.vertex[i].data,N.vertex[j].data);}printf("\n");return 1; } int LocateVertex(AdjGraph G,VertexType v) /*返回圖中頂點對應的位置*/ {int i;for(i=0;i<G.vexnum;i++)if(strcmp(G.vertex[i].data,v)==0)return i;return -1; } void CreateGraph(AdjGraph *N) /*采用鄰接表存儲結構,創建有向網N*/ {int i,j,k,w;VertexType v1,v2; /*定義兩個弧v1和v2*/ArcNode *p;printf("請輸入圖的頂點數,邊數(以逗號分隔): ");scanf("%d,%d",&(*N).vexnum,&(*N).arcnum);printf("請輸入%d個頂點的值:",N->vexnum);for(i=0;i<N->vexnum;i++) /*將頂點存儲在頭結點中*/{scanf("%s",N->vertex[i].data);N->vertex[i].firstarc=NULL; /*將相關聯的頂點置為空*/}printf("請輸入弧尾、弧頭和權值(以空格作為分隔):\n");for(k=0;k<N->arcnum;k++) /*建立邊鏈表*/{scanf("%s%s%*c%d",v1,v2,&w);i=LocateVertex(*N,v1);j=LocateVertex(*N,v2);/*j為弧頭i為弧尾創建鄰接表*/p=(ArcNode*)malloc(sizeof(ArcNode));p->adjvex=j;p->info=(InfoPtr*)malloc(sizeof(InfoPtr));*(p->info)=w;/*將p指向的結點插入到邊表中*/p->nextarc=N->vertex[i].firstarc;N->vertex[i].firstarc=p;}(*N).kind=DN; }void DestroyGraph(AdjGraph *N) /*銷毀無向圖G*/ {int i;ArcNode *p,*q;for(i=0;i<N->vexnum;++i) /*釋放網中的邊表結點*/{p=N->vertex[i].firstarc; /*p指向邊表的第一個結點*/if(p!=NULL) /*如果邊表不為空,則釋放邊表的結點*/{q=p->nextarc;free(p);p=q;}}(*N).vexnum=0; /*將頂點數置為0*/(*N).arcnum=0; /*將邊的數目置為0*/ }int main() {AdjGraph N;CreateGraph(&N); /*采用鄰接表存儲結構創建有向網N*/CriticalPath(N); /*求網N的關鍵路徑*/DestroyGraph(&N); /*銷毀網N*/ } 實驗數據: 請輸入圖的頂點數,邊數(以逗號分隔): 8,10 請輸入8個頂點的值:v1 v2 v3 v4 v5 v6 v7 v8 請輸入弧尾、弧頭和權值(以空格作為分隔): v1 v2 3 v1 v2 4 v1 v4 6 v2 v5 3 v4 v7 3 v3 v5 1 v5 v7 3 v6 v8 4 v7 v8 5 v5 v6 5 (四)堆排序的應用——Top K問題實驗代碼: //4.堆排序的應用——Top K問題 #include<iostream> #include<string> using namespace std; #define max_arc_num 20 typedef struct arcnode{//弧(有向邊結構體) string head,tail;//弧頭,弧尾 string weight;//弧上的權值 }arcnode;//全局變量 arcnode arc[max_arc_num];//弧的結構體數組 int arclen=0;//數組長度 //輸入各條弧 void In_Put() {int i=1;arc[0].tail="0";arc[0].head="0";arc[0].weight="0";//數組零號元素不存儲弧 ,用于交換 記錄過程中暫存記錄 cout<<"請輸入各條弧的弧尾,弧頭,權值(-1表示結束輸入):"<<endl; while(cin>>arc[i].tail&&arc[i].tail!="-1"){cin>>arc[i].head>>arc[i].weight;i++;}arclen=i-1; }//已知arc[s...m]中除arc[s]外均滿足堆的特征,自上而下調整,使arc[s...m]也成為一個大頂堆 void heapadjust(arcnode arcs[],int s,int m){arcs[0]=arcs[s];for(int j=2*s;j<=m;j*=2)//沿著權值較大的孩子節點向下篩選 {if(j<m&&arcs[j].weight<arcs[j+1].weight) ++j;//先左右子樹根之間進行相互比較,j為權值較大的弧的所在下標if(arcs[0].weight>=arcs[j].weight)//根和子樹根之間相互比較 break;//找到arc[0]的插入位置,無需繼續往下調整 arcs[s]=arcs[j];//否則記錄上移,尚需繼續往下調整 s=j; }arcs[s]=arcs[0];} // 對弧的結構體數組進行堆排序 void heapsort(arcnode arcs[]) {for(int i=arclen;i>0;--i)heapadjust(arcs,i,arclen);//建大頂堆(自下而上) for(int i=arclen;i>1;--i)//將堆頂記錄和當前未經排序子序列arc[1...i]中最后一個記錄相互交換 {arcs[0]=arcs[i];arcs[i]=arcs[1];arcs[1]=arcs[0]; heapadjust(arcs,1,i-1); //對arc[1]進行篩選 } } //輸出排序后的結果void Out_Put(){cout<<"按弧的權值由小到大,輸出各條有向弧(箭頭由弧尾指向弧頭):"<<endl; for(int i=1;i<=arclen;i++){cout<<arc[i].tail<<"->"<<arc[i].head<<' ';cout<<"該弧上的權值為:"<<arc[i].weight<<endl; } } //Top K排序void Top_K(int k,bool flag)//flag=0/1分別表示查找最小/最大K個元素 {if(flag){cout<<"權值最大的"<<k<<"條弧為:"<<endl; for(int i=arclen;i>arclen-k;i--){cout<<arc[i].tail<<"->"<<arc[i].head<<' ';cout<<"該弧上的權值為:"<<arc[i].weight<<endl; } }else{cout<<"權值最小的"<<k<<"條弧為:"<<endl; for(int i=1;i<=k;i++){cout<<arc[i].tail<<"->"<<arc[i].head<<' ';cout<<"該弧上的權值為:"<<arc[i].weight<<endl; } }} int main(){In_Put();//輸入各條弧 heapsort(arc);Out_Put();//輸出堆排序結果 int k,flag;cout<<"請輸入k值:"<<endl;cin>>k;cout<<"查找最大"<<k<<"個元素請輸入1,查找最小的"<<k<<"個元素請輸入0:"<<endl;cin>>flag; Top_K(k,flag); return 0;} 輸入數據: 請輸入各條弧的弧尾,弧頭,權值(-1表示結束輸入): 1 2 6 1 3 4 1 4 5 2 5 1 3 5 1 4 6 2 5 7 9 5 8 7 6 8 4 7 9 2 8 9 4 -1 請輸入k值:5 查找最大5個元素請輸入1,查找最小的5個元素請輸入0:0

    總結

    以上是生活随笔為你收集整理的数据结构——课程设计的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。