}//while
}//QSort_NotRecurve
int Partition(SQList &L,int low,int high)//一趟划分的算法,与书上相同 {
L.r[0]=L.r[low];
pivotkey=L.r[low].key; while(low while(low L.r[low]=L.r[high]; while(low L.r[high]=L.r[low]; }//while L.r[low]=L.r[0]; return low; }//Partition void Easy_Sort(SQList &L,int low,int high)//对长度小于3的子序列进行比较排序 { if(high-low==1) //子序列只含两个元素 if(L.r[low].key>L.r[high].key) L.r[low]<->L.r[high]; else //子序列含有三个元素 { if(L.r[low].key>L.r[low+1].key) L.r[low]<->L.r[low+1]; if(L.r[low+1].key>L.r[high].key) L.r[low+1]<->L.r[high]; if(L.r[low].key>L.r[low+1].key) L.r[low]<->L.r[low+1]; } }//Easy_Sort 10.31 void Divide(int a[ ],int n)//把数组a中所有值为负的记录调到非负的记录之前 { low=0;high=n-1; while(low while(low while(low }//Divide 10.32 typedef enum {RED,WHITE,BLUE} color; //三种颜色 void Flag_Arrange(color a[ ],int n)//把由三种颜色组成的序列重排为按照红,白,蓝的顺序排列 { i=0;j=0;k=n-1; while(j<=k) switch(a[j]) { case RED: a[i]<->a[j]; i++; j++; break; case WHITE: j++; break; case BLUE: a[j]<->a[k]; k--; //这里没有j++;语句是为了防止交换后a[j]仍为蓝色的情况 } }//Flag_Arrange 分析:这个算法中设立了三个指针.其中,j表示当前元素;i以前的元素全部为红色;k以后的元素全部为蓝色.这样,就可以根据j的颜色,把其交换到序列的前部或者后部. 10.33 void LinkedList_Select_Sort(LinkedList &L)//单链表上的简单选择排序算法 { for(p=L;p->next->next;p=p->next) { q=p->next;x=q->data; for(r=q,s=q;r->next;r=r->next) //在q后面寻找元素值最小的结点 if(r->next->data x=r->next->data; s=r; } if(s!=q) //找到了值比q->data更小的最小结点s->next { p->next=s->next;s->next=q; t=q->next;q->next=p->next->next; p->next->next=t; } //交换q和s->next两个结点 }//for }//LinkedList_Select_Sort 10.34 void Build_Heap(Heap &H,int n)//从低下标到高下标逐个插入建堆的算法 { for(i=2;i { //此时从H.r[1]到H.r[i-1]已经是大顶堆 j=i; while(j!=1) //把H.r[i]插入 { k=j/2; if(H.r[j].key>H.r[k].key) H.r[j]<->H.r[k]; j=k; } }//for }//Build_Heap 10.35 void TriHeap_Sort(Heap &H)//利用三叉树形式的堆进行排序的算法 { for(i=H.length/3;i>0;i--) Heap_Adjust(H,i,H.length); for(i=H.length;i>1;i--) { H.r[1]<->H.r[i]; Heap_Adjust(H,1,i-1); } }//TriHeap_Sort void Heap_Adjust(Heap &H,int s,int m)//顺序表H中,H.r[s+1]到H.r[m]已经是堆,把H.r[s]插入并调整成堆 { rc=H.r[s]; for(j=3*s-1;j<=m;j=3*j-1) { if(j H.r[s]=rc; }//Heap_Adjust 分析:本算法与课本上的堆排序算法相比,只有两处改动:1.建初始堆时,i的上限从H.length/3开始(为什么?) 2.调整堆的时候,要从结点的三个孩子结点中选择最大的那一个,最左边的孩子的序号的计算公式为j=3*s-1(为什么?) 10.36 void Merge_Sort(int a[ ],int n)//归并排序的非递归算法 { for(l=1;l for(i=0;(2*i-1)*l start1=2*l*i; //求出待归并的两段的上下界 end1=start1+l-1; start2=end1+1; end2=(start2+l-1)>(n-1)?(n-1):(start2+l-1);//注意end2可能超出边界 Merge(a,start1,end1,start2,end2); //归并 } }//Merge_Sort void Merge(int a[ ],int s1,int e1,int s2,int e2)//将有序子序列a[s1]到a[e1]和a[s2]到a[e2]归并为有序序列a[s1]到a[e2] { int b[MAXSIZE]; //设立辅助存储数组b for(i=s1,j=s2,k=s1;i<=e1&&j<=e2;k++) {