單鏈表的插入和刪除實驗報告_第1頁
單鏈表的插入和刪除實驗報告_第2頁
單鏈表的插入和刪除實驗報告_第3頁
單鏈表的插入和刪除實驗報告_第4頁
單鏈表的插入和刪除實驗報告_第5頁
已閱讀5頁,還剩36頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、 . 實驗一、單鏈表的插入和刪除一、目的了解和掌握線性表的邏輯結(jié)構(gòu)和鏈?zhǔn)酱鎯Y(jié)構(gòu),掌握單鏈表的基本算法及相關(guān)的時間性能分析。二、要求:建立一個數(shù)據(jù)域定義為字符串的單鏈表,在鏈表中不允許有重復(fù)的字符串;根據(jù)輸入的字符串,先找到相應(yīng)的結(jié)點,后刪除之。三、程序源代碼#include"stdio.h"#include"string.h"#include"stdlib.h"#include"ctype.h"typedef struct node /定義結(jié)點 char data10; /結(jié)點的數(shù)據(jù)域為字符串struct nod

2、e *next; /結(jié)點的指針域 ListNode;typedef ListNode * LinkList; / 自定義LinkList單鏈表類型LinkList CreatListR1(); /函數(shù),用尾插入法建立帶頭結(jié)點的單鏈表ListNode *LocateNode(); /函數(shù),按值查找結(jié)點void DeleteList(); /函數(shù),刪除指定值的結(jié)點void printlist(); /函數(shù),打印鏈表中的所有值void DeleteAll(); /函數(shù),刪除所有結(jié)點,釋放內(nèi)存/=主函數(shù)=void main() char ch10,num10; LinkList head; head=

3、CreatListR1(); /用尾插入法建立單鏈表,返回頭指針 printlist(head); /遍歷鏈表輸出其值 printf(" Delete node (y/n):");/輸入“y”或“n”去選擇是否刪除結(jié)點 scanf("%s",num); if(strcmp(num,"y")=0 | strcmp(num,"Y")=0) printf("Please input Delete_data:"); scanf("%s",ch); /輸入要刪除的字符串 DeleteL

