sorts

 

各种排序算法:

  1 #include <stdio.h>    

  2 #include <string.h>

  3 #include <ctype.h>      

  4 #include <stdlib.h>   

  5 #include <io.h>  

  6 #include <math.h>  

  7 #include <time.h>

  8 

  9 #define OK        1

 10 #define ERROR    0

 11 #define TRUE    1

 12 #define FALSE    0

 13 

 14 #define MAX_LENGTH_INSERT_SORT 7 /* 用于快速排序时判断是否选用插入排序阙值 */

 15 

 16 typedef int Status; 

 17 

 18 #define MAXSIZE 10000  /* 用于要排序数组个数最大值,可根据需要修改 */

 19 typedef struct

 20 {

 21     int r[MAXSIZE+1];    /* 用于存储要排序数组,r[0]用作哨兵或临时变量 */

 22     int length;            /* 用于记录顺序表的长度 */

 23 }SqList;

 24 

 25 /* 交换L中数组r的下标为i和j的值 */

 26 void swap(SqList *L,int i,int j) 

 27 { 

 28     int temp=L->r[i]; 

 29     L->r[i]=L->r[j]; 

 30     L->r[j]=temp; 

 31 }

 32 

 33 void print(SqList L)

 34 {

 35     int i;

 36     for(i=1;i<L.length;i++)

 37         printf("%d,",L.r[i]);

 38 

 39     printf("%d",L.r[i]);

 40     printf("\n");

 41 }

 42 

 43 /* 对顺序表L作交换排序(冒泡排序初级版) */

 44 void BubbleSort0(SqList *L)

 45 { 

 46     for( int i=1; i<L->length; i++)

 47     {

 48         for( int j=i+1; j<=L->length; j++)

 49         {

 50             if(L->r[i]>L->r[j])

 51             {

 52                  swap(L,i,j);        /* 交换L->r[i]与L->r[j]的值 */

 53             }

 54         }

 55     }

 56 }

 57 

 58 /* 对顺序表L作冒泡排序 */

 59 void BubbleSort(SqList *L)

 60 { 

 61     for(int i=1;i<L->length;i++)

 62     {

 63         for(int j=L->length-1;j>=i;j--) /* 注意j是从后往前循环 */

 64         {

 65             if(L->r[j]>L->r[j+1])        /* 若前者大于后者(注意这里与上一算法的差异)*/

 66             {

 67                  swap(L,j,j+1);            /* 交换L->r[j]与L->r[j+1]的值 */

 68             }

 69         }

 70     }

 71 }

 72 

 73 /* 对顺序表L作改进冒泡算法 */

 74 void BubbleSort2(SqList *L)

 75 { 

 76     Status flag = TRUE;            /* flag用来作为标记 */

 77     for( int i=1; i<L->length && flag; i++) /* 若flag为true说明有过数据交换,否则停止循环 */

 78     {

 79         flag = FALSE;                /* 初始为False */

 80         for(int j=L->length-1; j>=i; j--)

 81         {

 82             if(L->r[j] > L->r[j+1])

 83             {

 84                  swap(L, j, j+1);    /* 交换L->r[j]与L->r[j+1]的值 */

 85                  flag = TRUE;        /* 如果有数据交换,则flag为true */

 86             }

 87         }

 88     }

 89 }

 90 

 91 // 双向冒泡法

 92 void Bubble_2 ( int r[], int n)

 93 {  

 94     int low = 0;   

 95     int high = n-1; //设置变量的初始值  

 96     int tmp,j;

 97 

 98     while (low < high) 

 99     {  

100         for (j = low; j< high; ++j)    // 正向冒泡,找到最大者  

101             if (r[j] > r[j+1]) 

102             {  

103                 tmp = r[j]; r[j] = r[j+1]; r[j+1] = tmp;  

104             }   

105         --high;            // 修改high值, 前移一位  

106         for ( j = high; j > low; --j)    // 反向冒泡,找到最小者  

107             if (r[j] < r[j-1]) 

108             {  

109                 tmp = r[j]; r[j] = r[j-1]; r[j-1] = tmp;  

110             }  

111         ++low;            // 修改low值,后移一位  

112     }   

113 } 

