![查找排序?qū)嶒瀳蟾鎋第1頁](http://file4.renrendoc.com/view/941ef4522220d8a2e9f42a451cb8a04a/941ef4522220d8a2e9f42a451cb8a04a1.gif)
![查找排序?qū)嶒瀳蟾鎋第2頁](http://file4.renrendoc.com/view/941ef4522220d8a2e9f42a451cb8a04a/941ef4522220d8a2e9f42a451cb8a04a2.gif)
![查找排序?qū)嶒瀳蟾鎋第3頁](http://file4.renrendoc.com/view/941ef4522220d8a2e9f42a451cb8a04a/941ef4522220d8a2e9f42a451cb8a04a3.gif)
![查找排序?qū)嶒瀳蟾鎋第4頁](http://file4.renrendoc.com/view/941ef4522220d8a2e9f42a451cb8a04a/941ef4522220d8a2e9f42a451cb8a04a4.gif)
![查找排序?qū)嶒瀳蟾鎋第5頁](http://file4.renrendoc.com/view/941ef4522220d8a2e9f42a451cb8a04a/941ef4522220d8a2e9f42a451cb8a04a5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
《編程實訓(xùn)》試驗匯報書專業(yè):計算機科學(xué)與技術(shù)班級:151班學(xué)號:姓名:指導(dǎo)教師:日期:6月30日
目錄HYPERLINK一、需求分析…………………31.任務(wù)規(guī)定……………………32.軟件功能分析………………33.數(shù)據(jù)準備……………………3HYPERLINK二、概要設(shè)計…………………31.功能模塊圖………………42.模塊間調(diào)用關(guān)系…………43.主程序模塊………………54.抽象數(shù)據(jù)類型描述…………5HYPERLINK三、詳細設(shè)計…………………61.存儲構(gòu)造定義………………62.各功能模塊的詳細設(shè)計……………………7HYPERLINK四、實現(xiàn)和調(diào)試………………71.重要的算法………………72.重要問題及處理…………83.測試執(zhí)行及成果……………8HYPERLINK五、改善………………………9HYPERLINK六、附錄……………………9HYPERLINK1.查找源程序………………9HYPERLINK2.排序源程序………………9
目錄1
需求分析
1.1
任務(wù)規(guī)定
對于從鍵盤隨機輸入的一種序列的數(shù)據(jù),存入計算機內(nèi),給出多種查找算法的實現(xiàn);以及多種排序算法的實現(xiàn)。1.2
軟件功能分析 任意輸入n個正整數(shù),該程序可以實現(xiàn)各類查找及排序的功能并將成果輸出。1.3
數(shù)據(jù)準備 任意輸入了5個正整數(shù)如下:12234556782
概要設(shè)計(假如2,3合并可以省略2.4)
2.1
功能模塊圖(注:含功能闡明)2.2
模塊間調(diào)用關(guān)系
2.3
主程序模塊
2.4
抽象數(shù)據(jù)類型描述 存儲構(gòu)造:數(shù)據(jù)構(gòu)造在計算機中的表達(也稱映像)叫做物理構(gòu)造。又稱為存儲構(gòu)造。數(shù)據(jù)類型(datatype)是一種“值”的集合和定義在此集合上的一組操作的總稱。3
詳細設(shè)計3.1
存儲構(gòu)造定義查找:typedefintElemType;//次序存儲構(gòu)造typedefstruct{ ElemType*elem;//數(shù)據(jù)元素存儲空間基址,建表時按實際長度分派,號單元留空 intlength;//表的長度}SSTable;排序:typedefstruct{//定義記錄類型 intkey;//關(guān)鍵字項}RecType;typedefRecTypeSeqList[Max+1];//SeqList為次序表,表中第0個元素作為哨兵3.2
各功能模塊的詳細設(shè)計查找:voidCreate(SSTable*table,intlength); //構(gòu)建次序表voidFillTable(SSTable*table)//無序表的輸入intSearch_Seq(SSTable*table,ElemTypekey); //哨兵查找算法 voidSort(SSTable*table)//排序算法intSearch_Bin(SSTable*table,ElemTypekey)//二分法查找(非遞歸) 排序:voidInsertSort(SeqListR)//對次序表R中的記錄R[1‥n]按遞增序進行插入排序voidBubbleSort(SeqListR)//自下向上掃描對R做冒泡排序intPartition(SeqListR,inti,intj)//對R[i‥j]做一次劃分,并返回基準記錄的位置voidQuickSort(SeqListR,intlow,inthigh)//R[low..high]迅速排序voidSelectSort(SeqListR)//直接選擇排序voidHeapify(SeqListR,intlow,inthigh)//大根堆調(diào)整函數(shù)voidMergePass(SeqListR,intlength)//歸并排序4
實現(xiàn)和調(diào)試4.1
重要的算法查找:①建立次序存儲構(gòu)造,構(gòu)建一種次序表,實現(xiàn)次序查找算法。typedefstruct{ElemType*elem;//數(shù)據(jù)元素存儲空間基址,建表時按實際長度分派,號單元留空intlength;//表的長度}SSTable;②對次序表先排序后,實現(xiàn)行二分法查找有關(guān)操作。③定義二叉樹節(jié)點,根據(jù)節(jié)點的值進行查找,并且實現(xiàn)節(jié)點的插入,刪除等操作。typedefstructBiTnode{//定義二叉樹節(jié)點 intdata;//節(jié)點的值 structBiTnode*lchild,*rchild;}BiTnode,*BiTree;④定義哈希表以及要查找的節(jié)點元素,創(chuàng)立哈希表,實現(xiàn)其有關(guān)查找操作。typedefstruct{intnum; }Elemtype;//定義查找的結(jié)點元素typedefstruct{Elemtype*elem;//數(shù)據(jù)元素存儲基址 intcount;//數(shù)據(jù)元素個數(shù) intsizeindex;}HashTable;//定義哈希表排序:2.排序有關(guān)試驗內(nèi)容及環(huán)節(jié)。①定義記錄類型。typedefstruct{intkey;//關(guān)鍵字項}RecType;②實現(xiàn)直接插入排序:每次將一種待排序的記錄,按其關(guān)鍵字大小插入到前面已排序好的子文獻中的合適位置,直到所有記錄插入完畢為止。③實現(xiàn)冒泡排序:設(shè)想被排序的記錄數(shù)組R[1‥n]垂直排序。根據(jù)輕氣泡不能在重氣泡之下的原則,從下往上掃描數(shù)組R,凡掃描到違反本原則的輕氣泡,就使其向上“漂浮”(互換),如此反復(fù)進行,直到最終任意兩個氣泡都是輕者在上,重者在下為止。④實現(xiàn)迅速排序:在待排序的n個記錄中任取一種記錄(一般取第一種記錄),把該記錄作為支點(又稱基準記錄)(pivot),將所有關(guān)鍵字比它小的記錄放置在它的位置之前,將所有關(guān)鍵字比它大的記錄放置在它的位置之后(稱之為一次劃分過程)。之后對所分的兩部分分別反復(fù)上述過程,直到每部分只有一種記錄為止。⑤實現(xiàn)直接選擇排序:第i趟排序開始時,目前有序區(qū)和無序辨別別為R[1‥i-1]和R[i‥n](1≤i≤n-1),該趟排序則是從目前無序區(qū)中選擇出關(guān)鍵字最小的記錄R[k],將它與無序區(qū)的的第一種記錄R[i]互換,有序區(qū)增長一種記錄,使R[1‥i],和R[i+1‥n]分別為新的有序區(qū)和新的無序區(qū)。如此反復(fù)進行,直到排序完畢。⑥實現(xiàn)堆排序:它是一種樹型選擇排序,特點是:在排序的過程中,將R[1‥n]當(dāng)作是一種完全二叉樹的次序存儲構(gòu)造,運用完全二叉樹中雙親結(jié)點和孩子結(jié)點之間的內(nèi)在關(guān)系,在目前無序區(qū)中選擇關(guān)鍵字最大(或最?。┑挠涗?。即:把待排序文獻的關(guān)鍵字寄存在數(shù)組R[1‥n]子中,將R當(dāng)作是一棵二叉樹,每個結(jié)點表達一種記錄,源文獻的第一種記錄R[1]作為二叉樹的根,如下各記錄R[2‥n]依次逐層從左到右排列,構(gòu)成一棵完全二叉樹,任意結(jié)點R[i]的左孩子是R[2i],右孩子是R[2i+1],雙親是R[i/2]。⑦實現(xiàn)二路歸并排序:假設(shè)初始序列n個記錄,則可當(dāng)作是n個有序的子序列,每個子序列的長度為1,然后兩兩歸并,得到[n/2]個長度為2或1的有序子序列;再兩兩歸并,……,如此反復(fù),直到一種長度為n的有序序列為止。4.2
重要問題及處理 在試驗前對于多種查找和排序的算法不是很熟悉,因此花了某些時間去復(fù)習(xí)。有些代碼反復(fù)測試還是找不出錯誤,最終也是翻閱了書本并仔細思索才改善了算法并成功測試出了成果。這次試驗大大提高了我對排序算法及查找算法的純熟程度。4.3
測試執(zhí)行及成果 查找算法:任意輸入若干正整數(shù)并測試如下:排序算法:任意輸入數(shù)字并測試如下:5
改善 根據(jù)提醒的代碼,通過一系列調(diào)試后最終出了成果。在一開始運行時總是出錯,尤其是二叉樹的測試,代碼有些小錯誤導(dǎo)致測試的時候程序總是出錯。最終改動了一下提高了程序的穩(wěn)定性并成功運行出了成果。6附錄【附錄1----查找源程序】#include"iostream"#include"stdlib.h"#include"stdio.h"#include"malloc.h"#defineMAX11usingnamespacestd;typedefintElemType;//次序存儲構(gòu)造typedefstruct{ ElemType*elem;//數(shù)據(jù)元素存儲空間基址,建表時按實際長度分派,號單元留空 intlength;//表的長度}SSTable;voidCreate(SSTable*table,intlength); voidDestroy(SSTable*table);intSearch_Seq(SSTable*table,ElemTypekey); voidTraverse(SSTable*table,void(*visit)(ElemTypeelem));voidCreate(SSTable**table,intlength)//構(gòu)建次序表{ SSTable*t=(SSTable*)malloc(sizeof(SSTable));//分派空間 t->elem=(ElemType*)malloc(sizeof(ElemType)*(length+1)); t->length=length; *table=t;}voidFillTable(SSTable*table)//無序表的輸入{ ElemType*t=table->elem; for(inti=0;i<table->length;i++)//for循環(huán),輸入各個元素 { t++; scanf("%d",t);//輸入元素 getchar(); }}voidDestroy(SSTable*table)//銷毀表{ free(table->elem);//釋放元素空間 free(table);//釋放表的空間}voidPrintTable(SSTable*table)//打印查找表{inti;//定義變量 ElemType*t=table->elem; for(i=0;i<table->length;i++)//進入循環(huán),依次打印表中元素 { t++; printf("%d",*t);//打印輸出 } printf("\n");}intSearch_Seq(SSTable*table,ElemTypekey)//哨兵查找算法{ table->elem[0]=key;//設(shè)置哨兵 intresult=0;//找不屆時,返回 inti; for(i=table->length;i>=1;i--) {if(table->elem[i]==key) { result=i; break; } } returnresult;//返回成果}voidprintSeq(){ SSTable*table;//先設(shè)置幾種變量 intr; int n; ElemTypekey; printf("請輸入元素個數(shù):");scanf("%d",&n);//輸入元素個數(shù) Create(&table,n);//建立表 printf("請輸入");cout<<n;printf("個值:"); FillTable(table);//輸入無序表的值 printf("您輸入的%d個值是:\n",n); PrintTable(table);//打印無序表 printf("請輸入關(guān)鍵字的值:"); scanf("%d",&key); printf("\n"); printf("次序查找法運行成果如下:\n\n"); Search_Seq(table,key);//哨兵查找算法 r=Search_Seq(table,key); if(r>0) { printf("關(guān)鍵字%d在表中的位置是:%d\n",key,r);//打印關(guān)鍵字在表中的位置 printf("\n"); } else//查找失敗 { printf("查找失敗,表中無此數(shù)據(jù)。\n\n"); }}voidSort(SSTable*table)//排序算法{ inti,j; ElemTypetemp; for(i=table->length;i>=1;i--)//從前去后找 {for(j=1;j<i;j++) { if(table->elem[j]>table->elem[j+1]) { temp=table->elem[j]; table->elem[j]=table->elem[j+1]; table->elem[j+1]=temp; } } }}intSearch_Bin(SSTable*table,ElemTypekey)//二分法查找(非遞歸){ intlow=1; inthigh=table->length; intresult=0;//找不屆時,返回 while(low<=high)//low不不小于high時 { intmid=(low+high)/2; if(table->elem[mid]==key)//假如找到 { result=mid; break; } elseif(key<table->elem[mid])//假如關(guān)鍵字不不小于mid對應(yīng)的值 { high=mid-1; } else { low=mid+1; } } returnresult;//返回成果}voidprintBin(){ SSTable*table;//申明變量 intr; int n; ElemTypekey; printf("請輸入元素個數(shù):"); scanf("%d",&n); Create(&table,n);//建立表 printf("請輸入");cout<<n;printf("個值:"); FillTable(table);//輸入無序表的值 printf("您輸入的%d個值是:\n",n); PrintTable(table);//打印無序表 printf("請輸入關(guān)鍵字的值:"); scanf("%d",&key); printf("\n"); Sort(table);//對無序表進行排序 printf("數(shù)據(jù)排序后的次序如下:\n\n"); PrintTable(table);//打印有序表 printf("\n"); printf("二分查找法的運行成果如下:\n\n"); r=Search_Bin(table,key);//二分(非遞歸)查找算法 if(r>0) printf("關(guān)鍵字%d在表中的位置是:%d\n",key,r); else { printf("查找失敗,表中無此數(shù)據(jù)。\n\n"); }}//二叉排序樹typedefstructBiTnode//定義二叉樹節(jié)點{ intdata;//節(jié)點的值 structBiTnode*lchild,*rchild;//節(jié)點的左孩子,節(jié)點的右孩子}BiTnode,*BiTree;//查找(根據(jù)節(jié)點的值查找)返回節(jié)點指針BiTreesearch_tree(BiTreeT,intkeyword,BiTree*father){ BiTreep;//臨時指針變量 *father=NULL;//先設(shè)其父親節(jié)點指向空 p=T;//p賦值為根節(jié)點(從根節(jié)點開始查找) while(p&&p->data!=keyword)//假如不是p不指向空且未找到相似值的節(jié)點 { *father=p;//先將父親指向自己(注意:這里傳過來的father是二級指針) if(keyword<p->data)//假如要找的值不不小于自己的值 p=p->lchild;//就向自己的左孩子開始找 else p=p->rchild;//否則向自己的右孩子開始查找 } returnp;//假如找到了則返回節(jié)點指針}BiTreecreat_tree(intcount){ BiTreeT,p;//設(shè)置兩個臨時變量T,p inti=1; while(i<=count) { if(i==1)//假如i=1,闡明還是空樹 { p=(BiTnode*)malloc(sizeof(BiTree));//使p指向新分派的節(jié)點 if(!p)//分派未成功 returnNULL; T=p;//分派成功,T=p(這里實際上T就是根節(jié)點) scanf("%d",&p->data);//輸入p指向節(jié)點的值 p->lchild=p->rchild=NULL;//p的左孩子和右孩子都指向空 i++; } else { inttemp;//假如不是空樹 scanf("%d",&temp);//輸入節(jié)點的值 search_tree(T,temp,&p);//查找節(jié)點要插入的位置。(T是根節(jié)點,插入的節(jié)點的值,父親節(jié)點的地址) if(temp<p->data)//假如插入的值不不小于父親節(jié)點的值 { p->lchild=(BiTnode*)malloc(sizeof(BiTnode));//那么就為父親節(jié)點的左孩子分派一種節(jié)點空間,并指向這個空間 if(!p->lchild) returnNULL; p=p->lchild;//分派成功,p指向自己的左孩子 } else//假如插入的值不小于父親節(jié)點的值 { p->rchild=(BiTnode*)malloc(sizeof(BiTnode)); if(!p->rchild) returnNULL;//分派不成功,退出 p=p->rchild;//p指向自己的右孩子 } p->data=temp;//新分派的節(jié)點的值賦值為插入的值 p->lchild=p->rchild=NULL;//使其左右節(jié)點均為NULL i++; } } returnT;//返回根節(jié)點}voidInOrder(BiTreeT){ if(T) { InOrder(T->lchild); printf("%d",T->data); InOrder(T->rchild); }}intinsert_tree(BiTree*T,intelem)//插入(根節(jié)點,插入的值)返回-1和,-1代表插入失敗,代表成功{ BiTrees,p,father; s=(BiTnode*)malloc(sizeof(BiTnode));//s指向新開辟一種節(jié)點 if(!s)//為開辟成功 return-1;//返回值-1 s->data=elem;//新節(jié)點的值賦值為插入的值 s->lchild=s->rchild=NULL;//其左右孩子為空 p=search_tree(*T,elem,&father);//p賦值為要插入的節(jié)點 if(!p) return-1;//未開辟成功,返回-1 if(father==NULL)//假如父親節(jié)點指向空,闡明是空樹 *T=s;//讓根節(jié)點指向s elseif(elem<father->data)//否則假如插入的值不不小于父親的值 father->lchild=s;//父親的左孩子賦值為s else father->rchild=s;//否則父親的右孩子賦值為s return0;//返回}intdelete_tree(BiTree*T,intelem)//刪除樹結(jié)點的操作{ BiTrees,p,q,father;//申明變量 p=search_tree(*T,elem,&father);//查找 if(!p) return-1; if(!p->lchild)//假如p的左孩子為空 { if(father==NULL) { *T=p->rchild;//T指向左孩子 free(p);//釋放p return0; } if(p==father->lchild)//假如p和father的左孩子相等 father->lchild=p->rchild;//將p的左孩子的值賦給father的左孩子 else father->rchild=p->rchild;//將p的左孩子的值賦給father的右孩子 free(p);//釋放p return0; } else if(!p->rchild) { if(father==NULL)//假如father為空 { *T=p->lchild;//將p的左孩子賦給T free(p);//釋放p return0; } if(p==father->lchild)//假如p等于father的左孩子的值 father->lchild=p->lchild;//將p的左孩子的值賦給father的左孩子 else father->rchild=p->lchild;//將p的左孩子的值賦給father的右孩子 free(p); return0; } else { q=p; s=p->lchild;//將p的左孩子賦給s while(s->rchild) { q=s; s=s->rchild; } p->data=s->data;//將s的值賦給p if(q!=p)//假如q不等于p q->rchild=s->lchild;//將s的左孩子值賦給p的右孩子 else q->lchild=s->lchild;//將s的左孩子值賦給p的右孩子 free(s);//釋放s return0; }}voidprint1()//定義print1()以便調(diào)用{ printf("\t**********************\n"); printf("\t1,輸出中序遍歷\n"); printf("\t2,插入一種結(jié)點\n"); printf("\t3,刪除一種結(jié)點\n"); printf("\t4,查找一種結(jié)點\n"); printf("\t5,返回主菜單\n"); printf("\t**********************\n");}voidprintTree(){ BiTreeT,p;//申明變量 T=NULL; int i,n; ElemTypekey; printf("請輸入結(jié)點個數(shù):\n"); scanf("%d",&n);//輸入值 printf("請輸入");cout<<n;printf("個值:"); T=creat_tree(n);//建立樹 print1(); scanf("%d",&i);//輸入各個值 while(i!=5)//i不等于5時 { switch(i) { case1: printf("中序遍歷二叉樹成果如下:\n"); InOrder(T);//中序遍歷 break; case2: printf("請輸入要插入的結(jié)點值:"); scanf("%d",&key);//輸入要查找的關(guān)鍵字 if(insert_tree(&T,key))//假如插入成功 printf("插入成功!"); else printf("已存在此元素!"); break; case3: printf("請輸入要刪除的結(jié)點值:"); scanf("%d",&key);//輸入要刪除的關(guān)鍵字 if(!(delete_tree(&T,key)))//假如刪除成功 printf("刪除成功!"); else printf("不存在此元素!"); break; case4: printf("請輸入要查找的結(jié)點值:"); scanf("%d",&key);//輸入要查找的關(guān)鍵字 if(search_tree(T,key,&p))//假如查找成功 printf("查找成功!"); else printf("不存在此元素!"); break; default: printf("按鍵錯誤!"); } printf("\n"); print1(); scanf("%d",&i); }}//哈希表typedefstruct{ intnum;}Elemtype;//定義查找的結(jié)點元素typedefstruct{ Elemtype*elem;//數(shù)據(jù)元素存儲基址 intcount;//數(shù)據(jù)元素個數(shù) intsizeindex;}HashTable;//定義哈希表intHash(intnum){ intp; p=num%11; returnp;}//定義哈希函數(shù)//沖突處理函數(shù),采用二次探測再散列法處理沖突intcollision(intp,int&c){ inti,q; i=c/2+1; while(i<MAX) { if(c%2==0) { c++; q=(p+i*i)%MAX; if(q>=0)returnq; elsei=c/2+1; } else { q=(p-i*i)%MAX; c++; if(q>=0) returnq; else i=c/2+1; } } return0;}voidInitHash(HashTable*H)//創(chuàng)立哈希表{ inti;H->elem=(Elemtype*)malloc(MAX*sizeof(Elemtype)); H->count=0; H->sizeindex=MAX; for(i=0;i<MAX;i++) H->elem[i].num=0;//初始化,使SearHash函數(shù)能判斷究竟有無元素在里面}intSearHash(HashTableH,intkey,int*p)//查找函數(shù){ *p=Hash(key); while(H.elem[*p].num!=key&&H.elem[*p].num!=0) *p=*p+1; if(H.elem[*p].num==key) return1; else return0;}voidInsertHash(HashTable*H,Elemtypee){//假如查找不到就插入元素 intp; SearHash(*H,e.num,&p);//查找 H->elem[p]=e; ++H->count;}voidprintHash()//調(diào)用哈希表{ HashTableH; intp,key,i,n; Elemtypee; InitHash(&H); printf("輸入數(shù)據(jù)個數(shù)(<11):"); scanf("%d",&n); printf("請輸入各個值:"); for(i=0;i<n;i++) {//輸入n個元素 scanf("%d",&e.num);//輸入數(shù)字 if(!SearHash(H,e.num,&p)) { InsertHash(&H,e);//插入元素 } else printf("已經(jīng)存在\n");//否則就表達元素的數(shù)字已經(jīng)存在 } printf("輸入查找的數(shù)字:"); scanf("%d",&key);//輸入要查找的數(shù)字 if(SearHash(H,key,&p))//能查找成功 { printf("查找成功!");//輸出位置 } else printf("不存在此元素!");}voidprint(){ printf("\t**********************\n"); printf("\t1,次序查找\n"); printf("\t2,二分查找\n"); printf("\t3,二叉排序樹\n"); printf("\t4,哈希查找\n"); printf("\t5,退出\n"); printf("\t**********************\n"); printf("請選擇查找方式:\n");}//主函數(shù)intmain(intargc,char*argv[]){ inti;//定義變量 print(); scanf("%d",&i);//輸入要數(shù)字選擇要使用的查找措施 while(i!=5)//i不等于5時 { switch(i) { case1://i=1時 printf("次序查找法:\n"); printSeq();//次序查找法 break;//跳出循環(huán)} case2: printf("二分查找法:\n"); printBin();//二分查找法 break;//跳出循環(huán) case3: printf("二叉排序樹:\n"); printTree();//二叉排序樹 break;//跳出循環(huán) case4: printf("哈希查找法:\n"); printHash();//哈希查找法 break;//跳出循環(huán) default: printf("按鍵錯誤!"); } printf("\n"); print();//調(diào)用函數(shù)print() scanf("%d",&i); } return0;//返回0}【附錄2----排序源程序】#include<stdio.h>#include<stdlib.h>#include<string.h>#defineMax100typedefstruct{//定義記錄類型 intkey;//關(guān)鍵字項}RecType;typedefRecTypeSeqList[Max+1];//SeqList為次序表,表中第0個元素作為哨兵intn;//次序表實際的長度//1、直接插入排序的基本思想:每次將一種待排序的記錄,按其關(guān)鍵字大小插入到前面已排序好的子文獻中的合適位置,直到所有記錄插入完畢為止。//==========直接插入排序法======voidInsertSort(SeqListR)//對次序表R中的記錄R[1‥n]按遞增序進行插入排序{ inti,j; for(i=2;i<=n;i++)//依次插入R[2],……,R[n] if(R[i].key<R[i-1].key) {//若R[i].key不小于等于有序區(qū)中所有的keys,則R[i]留在原位 R[0]=R[i];j=i-1;//R[0]是R[i]的副本 do {//從右向左在有序區(qū)R[1‥i-1]中查找R[i]的位置 R[j+1]=R[j];//將關(guān)鍵字不小于R[i].key的記錄后移 j--; }while(R[0].key<R[j].key);//當(dāng)R[i].key≥R[j].key是終止 R[j+1]=R[0];//R[i]插入到對的的位置上 }}//2、冒泡排序的基本思想:設(shè)想被排序的記錄數(shù)組R[1‥n]垂直排序。根據(jù)輕氣泡不能在重氣泡之下的原則,從下往上掃描數(shù)組R,凡掃描到違反本原則的輕氣泡,就使其向上"漂浮"(互換),如此反復(fù)進行,直到最終任意兩個氣泡都是輕者在上,重者在下為止。//==========冒泡排序=======typedefenum{FALSE,TRUE}Boolean;//FALSE為0,TRUE為1voidBubbleSort(SeqListR){//自下向上掃描對R做冒泡排序 inti,j;Booleanexchange;//互換標志 for(i=1;i<n;i++) {//最多做n-1趟排序 exchange=FALSE;//本趟排序開始前,互換標志應(yīng)為假 for(j=n-1;j>=i;j--)//對目前無序區(qū)R[i‥n]自下向上掃描 if(R[j+1].key<R[j].key) {//兩兩比較,滿足條件互換記錄 R[0]=R[j+1];//R[0]不是哨兵,僅做暫存單元 R[j+1]=R[j]; R[j]=R[0]; exchange=TRUE;//發(fā)生了互換,故將互換標志置為真 } if(!exchange)//本趟排序未發(fā)生互換,提前終止算法 return; }}//3、迅速排序的基本思想:在待排序的n個記錄中任取一種記錄(一般取第一種記錄),把該記錄作為支點(又稱基準記錄)(pivot),將所有關(guān)鍵字比它小的記錄放置在它的位置之前,將所有關(guān)鍵字比它大的記錄放置在它的位置之后(稱之為一次劃分過程)。之后對所分的兩部分分別反復(fù)上述過程,直到每部分只有一種記錄為止。//1.========一次劃分函數(shù)=====intPartition(SeqListR,inti,intj)//對R[i‥j]做一次劃分,并返回基準記錄的位置{ RecTypepivot=R[i];//用第一種記錄作為基準 while(i<j) {//從區(qū)間兩端交替向中間掃描,直到i=j while(i<j&&R[j].key>=pivot.key)//基準記錄pivot相稱與在位置i上 j--;//從右向左掃描,查找第一種關(guān)鍵字不不小于pivot.key的記錄R[j] if(i<j)//若找到的R[j].key<pivot.key,則 R[i++]=R[j];//互換R[i]和R[j],互換后i指針加1 while(i<j&&R[i].key<=pivot.key)//基準記錄pivot相稱與在位置j上 i++;//從左向右掃描,查找第一種關(guān)鍵字不不小于pivot.key的記錄R[i] if(i<j)//若找到的R[i].key>pivot.key,則 R[j--]=R[i];//互換R[i]和R[j],互換后j指針減1 } R[i]=pivot;//此時,i=j,基準記錄已被最終定位 returni;//返回基準記錄的位置}//2.=====迅速排序===========voidQuickSort(SeqListR,intlow,inthigh)//R[low..high]迅速排序{ intpivotpos;//劃分后基準記錄的位置 if(low<high) {//僅當(dāng)區(qū)間長度不小于1時才排序 pivotpos=Partition(R,low,high);//對R[low..high]做一次劃分,得到基準記錄的位置 QuickSort(R,low,pivotpos-1);//對左區(qū)間遞歸排序 QuickSort(R,pivotpos+1,high);//對右區(qū)間遞歸排序 }}//4、直接選擇排序的基本思想:第i趟排序開始時,目前有序區(qū)和無序辨別別為R[1‥i-1]和R[i‥n](1≤i≤n-1),該趟排序則是從目前無序區(qū)中選擇出關(guān)鍵字最小的記錄R[k],將它與無序區(qū)的的第一種記錄R[i]互換,有序區(qū)增長一種記錄,使R[1‥i],和R[i+1‥n]分別為新的有序區(qū)和新的無序區(qū)。如此反復(fù)進行,直到排序完畢。//=====直接選擇排序========voidSelectSort(SeqListR){ inti,j,k; for(i=1;i<n;i++) {//做第i趟排序(1≤i≤n-1) k=i; for(j=i+1;j<=n;j++)//在目前無序區(qū)R[i‥n]中選key最小的記錄R[k] if(R[j].key<R[k].key) k=j;//k記下目前找到的最小關(guān)鍵字所在的位置 if(k!=i) {//互換R[i]和R[k] R[0]=R[i];R[i]=R[k];R[k]=R[0]; } }}//5、堆排序的基本思想:它是一種樹型選擇排序,特點是:在排序的過程中,將R[1‥n]當(dāng)作是一種完全二叉樹的次序存儲構(gòu)造,運用完全二叉樹中雙親結(jié)點和孩子結(jié)點之間的內(nèi)在關(guān)系,在目前無序區(qū)中選擇關(guān)鍵字最大(或最小)的記錄。即:把待排序文獻的關(guān)鍵字寄存在數(shù)組R[1‥n]子中,將R當(dāng)作是一棵二叉樹,每個結(jié)點表達一種記錄,源文獻的第一種記錄R[1]作為二叉樹的根,如下各記錄R[2‥n]依次逐層從左到右排列,構(gòu)成一棵完全二叉樹,任意結(jié)點R[i]的左孩子是R[2i],右孩子是R[2i+1],雙親是R[i/2]。對這棵完全二叉樹的結(jié)點進行調(diào)整,使各結(jié)點的關(guān)鍵字滿足下列條件://R[i].key≤R[2i].key并且R[i].key≤R[2i+1].key稱小堆根//或R[i].key≥R[2i].key并且R[i].key≥R[2i+1].key稱大堆根//==========大根堆調(diào)整函數(shù)=======voidHeapify(SeqListR,intlow,inthigh)//將R[low..high]調(diào)整為大根堆,除R[low]外,其他結(jié)點均滿足堆性質(zhì){ intlarge;//large指向調(diào)整結(jié)點的左、右孩子結(jié)點中關(guān)鍵字較大者 RecTypetemp=R[low];//暫存調(diào)整結(jié)點 for(large=2*low;large<=high;large*=2) {//R[low]是目前調(diào)整結(jié)點//若large>high,則表達R[low]是葉子,調(diào)整結(jié)束;否則先令large指向R[low]的左孩子 if(large<high&&R[large].key<R[large+1].key) large++;//若R[low]的右孩子存在且關(guān)鍵字不小于左兄弟,則令large指向//目前R[large]是調(diào)整結(jié)點R[low]的左右孩子結(jié)點中關(guān)鍵字較大者 if(temp.key>=R[large].key)//temp一直對應(yīng)R[low] break;//目前調(diào)整結(jié)點不不不小于其孩子結(jié)點的關(guān)鍵字,結(jié)束調(diào)整 R[low]=R[large];//相稱于互換了R[low]和R[large] low=large;//令low指向新的調(diào)整結(jié)點,相稱于temp已篩下到large的位置 } R[low]=temp;//將被調(diào)整結(jié)點放入最終位置上}//==========構(gòu)造大根堆==========voidBuildHeap(SeqListR)//將初始文獻R[1..n]構(gòu)造為堆{ inti; for(i=n/2;i>0;i--) Heapify(R,i,n);//將R[i..n]調(diào)整為大根堆}//==========堆排序===========voidHeapSort(SeqListR)//對R[1..n]進行堆排序,不妨用R[0]做暫存單元{ inti; BuildHeap(R);//將R[1..n]構(gòu)造為初始大根堆 for(i=n;i>1;i--) {//對目前無序區(qū)R[1..i]進行堆排序,共做n-1趟。 R[0]=R[1];R[1]=R[i];R[i]=R[0];//將堆頂和堆中最終一種記錄互換 Heapify(R,1,i-1);//將R[1..i-1]重新調(diào)整為堆,僅有R[1]也許違反堆性質(zhì)。 }}//6、二路歸并排序的基本思想:假設(shè)初始序列n個記錄,則可當(dāng)作是n個有序的子序列,每個子序列的長度為1,然后兩兩歸并,得到[n/2]個長度為2或1的有序子序列;再兩兩歸并,……,如此反復(fù),直到一種長度為n的有序序列為止。//=====將兩個有序的子序列R[low..m]和R[m+1..high]歸并成有序的序列R[low..high]==voidMerge(SeqListR,intlow,intm,inthigh){ inti=low,j=m+1,p=0;//置初始值 RecType*R1;//R1為局部量 R1=(RecType*)malloc((high-low+1)*sizeof(RecType));//申請空間 while(i<=m&&j<=high)//兩個子序列非空時取其小者輸出到R1[p]上 R1[p++]=(R[i].key<=R[j].key)?R[i++]:R[j++]; while(i<=m)//若第一種子序列非空,則復(fù)制剩余記錄到R1 R1[p++]=R[i++]; while(j<=high)//若第二個子序列非空,則復(fù)制剩余記錄到R1中 R1[p++]=R[j++]; for(p=0,i=low;i<=high;p++,i++) R[i]=R1[p];//歸并完畢后將成果復(fù)制回R[low..high]}//=========對R[1..n]做一趟歸并排序========voidMergePass(SeqListR,intlength){ inti; for(i=1;i+2*length-1<=n;i=i+2*length) Merge(R,i,i+length-1,i+2*length-1);//歸并長度為length的兩個相鄰的子序列
溫馨提示
- 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中國防火板表層紙行業(yè)市場調(diào)查研究及投資前景預(yù)測報告
- 2023-2029年中國膚癢顆粒行業(yè)市場發(fā)展監(jiān)測及投資潛力預(yù)測報告
- 2019-2025年中國保健醋行業(yè)市場調(diào)查研究及投資前景預(yù)測報告
- 中國安宮牛黃丸行業(yè)全景評估及投資規(guī)劃建議報告
- 設(shè)置醫(yī)療機構(gòu)申請書范本
- 中國香薰蠟燭市場運營態(tài)勢分析及投資前景預(yù)測報告
- 知識產(chǎn)權(quán)與企業(yè)社會責(zé)任的關(guān)系
- 中國盤式連續(xù)干燥機市場運營態(tài)勢及發(fā)展前景預(yù)測報告
- 電子商務(wù)物流模式前沿創(chuàng)新策略與優(yōu)化路徑
- 計算機配件行業(yè)市場發(fā)展現(xiàn)狀及趨勢與投資分析研究報告
- 2024年山東公務(wù)員考試申論試題(B卷)
- 四年級數(shù)學(xué)(四則混合運算帶括號)計算題專項練習(xí)與答案
- 2024年中考語文(云南卷)真題詳細解讀及評析
- 2025年上半年山東氣象局應(yīng)屆高校畢業(yè)生招考易考易錯模擬試題(共500題)試卷后附參考答案
- 電梯消防安全與維護
- 【大學(xué)課件】工程倫理與社會
- 第二單元 主題活動三《世界那么大我想去看看》(說課稿)-2023-2024學(xué)年六年級下冊綜合實踐活動內(nèi)蒙古版
- 人教版2024-2025學(xué)年八年級上學(xué)期數(shù)學(xué)期末壓軸題練習(xí)
- 【人教版化學(xué)】必修1 知識點默寫小紙條(答案背誦版)
- 雙線大橋連續(xù)梁剛構(gòu)專項施工方案及方法
- 美容院前臺接待流程
評論
0/150
提交評論