4、ist(head,ch); printlist(head); DeleteAll(head); /刪除所有結(jié)點,釋放內(nèi)存/=用尾插入法建立帶頭結(jié)點的單鏈表= LinkList CreatListR1(void) char ch10; LinkList head=(LinkList)malloc(sizeof(ListNode); /生成頭結(jié)點 ListNode *s,*r,*pp; r=head; r->next=NULL; printf("Input # to end "); /輸入“#”代表輸入結(jié)束 printf("Please input Node_d

5、ata:"); scanf("%s",ch); /輸入各結(jié)點的字符串 while(strcmp(ch,"#")!=0) pp=LocateNode(head,ch); /按值查找結(jié)點,返回結(jié)點指針 if(pp=NULL) /沒有重復(fù)的字符串,插入到鏈表中 s=(ListNode *)malloc(sizeof(ListNode); strcpy(s->data,ch); r->next=s; r=s; r->next=NULL; printf("Input # to end "); printf("

6、;Please input Node_data:"); scanf("%s",ch); return head; /返回頭指針/=按值查找結(jié)點,找到則返回該結(jié)點的位置,否則返回NULL=ListNode *LocateNode(LinkList head, char *key) ListNode *p=head->next; /從開始結(jié)點比較 while(p&&strcmp(p->data,key)!=0 ) /直到p為NULL或p->data為key止p=p->next; /掃描下一個結(jié)點 return p; /若p=NU

7、LL則查找失敗,否則p指向找到的值key的結(jié)點/=刪除帶頭結(jié)點的單鏈表中的指定結(jié)點=void DeleteList(LinkList head,char *key) ListNode *p,*r,*q=head; p=LocateNode(head,key); /按key值查找結(jié)點的 if(p=NULL ) /若沒有找到結(jié)點,退出printf("position error");exit(0); while(q->next!=p) /p為要刪除的結(jié)點,q為p的前結(jié)點q=q->next; r=q->next; q->next=r->next; f

8、ree(r); /釋放結(jié)點/=打印鏈表=void printlist(LinkList head) ListNode *p=head->next; /從開始結(jié)點打印 while(p)printf("%s, ",p->data);p=p->next; printf("n");/=刪除所有結(jié)點,釋放空間=void DeleteAll(LinkList head) ListNode *p=head,*r; while(p->next)r=p->next;free(p);p=r; free(p);運行結(jié)果:加的添加結(jié)點的代碼:int

9、 Insert(ListNode *head) / the insert functionListNode *in,*p,*q;int wh;printf("input the insert node:");in=(ListNode *)malloc(sizeof(ListNode);in->next=NULL;p=(ListNode *)malloc(sizeof(ListNode);p->next=NULL;q=(ListNode *)malloc(sizeof(ListNode);q->next=NULL;if(!in)return 0;scanf(

10、"%s",in->data);printf("input the place where you want to insert you data:");scanf("%d",&wh);for(p=head;wh>0;p=p->next,wh-);q=p->next;p->next=in;in->next=q;return 1;運行結(jié)果:最后提示為OK 添加成功。實驗心得:這個實驗中 主要修改的是ch 和 num 把它們由指針改成數(shù)組 因為不改的話在后面delect函數(shù)中會出現(xiàn)沒有地址的情況

11、找不到地址就不能執(zhí)行功能 然后把locate函數(shù)的判斷語句改一下 避免矛盾的出現(xiàn)。實驗二、二叉樹操作一、 目的掌握二叉樹的定義、性質(zhì)及存儲方式,各種遍歷算法。二、 要求采用二叉樹鏈表作為存儲結(jié)構(gòu),完成二叉樹的建立,先序、中序和后序以及按層次遍歷的操作,求所有葉子及結(jié)點總數(shù)的操作。三、 程序源代碼#include"stdio.h"#include"string.h"#define Max 20 /結(jié)點的最大個數(shù)typedef struct node char data; struct node *lchild,*rchild;BinTNode; /自定義二

12、叉樹的結(jié)點類型typedef BinTNode *BinTree; /定義二叉樹的指針int NodeNum,leaf; /NodeNum為結(jié)點數(shù),leaf為葉子數(shù)/=基于先序遍歷算法創(chuàng)建二叉樹=/=要求輸入先序序列,其中加入虛結(jié)點“#”以示空指針的位置=BinTree CreatBinTree(void) BinTree T; char ch; if(ch=getchar()='#')return(NULL); /讀入#,返回空指針 else T=(BinTNode *)malloc(sizeof(BinTNode); / 生成結(jié)點T->data=ch;T->lc

13、hild=CreatBinTree(); /構(gòu)造左子樹T->rchild=CreatBinTree(); /構(gòu)造右子樹return(T); /=NLR 先序遍歷=void Preorder(BinTree T) if(T) printf("%c",T->data); /訪問結(jié)點Preorder(T->lchild); /先序遍歷左子樹Preorder(T->rchild); /先序遍歷右子樹 /=LNR 中序遍歷= void Inorder(BinTree T) if(T) Inorder(T->lchild); /中序遍歷左子樹printf(

14、"%c",T->data); /訪問結(jié)點Inorder(T->rchild); /中序遍歷右子樹 /=LRN 后序遍歷=void Postorder(BinTree T) if(T) Postorder(T->lchild); /后序遍歷左子樹Postorder(T->rchild); /后序遍歷右子樹printf("%c",T->data); /訪問結(jié)點 /=采用后序遍歷求二叉樹的深度、結(jié)點數(shù)及葉子數(shù)的遞歸算法=int TreeDepth(BinTree T) int hl,hr,max; if(T)hl=TreeDept

15、h(T->lchild); /求左深度hr=TreeDepth(T->rchild); /求右深度max=hl>hr? hl:hr; /取左右深度的最大值NodeNum=NodeNum+1; /求結(jié)點數(shù)if(hl=0&&hr=0) leaf=leaf+1; /若左右深度為0,即為葉子。return(max+1); else return(0);/=利用“先進先出”(FIFO)隊列,按層次遍歷二叉樹=void Levelorder(BinTree T) int front=0,rear=1; BinTNode *cqMax,*p; /定義結(jié)點的指針數(shù)組cq cq

16、1=T; /根入隊 while(front!=rear) front=(front+1)%NodeNum;p=cqfront; /出隊printf("%c",p->data); /出隊,輸出結(jié)點的值 if(p->lchild!=NULL) rear=(rear+1)%NodeNum; cqrear=p->lchild; /左子樹入隊if(p->rchild!=NULL) rear=(rear+1)%NodeNum; cqrear=p->rchild; /右子樹入隊 /=主函數(shù)=void main() BinTree root; int i,de

17、pth; printf("n");printf("Creat Bin_Tree; Input preorder:"); /輸入完全二叉樹的先序序列, / 用#代表虛結(jié)點,如ABD#CE#F# root=CreatBinTree(); /創(chuàng)建二叉樹,返回根結(jié)點 do /從菜單中選擇遍歷方式,輸入序號。printf("t* select *n");printf("t1: Preorder Traversaln"); printf("t2: Iorder Traversaln");printf(&qu

18、ot;t3: Postorder traversaln");printf("t4: PostTreeDepth,Node number,Leaf numbern");printf("t5: Level Depthn"); /按層次遍歷之前,先選擇4,求出該樹的結(jié)點數(shù)。printf("t0: Exitn");printf("t*n");scanf("%d",&i); /輸入菜單序號(0-5)switch (i)case 1: printf("Print Bin_tree

19、 Preorder: ");Preorder(root); /先序遍歷break;case 2: printf("Print Bin_Tree Inorder: ");Inorder(root); /中序遍歷break;case 3: printf("Print Bin_Tree Postorder: ");Postorder(root); /后序遍歷break;case 4: depth=TreeDepth(root); /求樹的深度及葉子數(shù)printf("BinTree Depth=%d BinTree Node number=%

20、d",depth,NodeNum);printf(" BinTree Leaf number=%d",leaf);break;case 5: printf("LevePrint Bin_Tree: ");Levelorder(root); /按層次遍歷break;default: exit(1);printf("n"); while(i!=0); 執(zhí)行程序1. 先序遍歷2. 中序遍歷3. 后序遍歷4. 結(jié)點數(shù) 葉子數(shù) 高度5.層次遍歷自己設(shè)計的:abdhl#m#i#e#jn#cf#ko#g#1.預(yù)計先序遍歷結(jié)果:abdhlm

21、iejncfkog2.預(yù)計中序遍歷結(jié)果:lhmdibenjafokcg3.預(yù)計后序遍歷結(jié)果:lmhidnjebokfgca4.結(jié)點數(shù) 15 高度5 葉子數(shù) 6實際結(jié)果:實驗心得:這次實驗主要是要讓我們熟練樹及其相關(guān)知識 熟練掌握先序中序后序遍歷,層次遍歷 然后我們自己畫一個圖 會實現(xiàn)以上功能 以及葉子數(shù) 結(jié)點數(shù)還有高度的計算 程序里面大量運用了遞歸以及隊的應(yīng)用, 實驗三、圖的遍歷操作一、 目的掌握有向圖和無向圖的概念;掌握鄰接矩陣和鄰接鏈表建立圖的存儲結(jié)構(gòu);掌握DFS及BFS對圖的遍歷操作;了解圖結(jié)構(gòu)在人工智能、工程等領(lǐng)域的廣泛應(yīng)用。二、 要求采用鄰接矩陣和鄰接鏈表作為圖的存儲結(jié)構(gòu),完成有向圖

22、和無向圖的DFS和BFS操作。三、 DFS和BFS 的基本思想深度優(yōu)先搜索法DFS的基本思想:從圖G中某個頂點Vo出發(fā),首先訪問Vo,然后選擇一個與Vo相鄰且沒被訪問過的頂點Vi訪問,再從Vi出發(fā)選擇一個與Vi相鄰且沒被訪問過的頂點Vj訪問,依次繼續(xù)。如果當(dāng)前被訪問過的頂點的所有鄰接頂點都已被訪問,則回退到已被訪問的頂點序列中最后一個擁有未被訪問的相鄰頂點的頂點W,從W出發(fā)按同樣方法向前遍歷。直到圖中所有的頂點都被訪問。廣度優(yōu)先算法BFS的基本思想:從圖G中某個頂點Vo出發(fā),首先訪問Vo,然后訪問與Vo相鄰的所有未被訪問過的頂點V1,V2,Vt;再依次訪問與V1,V2,Vt相鄰的起且未被訪問過

23、的的所有頂點。如此繼續(xù),直到訪問完圖中的所有頂點。四、 程序源代碼1 鄰接矩陣作為存儲結(jié)構(gòu)的程序示例#include"stdio.h"#include"stdlib.h"#define MaxVertexNum 100 /定義最大頂點數(shù)typedef struct char vexsMaxVertexNum; /頂點表 int edgesMaxVertexNumMaxVertexNum; /鄰接矩陣,可看作邊表 int n,e; /圖中的頂點數(shù)n和邊數(shù)eMGraph; /用鄰接矩陣表示的圖的類型/=建立鄰接矩陣=void CreatMGraph(MGra

24、ph *G) int i,j,k; char a; printf("Input VertexNum(n) and EdgesNum(e): "); scanf("%d,%d",&G->n,&G->e); /輸入頂點數(shù)和邊數(shù) scanf("%c",&a); printf("Input Vertex string:"); for(i=0;i<G->n;i+) scanf("%c",&a); G->vexsi=a; /讀入頂點信息,建立頂點

25、表 for(i=0;i<G->n;i+)for(j=0;j<G->n;j+) G->edgesij=0; /初始化鄰接矩陣 printf("Input edges,Creat Adjacency Matrixn"); for(k=0;k<G->e;k+) /讀入e條邊,建立鄰接矩陣 scanf("%d%d",&i,&j); /輸入邊(Vi,Vj)的頂點序號 G->edgesij=1; G->edgesji=1; /若為無向圖,矩陣為對稱矩陣;若建立有向圖,去掉該條語句 /=定義標(biāo)志向量

26、,為全局變量=typedef enumFALSE,TRUE Boolean;Boolean visitedMaxVertexNum;/=DFS:深度優(yōu)先遍歷的遞歸算法=void DFSM(MGraph *G,int i) /以Vi為出發(fā)點對鄰接矩陣表示的圖G進行DFS搜索,鄰接矩陣是0,1矩陣 int j; printf("%c",G->vexsi); /訪問頂點Vi visitedi=TRUE; /置已訪問標(biāo)志 for(j=0;j<G->n;j+) /依次搜索Vi的鄰接點if(G->edgesij=1 && ! visitedj)

27、DFSM(G,j); /(Vi,Vj)E,且Vj未訪問過,故Vj為新出發(fā)點void DFS(MGraph *G) int i; for(i=0;i<G->n;i+)visitedi=FALSE; /標(biāo)志向量初始化 for(i=0;i<G->n;i+)if(!visitedi) /Vi未訪問過 DFSM(G,i); /以Vi為源點開始DFS搜索/=BFS:廣度優(yōu)先遍歷=void BFS(MGraph *G,int k) /以Vk為源點對用鄰接矩陣表示的圖G進行廣度優(yōu)先搜索 int i,j,f=0,r=0; int cqMaxVertexNum; /定義隊列 for(i=0

28、;i<G->n;i+)visitedi=FALSE; /標(biāo)志向量初始化 for(i=0;i<G->n;i+)cqi=-1; /隊列初始化 printf("%c",G->vexsk); /訪問源點Vk visitedk=TRUE; cqr=k; /Vk已訪問,將其入隊。注意,實際上是將其序號入隊 while(cqf!=-1) /隊非空則執(zhí)行 i=cqf; f=f+1; /Vf出隊 for(j=0;j<G->n;j+) /依次Vi的鄰接點Vj if(G->edgesij=1 && !visitedj) /Vj未訪問

29、 printf("%c",G->vexsj); /訪問Vj visitedj=TRUE; r=r+1; cqr=j; /訪問過Vj入隊 /=main=void main() int i; MGraph *G; G=(MGraph *)malloc(sizeof(MGraph); /為圖G申請內(nèi)存空間 CreatMGraph(G); /建立鄰接矩陣 printf("Print Graph DFS: "); DFS(G); /深度優(yōu)先遍歷 printf("n"); printf("Print Graph BFS: &quo

30、t;); BFS(G,3); /以序號為3的頂點開始廣度優(yōu)先遍歷 printf("n");調(diào)試結(jié)果:自己畫的圖: 1對應(yīng)頂點下標(biāo)0 以此類推 9對應(yīng)下標(biāo)8預(yù)計運行結(jié)果:DFS:012345678BFS:324105687對應(yīng)我這個圖:DFS:123456789BFS:435216798實驗心得:圖在數(shù)據(jù)結(jié)構(gòu)中是相當(dāng)重要的一部分 聯(lián)系很多現(xiàn)實問題 圖的根本就是頂點和邊 通過頂點和邊建立鄰接矩陣以及鄰接鏈表 廣度搜索和深度搜索是此算法著重關(guān)注的地方。要學(xué)會自己畫圖 然后寫出這兩種搜索的結(jié)果,程序中用了隊的算法 是亮點 通過TRUE和FAUSE來標(biāo)記頂點是否以及訪問 避免重復(fù) 實

31、驗四、排序一、 目的掌握各種排序方法的基本思想、排序過程、算法實現(xiàn),能進行時間和空間性能的分析,根據(jù)實際問題的特點和要求選擇合適的排序方法。二、 要求實現(xiàn)直接排序、冒泡、直接選擇、快速、堆、歸并排序算法。比較各種算法的運行速度。三、 程序示例#include"stdio.h"#include"stdlib.h"#define Max 100 /假設(shè)文件長度typedef struct /定義記錄類型 int key; /關(guān)鍵字項RecType;typedef RecType SeqListMax+1; /SeqList為順序表,表中第0個元素作為哨兵in

32、t n; /順序表實際的長度1、 直接插入排序的基本思想:每次將一個待排序的記錄,按其關(guān)鍵字大小插入到前面已排序好的子文件中的適當(dāng)位置,直到全部記錄插入完成為止。/=直接插入排序法=void InsertSort(SeqList R) /對順序表R中的記錄R1n按遞增序進行插入排序 int i,j; for(i=2;i<=n;i+) /依次插入R2,Rn if(Ri.key<Ri-1.key) /若Ri.key大于等于有序區(qū)中所有的keys,則Ri留在原位 R0=Ri;j=i-1; /R0是Ri的副本 do /從右向左在有序區(qū)R1i-1中查找Ri的位置Rj+1=Rj; /將關(guān)鍵字大

33、于Ri.key的記錄后移j-; while(R0.key<Rj.key); /當(dāng)Ri.keyRj.key 是終止 Rj+1=R0; /Ri插入到正確的位置上/endif2、 冒泡排序的基本思想:設(shè)想被排序的記錄數(shù)組R1n垂直排序。根據(jù)輕氣泡不能在重氣泡之下的原則,從下往上掃描數(shù)組R,凡掃描到違反本原則的輕氣泡,就使其向上“漂浮”(交換),如此反復(fù)進行,直到最后任意兩個氣泡都是輕者在上,重者在下為止。/=冒泡排序=typedef enumFALSE,TRUE Boolean; /FALSE為0,TRUE為1void BubbleSort(SeqList R) /自下向上掃描對R做冒泡排序

34、int i,j; Boolean exchange; /交換標(biāo)志 for(i=1;i<n;i+) /最多做n-1趟排序exchange=FALSE; /本趟排序開始前,交換標(biāo)志應(yīng)為假for(j=n-1;j>=i;j-) /對當(dāng)前無序區(qū)Rin 自下向上掃描 if(Rj+1.key<Rj.key) /兩兩比較,滿足條件交換記錄R0=Rj+1; /R0不是哨兵,僅做暫存單元Rj+1=Rj;Rj=R0;exchange=TRUE; /發(fā)生了交換,故將交換標(biāo)志置為真 if(! exchange) /本趟排序未發(fā)生交換,提前終止算法 return; /endfor(為循環(huán))3、 快速排序

35、的基本思想:在待排序的n個記錄中任取一個記錄(通常取第一個記錄),把該記錄作為支點(又稱基準(zhǔn)記錄)(pivot),將所有關(guān)鍵字比它小的記錄放置在它的位置之前,將所有關(guān)鍵字比它大的記錄放置在它的位置之后(稱之為一次劃分過程)。之后對所分的兩部分分別重復(fù)上述過程,直到每部分只有一個記錄為止。/1.=一次劃分函數(shù)=int Partition(SeqList R,int i,int j) / 對Rij做一次劃分,并返回基準(zhǔn)記錄的位置 RecType pivot=Ri; /用第一個記錄作為基準(zhǔn) while(i<j) /從區(qū)間兩端交替向中間掃描,直到i=j while(i<j &&am

36、p;Rj.key>=pivot.key) /基準(zhǔn)記錄pivot相當(dāng)與在位置i上 j-; /從右向左掃描,查找第一個關(guān)鍵字小于pivot.key的記錄Rjif(i<j) /若找到的Rj.key < pivot.key,則 Ri+=Rj; /交換Ri和Rj,交換后i指針加1while(i<j &&Ri.key<=pivot.key) /基準(zhǔn)記錄pivot相當(dāng)與在位置j上 i+; /從左向右掃描,查找第一個關(guān)鍵字小于pivot.key的記錄Riif(i<j) /若找到的Ri.key > pivot.key,則 Rj-=Ri; /交換Ri和Rj

37、,交換后j指針減1 Ri=pivot; /此時,i=j,基準(zhǔn)記錄已被最后定位 return i; /返回基準(zhǔn)記錄的位置/2.=快速排序=void QuickSort(SeqList R,int low,int high) /Rlow.high快速排序 int pivotpos; /劃分后基準(zhǔn)記錄的位置 if(low<high) /僅當(dāng)區(qū)間長度大于1時才排序pivotpos=Partition(R,low,high); /對Rlow.high做一次劃分,得到基準(zhǔn)記錄的位置QuickSort(R,low,pivotpos-1); /對左區(qū)間遞歸排序QuickSort(R,pivotpos+1

38、,high); /對右區(qū)間遞歸排序 4、 直接選擇排序的基本思想:第i趟排序開始時,當(dāng)前有序區(qū)和無序區(qū)分別為R1i-1和Rin(1in-1),該趟排序則是從當(dāng)前無序區(qū)中選擇出關(guān)鍵字最小的記錄Rk,將它與無序區(qū)的的第一個記錄Ri交換,有序區(qū)增加一個記錄,使R1i,和Ri+1n分別為新的有序區(qū)和新的無序區(qū)。如此反復(fù)進行,直到排序完畢。/=直接選擇排序=void SelectSort(SeqList R) int i,j,k; for(i=1;i<n;i+) /做第i趟排序(1in-1)k=i;for(j=i+1;j<=n;j+) /在當(dāng)前無序區(qū)Rin中選key最小的記錄Rk if(Rj

39、.key<Rk.key)k=j; /k記下目前找到的最小關(guān)鍵字所在的位置if(k!=i) / /交換Ri和Rk R0=Ri;Ri=Rk;Rk=R0; /endif /endfor5、 堆排序的基本思想:它是一種樹型選擇排序,特點是:在排序的過程中,將R1n看成是一個完全二叉樹的順序存儲結(jié)構(gòu),利用完全二叉樹中雙親結(jié)點和孩子結(jié)點之間的內(nèi)在關(guān)系,在當(dāng)前無序區(qū)中選擇關(guān)鍵字最大(或最?。┑挠涗洝<矗喊汛判蛭募年P(guān)鍵字存放在數(shù)組R1n子中,將R看成是一棵二叉樹,每個結(jié)點表示一個記錄,源文件的第一個記錄R1作為二叉樹的根,以下各記錄R2n依次逐層從左到右排列,構(gòu)成一棵完全二叉樹,任意結(jié)點Ri的左孩子

40、是R2i,右孩子是R2i+1,雙親是Ri/2。對這棵完全二叉樹的結(jié)點進行調(diào)整,使各結(jié)點的關(guān)鍵字滿足下列條件:Ri.keyR2i.key并且Ri.keyR2i+1.key 稱小堆根或 Ri.keyR2i.key并且Ri.keyR2i+1.key 稱大堆根/=大根堆調(diào)整函數(shù)=void Heapify(SeqList R,int low,int high) / 將Rlow.high調(diào)整為大根堆,除Rlow外,其余結(jié)點均滿足堆性質(zhì) int large; /large指向調(diào)整結(jié)點的左、右孩子結(jié)點中關(guān)鍵字較大者 RecType temp=Rlow; /暫存調(diào)整結(jié)點 for(large=2*low; lar

41、ge<=high;large*=2) /Rlow是當(dāng)前調(diào)整結(jié)點 /若large>high,則表示Rlow是葉子,調(diào)整結(jié)束;否則先令large指向Rlow的左孩子if(large<high && Rlarge.key<Rlarge+1.key) large+; /若Rlow的右孩子存在且關(guān)鍵字大于左兄弟,則令large指向它 /現(xiàn)在Rlarge是調(diào)整結(jié)點Rlow的左右孩子結(jié)點中關(guān)鍵字較大者if(temp.key>=Rlarge.key) /temp始終對應(yīng)Rlow break; /當(dāng)前調(diào)整結(jié)點不小于其孩子結(jié)點的關(guān)鍵字,結(jié)束調(diào)整Rlow=Rlarge;

42、 /相當(dāng)于交換了Rlow和Rlargelow=large; /令low指向新的調(diào)整結(jié)點,相當(dāng)于temp已篩下到large的位置 Rlow=temp; /將被調(diào)整結(jié)點放入最終位置上/=構(gòu)造大根堆=void BuildHeap(SeqList R) /將初始文件R1.n構(gòu)造為堆 int i; for(i=n/2;i>0;i-)Heapify(R,i,n); /將Ri.n調(diào)整為大根堆/=堆排序=void HeapSort(SeqList R) /對R1.n進行堆排序,不妨用R0做暫存單元 int i; BuildHeap(R); /將R1.n構(gòu)造為初始大根堆 for(i=n;i>1;i-

43、) /對當(dāng)前無序區(qū)R1.i進行堆排序,共做n-1趟。R0=R1; R1=Ri;Ri=R0; /將堆頂和堆中最后一個記錄交換Heapify(R,1,i-1); /將R1.i-1重新調(diào)整為堆,僅有R1可能違反堆性質(zhì)。 6、 二路歸并排序的基本思想:假設(shè)初始序列n個記錄,則可看成是n個有序的子序列,每個子序列的長度為1,然后兩兩歸并,得到n/2個長度為2或1的有序子序列;再兩兩歸并,如此重復(fù),直到一個長度為n的有序序列為止。/=將兩個有序的子序列Rlow.m和Rm+1.high歸并成有序的序列Rlow.high=void Merge(SeqList R,int low,int m,int high)

44、 int i=low,j=m+1,p=0; /置初始值 RecType *R1; /R1為局部量 R1=(RecType *)malloc(high-low+1)*sizeof(RecType); /申請空間 while(i<=m && j<=high) /兩個子序列非空時取其小者輸出到R1p上R1p+=(Ri.key<=Rj.key)? Ri+:Rj+; while(i<=m) /若第一個子序列非空,則復(fù)制剩余記錄到R1R1p+=Ri+; while(j<=high) /若第二個子序列非空,則復(fù)制剩余記錄到R1中R1p+=Rj+; for(p=0

45、,i=low;i<=high;p+,i+)Ri=R1p; /歸并完成后將結(jié)果復(fù)制回Rlow.high/=對R1.n做一趟歸并排序=void MergePass(SeqList R,int length) int i; for(i=1;i+2*length-1<=n;i=i+2*length)Merge(R,i,i+length-1,i+2*length-1); /歸并長度為length的兩個相鄰的子序列 if(i+length-1<n) /尚有一個子序列,其中后一個長度小于lengthMerge(R,i,i+length-1,n); /歸并最后兩個子序列 /注意:若in且i+length-1n時,則剩余一個子序列輪空,無須歸并/

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論