114 

115 /*

116 多关键码排序方法:

117 

118 多关键码排序按照从最主位关键码到最次位关键码或从最次位到最主位关键码的顺序逐次排序,分两种方法:

119 

120 最高位优先(Most Significant Digit first)法,简称MSD法:

121     1)先按k1 排序分组,将序列分成若干子序列,同一组序列的记录中,关键码k1 相等。

122     2)再对各组按k2 排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd 对各子组排序后。

123     3)再将各组连接起来,便得到一个有序序列。扑克牌按花色、面值排序中介绍的方法一即是MSD 法。

124 

125 最低位优先(Least Significant Digit first)法,简称LSD法:

126     1) 先从kd 开始排序,再对kd-1进行排序,依次重复,直到按k1排序分组分成最小的子序列后。

127     2) 最后将各个子序列连接起来,便可得到一个有序的序列, 扑克牌按花色、面值排序中介绍的方法二即是LSD 法。

128 

129 原理:

130         按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。

131     有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。

132     最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。

133     基数排序基于分别排序,分别收集,所以是稳定的。

134 @param:

135     r: 原始数组

136     

137     // 原理版本

138 void RadixSort(int r[], int length, int maxradix )  

139 {  

140     int k, lsp;  

141     k = 1; 

142     int n = 0;    // 基数内 序号

143     int m = 1;  // 个位、十位

144 

145     int temp[10][length-1];  

146     Empty( temp );    // 清空临时空间  

147 

148     while( k < maxradix )    // 遍历所有关键字  

149     {  

150         for(int i=0; i<length; i++) //分配过程  

151         {  

152             if(r[i] < m)  

153                 temp[0][n] = r[i];  

154             else  

155                 lsp = (r[i]/m) % 10; //确定关键字  

156 

157             temp[lsp][n] = r[i];  

158             n++;  

159         } 

160 

161         CollectElement(r, temp); // 收集  

162         n = 0;  

163         m = m*10;  

164         k++;  

165     }  

166 } 

167  */

168     // 得到最大位数

169 int maxbit(int data[], int n)

170 {

171     int nBit = 1;

172     for(int i=0; i<n; i++)

173     {

174         int tempC = 1;

175         int p = data[i];

176         while( p/10 )

177         {

178             p = p/10;

179             tempC++;

180         }

181         if( tempC > nBit )

182             nBit = tempC;

183     }

184     return nBit;

185 }

186 

187 void RadixSort(int data[], int n)

188 {  

189     int* tmp = new int[n];

190     int count[10];    // 每一桶中的个数

191     int nBit = maxbit(data,n);

192     int r=1;

193 

194     for(int i=0; i<nBit; i++)

195     {

196             // 装桶之前要先清桶

197         for(int i=0;i<10;i++)

198             count[i]=0;

199 

200         for(i=0;i<n;i++)    // 记录每个桶的个数

201         {

202             int k=data[i]/r;

203             int q=k%10;

204             count[q]++;

205         }

206         for(i=1; i<10; i++)    // 计算位置

207         {

208             count[i] += count[i-1];

209         }

210         for(int j=n-1; j>=0; j--)

211         {

212             int p = data[j]/r;

213             int s = p%10;

214             tmp[count[s]-1] = data[j];

215             count[s]--;                

216         }

217         for(i=0; i<n; i++)

218         {

219             data[i] = tmp[i];        

220         }            

221         r = r*10;    // 更高一位

222 

223     }

224 

225 }

226 

227 

228 // 计数排序

229 void CountSort(int* pData, int n)

230 {

231     int* pCout = NULL;            // 记数的指针

232     int* pSort = NULL;            // 暂存排序结果的指针

233     pCout = (int*)malloc(sizeof(int) * n);    // 申请空间

234     pSort = (int*)malloc(sizeof(int) * n);   

235 

236 

237         // 初始化记数为0

238     for (int i = 0; i < n; ++i)

239     {

240         pCout[i] = 0;

241     }

242         // 统计相同元素的个数

243     for (int i = 0; i < n; ++i)

244     {

245         ++pCout[pData[i]];       

246     }

247         // pCout[i]中是 <= i 的元素个数

248     for (int i = 1; i < n; ++i)

249     {

250         pCout[i] += pCout[i-1];    

251     }

252     for (int i = 0; i < n; ++i)

253     {

254         pSort[pCout[pData[i]]] = pData[i];    // 把每一个元素放在数组中相应的位置;因为pCout[pData[i]]的值就是不比他大数据的个数;      

255         pCout[pData[i]]--;                    // 如果有相同数据的元素先减1

256     }

257         // 排序结束,复制到原来数组中

258     for (int i = 0; i < n; ++i)

259     {

260         pData[i] = pSort[i];

261     }

262         // 释放申请的空间

263     free(pCout);

264     free(pSort);

265 }

266 

267 /* 对顺序表L作简单选择排序 */

268 void SelectSort(SqList *L)

269 {

270     int min;

271     for( int i=1; i<L->length; i++)

272     { 

273         min = i;                        /* 将当前下标定义为最小值下标 */

274         for ( int j = i+1;j<=L->length;j++)/* 循环之后的数据 */

275         {

276             if (L->r[min] > L->r[j])    /* 如果有小于当前最小值的关键字 */

277                 min = j;                /* 将此关键字的下标赋值给min */

278         }

279         if(i != min)                    /* 若min不等于i,说明找到最小值,交换 */

280             swap(L, i, min);            /* 交换L->r[i]与L->r[min]的值 */

281     }

282 }

283 

284 // 简单选择排序的改进   二元选择排序

285 void SelectSort(int r[],int n) 

286 {  

287     int i, j, min, max, tmp;  

288     for (i = 1; i <= n/2; i++) 

289     {    

290             // 做不超过n/2趟选择排序   

291         min = i; max = i ;    // 分别记录最大和最小关键字记录位置  

292         for (j = i+1; j <= n-i; j++) 

293         {  

294             if (r[j] > r[max]) 

295             {   

296                 max = j; 

297                 continue;   

298             }    

299             if (r[j] < r[min]) 

300             {   

301                 min = j;   

302             }     

303         }    

304 

305         tmp = r[i-1]; r[i-1] = r[min]; r[min] = tmp;  // swap(a, min, i-1);

306         tmp = r[n-i]; r[n-i] = r[max]; r[max] = tmp;  // swap(a, max, n-i)

307     }   

308 } 

309 

310 /* 对顺序表L作直接插入排序 

311 

312 插入排序(insert sorting)思想:

313 当插入第i个元素时,前面的v[0],v[1],v[2]......v[i-1],已经排好序了.

314 这时用v[i]的插入码与 v[i-1],v[i-2],......排序码进行比较,

315 找到插入的位置即插入v[i],原来位置上的元素从后向前依次后移。

316 

317 时间复杂度:  平均比较次数O(n2),平均移动次数 O(n2).

318 直接插入排序是一种稳定的排序。元素大部分有序时 效率会更高,这时比较次数和移动次数都会减少。

319 

320 */

321 void InsertSort(SqList *L)

322 { 

323     int j;

324     for( int i=2; i<=L->length; i++)

325     {

326         if (L->r[i] < L->r[i-1])        /* 需将L->r[i]插入有序子表 */

327         {

328             L->r[0] = L->r[i];            /* 设置哨兵 */

329             for( j=i-1; L->r[j] > L->r[0]; j--)

330                 L->r[j+1] = L->r[j];    /* 记录后移 */

331 

332             L->r[j+1] = L->r[0];        /* 插入到正确位置 */

333         }

334     }

335 }

336 

337 /* 对顺序表L作希尔排序 

338 

339 希尔排序(Shell sort)基本思想: 改进的直接插入算法。

340 设待排序的元素序列有n个元素,首先取一整数gap(<n)作为间隔,将全部元素分为gap个子序列,

341 所有距离为gap的元素 放在同一序列中,在每个子序列中分别进行直接插入排序。

342 然后缩小gap,例如gap = gap/2,重复上述的子序列划分与排序工作。

343 开始由于gap取值大,每个子序列元素少,排序速度快,待排序后期,

344 gap值逐渐变小,子序列元素变多,但由于前面的工作基础,大多数元素已经有序,所以排序速度快。

345 

346 

347 希尔排序是一种不稳定的排序

348 */

349 void ShellSort(SqList *L)

350 {

351     int j, k = 0;

352     int d = L->length;

353     do

354     {

355         d = d/3 + 1;                /* 增量序列 */

356         for(int i=d+1; i<=L->length; i++)

357         {

358             if (L->r[i] < L->r[i-d])    /*  需将L->r[i]插入有序增量子表 */ 

359             { 

360                 L->r[0] = L->r[i];        /*  暂存在L->r[0] */

361                 for( j = i-d; j>0 && L->r[0]<L->r[j]; j -= d)

362                     L->r[j+d]=L->r[j];    /*  记录后移,查找插入位置 */

363 

364                 L->r[j+d]=L->r[0];        /*  插入 */

365             }

366         }

367         printf("第%d趟排序结果: ",++k);

368         print(*L);

369     }

370     while( d > 1 );

371 

372 }

373 

374 

375 /*  

376 大根堆排序的基本思想: 

377 1) 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区; 

378 2) 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,

379     由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key; 

380 3) 由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。 

381     然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,

382     由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系 R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。

383 */

384 

385 /*

386  @brief:

387      已知L->r[s..len]中记录的关键字除L->r[s]之外均满足堆的定义,

388      本函数调整L->r[s]的关键字,使L->r[s..len]成为一个大顶堆

389  @param:

390     cur: 当前位置 s

391     len: 当前状态的最大值

392 

393 m:当前堆的大小

394  */

395 void HeapAdjust(SqList *L, int cur, int len)

396 { 

397     int temp = L->r[cur];

398     for(int j = 2*cur; j <= len; j *= 2)// 沿关键字较大的孩子结点向下筛选(大根堆)

399     {

400         if(j < len && L->r[j] < L->r[j+1])

401             ++j;                        // j为关键字中较大的记录的下标

402         if(temp >= L->r[j])

403             break;                        /* 应插入在位置 cur 上 */

404 

405         L->r[cur] = L->r[j];

406         cur = j;

407     }

408     L->r[cur] = temp;                    /* 插入 */

409 }

410 

411 /*  对顺序表L进行堆排序 */

412 void HeapSort( SqList* L )

413 {

414     for( int i = L->length/2; i>0; i--)    /*  把L中的r构建成一个大根堆 */

415          HeapAdjust(L, i, L->length);

416 

417     for( int i = L->length; i>1; i--)

418     { 

419          swap(L, 1, i);                /* 将堆顶记录和当前未经排序子序列的最后一个记录交换 */

420          HeapAdjust(L, 1, i-1);        /* 将L->r[1..i-1]重新调整为大根堆 */

421     }

422 }

423 

424 

425 #if 0

426 

427 

428 #include <iostream>

429 #include <algorithm>

430 

431 using std::cout;

432 using std::cin;

433 using std::endl;

434 

435 template<class T>

436 class Out

437 {

438 public:

439     void operator()(T o)

440     {

441         cout<<o<<'\t';

442     }

443 };

444 template<class T>

445 void Swap(T& a,T&b)

446 {

447     if(a == b)

448         return;

449     T t=a;

450     a=b;

451     b=t;

452 }

453 inline int Rt(int idx)

454 {

455     return (idx<<1)+2;

456 }

457 inline int Lt(int idx)

458 {

459     return (idx<<1)+1;

460 }

461 

462 template<class T>

463 void HeapBuild(T* A,int idx,int size)

464 {

465     int child;

466     for(; idx<=size/2; idx=child)

467     {

468         child=Lt(idx);

469         if (child<size&&A[child]>A[idx])

470         {

471             Swap(A[idx],A[child]);

472         }

473         child=Rt(idx);

474         if (child<size&&A[child]>A[idx])

475         {

476             Swap(A[idx],A[child]);

477         }

478     }

479 }

480 template<class T>

481 void HeapSort(T* A, int size)

482 {

483     if(size == 1)

484         return;

485 

486     for (int i=size/2; i>=0; i--)

487     {

488         HeapBuild(A,i,size);

489     }

490     int i=size-1;

491     cout<<"swap max number:"<<A[0]<<","<<A[i]<<endl;

492     Swap(A[0],A[i]);

493     //现在得到了一个最大值,对前size-1个递归调用HeapSort

494     HeapSort(A, i);

495 }

496 

497 int main()

498 {

499     int size=0;

500     cout<<"enter elements count num:"<<endl;

501     cin>>size;

502     //    size = 10;

503     int* elems = new int[size];

504     //    int elems[] = {1, 8, 4, 5, 6, 7, 11, 2, 3, 45};

505     cout<<"Input all elements to be sorted:"<<endl;

506     for(int i=0; i<size; cin>>elems[i++]);

507 

508     HeapSort(elems,size);

509     std::for_each(elems,elems+size,Out<int>());

510     delete []elems;

511 

512     system("pause");

513     return 0;

514 

515 }

516 

517 #endif

518 

519 #pragma region MergeSort

520 /*  

521 归并算法思想:

522     分而治之(divide - conquer);每个递归过程涉及三个步骤

523     1) 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.

524     2) 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作

525     3) 合并: 合并两个排好序的子序列,生成排序结果. 

526 */

527 

528 /* 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n] */

529 void Merge(int SR[],int TR[], int start, int mid, int end)

530 {

531     int j,k,l;

532     for(j=mid+1,k=start; start<=mid && j<=end; k++)    /* 将SR中记录由小到大地并入TR */

533     {

534         if (SR[start] < SR[j])

535             TR[k] = SR[start++];

536         else

537             TR[k] = SR[j++];

538     }

539     if(start<=mid)

540     {

541         for(l=0; l<=mid-start; l++)

542             TR[k+l] = SR[start+l];        /* 将剩余的SR[i..m]复制到TR */

543     }

544     if(j<=end)

545     {

546         for(l=0; l<=end-j; l++)

547             TR[k+l] = SR[j+l];            /* 将剩余的SR[j..n]复制到TR */

548     }

549 }

550 

551 /* 递归法 */

552 /* 将SR[s..t]归并排序为TR1[s..t] */

553 void MSort(int SR[],int TR1[], int start, int end)

554 {

555     int mid;

556     int TR2[MAXSIZE+1];

557 

558     if(start == end)

559     {

560         TR1[start] = SR[start];

561     }

562     else

563     {

564         mid = (start + end)/2;        /* 将SR[s..t]平分为SR[s..m]和SR[m+1..t] */

565         MSort(SR,TR2, start, mid);    /* 递归地将SR[s..m]归并为有序的TR2[s..m] */

566         MSort(SR,TR2, mid+1, end);    /* 递归地将SR[m+1..t]归并为有序的TR2[m+1..t] */

567 

568         Merge(TR2,TR1, start, mid, end);    /* 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t] */

569     }

570 }

571 

572 /* 对顺序表L作归并排序 */

573 void MergeSort(SqList *L)

574 { 

575     MSort(L->r, L->r, 1, L->length);

576 }

577 

578 

579 /* 非递归法 */

580 /* 

581 @brief:

582     将SR[]中相邻长度为s的子序列两两归并到TR[] 

583 @param:

584     size: 归并相邻字段的大小

585      len: 原始数据的总长度

586 */

587 void MergePass(int SR[],int TR[], int size,int len)

588 {

589     int i = 1;

590 

591     while(i <= len-2*size+1)

592     {            

593         Merge(SR,TR, i, i+size-1, i+2*size-1);    // 两两归并(归并长度为 size 的两个相邻子序列)

594         i += 2*size;        

595     }

596 

597     if(i < len-size+1)                // 归并最后两个序列(尚有两个子序列,其中后一个长度小于len)

598     {

599         Merge(SR,TR, i, i+size-1, len);

600     }

601     else                            // 若最后只剩下单个子序列

602     {

603         for( int j = i; j <= len; j++)

604             TR[j] = SR[j];

605     }

606 }

607 

608 /* 对顺序表L作归并非递归排序 */

609 void MergeSort2(SqList *L)

610 {

611     int* TR = (int*)malloc( L->length * sizeof(int) );    /* 申请额外空间 */

612 

613     int _size = 1;

614     while( _size < L->length )

615     {

616         MergePass(L->r, TR, _size, L->length);

617         _size *= 2;        /* 子序列长度加倍 */

618 

619         MergePass(TR, L->r, _size, L->length);

620         _size *= 2;        /* 子序列长度加倍 */

621     }

622 }

623 

624 /*

625 (归并)算法分析

626 

627 1、稳定性

628     归并排序是一种稳定的排序。

629 

630 2、存储结构要求

631     可用顺序存储结构,也易于在链表上实现。

632 

633 3、时间复杂度

634     对长度为n的文件,需进行log(n)趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。

635 

636 4、空间复杂度

637     需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。

638 */

639 

640 #pragma endregion MergeSort

641 

642 #pragma region QuickSort

643 /* 交换顺序表L中子表的记录,使枢轴记录到位,并返回其所在位置 */

644 /* 此时在它之前(后)的记录均不大(小)于它。 */

645 int Partition(SqList *L,int low,int high)

646 { 

647     int pivotkey;

648 

649     pivotkey = L->r[low]; /* 用子表的第一个记录作枢轴记录 */

650     while(low < high)          /* 从表的两端交替地向中间扫描 */

651     { 

652         while(low<high && L->r[high]>=pivotkey)

653             high--;

654         swap(L,low,high);/* 将比枢轴记录小的记录交换到低端 */

655         while(low<high && L->r[low]<=pivotkey)

656             low++;

657         swap(L,low,high);/* 将比枢轴记录大的记录交换到高端 */

658     }

659     return low; /* 返回枢轴所在位置 */

660 }

661 

662 /* 对顺序表L中的子序列L->r[low..high]作快速排序 */

663 void QSort(SqList *L,int low,int high)

664 { 

665     int pivot;

666     if(low < high)

667     {

668         pivot = Partition(L,low,high);    /*  将L->r[low..high]一分为二,算出枢轴值pivot */

669         QSort(L, low, pivot-1);            /*  对低子表递归排序 */

670         QSort(L, pivot+1, high);        /*  对高子表递归排序 */

671     }

672 }

673 

674 /* 对顺序表L作快速排序 */

675 void QuickSort(SqList *L)

676 { 

677     QSort(L, 1, L->length);

678 }

679 

680 

681 /* 改进后快速排序******************************** */

682 

683 /* 快速排序优化算法 */

684 int Partition1(SqList *L,int low,int high)

685 { 

686     int pivotkey;

687 

688     int m = low + (high - low) / 2; /* 计算数组中间的元素的下标 */  

689     if (L->r[low]>L->r[high])            

690         swap(L,low,high);    /* 交换左端与右端数据,保证左端较小 */

691     if (L->r[m]>L->r[high])

692         swap(L,high,m);        /* 交换中间与右端数据,保证中间较小 */

693     if (L->r[m]>L->r[low])

694         swap(L,m,low);        /* 交换中间与左端数据,保证左端较小 */

695 

696     pivotkey = L->r[low]; /* 用子表的第一个记录作枢轴记录 */

697     L->r[0]  = pivotkey;    /* 将枢轴关键字备份到L->r[0] */

698     while(low<high) /*  从表的两端交替地向中间扫描 */

699     { 

700         while(low<high&&L->r[high]>=pivotkey)

701             high--;

702         L->r[low]=L->r[high];

703         while(low<high&&L->r[low]<=pivotkey)

704             low++;

705         L->r[high]=L->r[low];

706     }

707     L->r[low]=L->r[0];

708     return low;        /* 返回枢轴所在位置 */

709 }

710 

711 void QSort1(SqList *L,int low,int high)

712 { 

713     int pivot;

714     if( (high-low) > MAX_LENGTH_INSERT_SORT )

715     {

716         while(low < high)

717         {

718             pivot = Partition1(L, low, high); /*  将L->r[low..high]一分为二,算出枢轴值pivot */

719             QSort1(L,low,pivot-1);        /*  对低子表递归排序 */

720             QSort1(L,pivot+1,high);        /*  对高子表递归排序 */

721             low=pivot+1;    /* 尾递归 */

722         }

723     }

724     else

725         InsertSort(L);

726 }

727 

728 /* 对顺序表L作快速排序 */

729 void QuickSort1(SqList *L)

730 { 

731     QSort1(L, 1, L->length);

732 }

733 

734 #pragma endregion QuickSort

735 

736 

737 

738 #define N 9

739 int main()

740 {

741    int i;

742    

743    /* int d[N]={9,1,5,8,3,7,4,6,2}; */

744    int d[N]={50,10,90,30,70,40,80,60,20};

745    /* int d[N]={9,8,7,6,5,4,3,2,1}; */

746 

747    SqList l0,l1,l2,l3,l4,l5,l6,l7,l8,l9,l10;

748    

749    for(i=0;i<N;i++)

750      l0.r[i+1] = d[i];

751    l0.length = N;

752 

753    l1=l2=l3=l4=l5=l6=l7=l8=l9=l10=l0;

754 

755    printf("排序前:\n");

756    print(l0);

757 

758    printf("初级冒泡排序:\n");

759    BubbleSort0(&l0);

760    print(l0);

761    

762    printf("冒泡排序:\n");

763    BubbleSort(&l1);

764    print(l1);

765    

766    printf("改进冒泡排序:\n");

767    BubbleSort2(&l2);

768    print(l2);

769    

770    printf("选择排序:\n");

771    SelectSort(&l3);

772    print(l3);

773    

774    printf("直接插入排序:\n");

775    InsertSort(&l4);

776    print(l4);

777 

778    printf("希尔排序:\n");

779    ShellSort(&l5);

780    print(l5);

781     

782    printf("堆排序:\n");

783    HeapSort(&l6);

784    print(l6);

785 

786    printf("归并排序(递归):\n");

787    MergeSort(&l7);

788    print(l7);

789 

790    printf("归并排序(非递归):\n");

791    MergeSort2(&l8);

792    print(l8);

793 

794    printf("快速排序:\n");

795    QuickSort(&l9);

796    print(l9);

797 

798    printf("改进快速排序:\n");

799    QuickSort1(&l10);

800    print(l10);

801 

802 

803 /*大数据排序*/

804 /* 

805     srand(time(0));  

806     int Max=10000;

807     int d[10000];

808     int i;

809     SqList l0;

810     for(i=0;i<Max;i++)

811         d[i]=rand()%Max+1;

812     for(i=0;i<Max;i++)

813         l0.r[i+1]=d[i];

814     l0.length=Max;

815     MergeSort(l0);

816     print(l0);

817 */

818 

819     system("pause");

820     return 0;

821 }

 

你可能感兴趣的:(sort)