各種基本演算法實現小結(五)—— 排序演算法
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
各種基本演算法實現小結(五)—— 排序演算法
(均已測試通過)
* 選擇排序 |____簡單選擇排序 |____堆排序 |____歸併排序
* 交換排序 |____氣泡排序 |____快速排序
* 插入排序
* 分配排序 |____箱排序 |____基數排序
======================================================================
簡單排序演算法
1、 氣泡排序
測試環境:VC 6.0 (C)
[cpp] view plain copy print ?- #include
- <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #define MAX 11
- void input(int num[])
- {
- int i;
- srand((unsigned)time(NULL));
- for(i=1; i<MAX; i++)
- num[i]=rand()%100;
- }
- void output(int num[])
- {
- int i;
- for(i=1; i<MAX; i++)
- {
- printf("%5d", num[i]);
- if(0 == i%10)
- printf("/n");
- }
- printf("/n");
- }
- void sort(int num[])
- {
- int i, j, tmp;
- for(i=1; i<MAX-1; i++)
- {
- printf("bubble.../n");
- for(j=1; j<MAX-i; j++)
- {
- printf("%5d", num[j]);
- if(num[j]>num[j+1])
- {
- tmp=num[j];
- num[j]=num[j+1];
- num[j+1]=tmp;
- }
- }
- printf("%5d/n", num[MAX-i]);
- printf("bubble after.../n");
- for(j=1; j<MAX; j++)
- printf("%5d", num[j]);
- printf("/n");
- }
- }
- /* bubble sort */
- /*
- void sort(int num[])
- {
- int i, j, tmp;
- for(i=1; i<MAX-1; i++)
- {
- for(j=1; j<MAX-i; j++)
- if(num[j]>num[j+1])
- {
- tmp=num[j];
- num[j]=num[j+1];
- num[j+1]=tmp;
- }
- }
- }
- */
- void main()
- {
- int num[MAX];
- printf("sort before.../n");
- input(num);
- output(num);
- sort(num);
- printf("sort after.../n");
- output(num);
- }
執行結果:
=======================================================
2、雙向氣泡排序
據說可以提高效率,減少比較次數和交換次數
但仔細分析可得,每次while迴圈,都for迴圈比較了兩次
因此每次low和high各減1,總體上比較次數並未減少,兩次for交換也未減少
個人認為雙向冒泡演算法並未有效的減少比較次數和交換次數,但此演算法也富含程式設計思想,值得學習
測試環境:VC 6.0 (C)
[cpp] view plain copy print ?- #include
- <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #define swap(x, y){int tmp; tmp=x; x=y; y=tmp;}
- #define MAX 11
- void input(int num[])
- {
- int i;
- srand((unsigned)time(NULL));
- for(i=1; i<MAX; i++)
- num[i]=rand()%100;
- }
- void output(int num[])
- {
- int i;
- for(i=1; i<MAX; i++)
- {
- printf("%5d", num[i]);
- if(0 == i%10)
- printf("/n");
- }
- }
- void sort(int num[], int low, int high)
- {
- int i;
- while(low<high)
- {
- for(i=low; i<high; i++) /* bubble to high */
- if(num[i]>num[i+1])
- swap(num[i], num[i+1]);
- high--;
- for(i=high; i>low; i--) /* bubble to low */
- if(num[i]<num[i-1])
- swap(num[i], num[i-1]);
- low++;
- }
- }
- void main()
- {
- int num[MAX];
- input(num);
- printf("sort before.../n");
- output(num);
- sort(num, 1, MAX-1);
- printf("sort after.../n");
- output(num);
- }
執行結果:
=======================================================
3、選擇排序
測試環境:VC 6.0 (C)
[cpp] view plain copy print ?- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #define MAX 101
- void input(int num[])
- {
- int i;
- srand((unsigned)time(NULL));
- for(i=1; i<MAX; i++)
- num[i]=rand()%100;
- }
- void output(int num[])
- {
- int i;
- for(i=1; i<MAX; i++)
- {
- printf("%5d", num[i]);
- if(0 == i%10)
- printf("/n");
- }
- printf("/n");
- }
- void sort(int num[])
- {
- int i, j, k, tmp;
- for(i=1; i<MAX-1; i++)
- {
- k=i;
- for(j=i+1; j<MAX; j++)
- if(num[k]>num[j])
- k=j;
- if(i<k)
- {
- tmp=num[i];
- num[i]=num[k];
- num[k]=tmp;
- }
- }
- }
- void main()
- {
- int num[MAX];
- printf("sort before.../n");
- input(num);
- output(num);
- sort(num);
- printf("sort after.../n");
- output(num);
- }
執行結果:
=======================================================
中級排序演算法
向部分已排好序數列插入新值,使整個數列最終都有序
1、直接插入排序
測試環境:VC 6.0 (C)
[cpp] view plain copy print ?- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #define MAX 11
- void input(int num[])
- {
- int i;
- srand((unsigned)time(NULL));
- for(i=1; i<MAX; i++)
- num[i]=rand()%100;
- }
- void output(int num[])
- {
- int i;
- for(i=1; i<MAX; i++)
- {
- printf("%5d", num[i]);
- if(0 == i%10)
- printf("/n");
- }
- printf("/n");
- }
- void sort(int num[])
- {
- int i, pos, tmp;
- for(i=2; i<MAX; i++) /* from 2 to sorting */
- {
- pos=i;
- tmp=num[pos];
- while(pos>1 && tmp<num[pos-1])
- {
- num[pos]=num[pos-1];
- pos--;
- }
- num[pos]=tmp;
- }
- }
- void main()
- {
- int num[MAX];
- printf("sort before.../n");
- input(num);
- output(num);
- sort(num);
- printf("sort after.../n");
- output(num);
- }
執行結果:
=======================================================
2、 折半插入排序
折半插入排序演算法是一種穩定的排序演算法,比直接插入演算法明顯減少了關鍵字之間比較的次數
因此速度比直接插入排序演算法快,但記錄移動的次數沒有變,
所以折半插入排序演算法的時間複雜度仍然為O(n^2),
測試環境:VC 6.0 (C)
[cpp] view plain copy print ?- #include
- <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #define MAX 11
- void input(int num[])
- {
- int i;
- srand((unsigned)time(NULL));
- for(i=1; i<MAX; i++)
- num[i]=rand()%100;
- }
- void output(int num[])
- {
- int i;
- for(i=1; i<MAX; i++)
- {
- printf("%5d", num[i]);
- if(0 == i%10)
- printf("/n");
- }
- printf("/n");
- }
- void sort(int num[], int low, int high)
- {
- int i, j, mid;
- int l, h;
- for(i=2; i<=high; i++)
- {
- l=low;
- h=i-1;
- num[0]=num[i]; /* save */
- while(l<=h)
- {
- mid=(l+h)/2;
- if(num[0]<num[mid])
- h=mid-1;
- else
- l=mid+1;
- }
- for(j=i; j>l; j--) /* move */
- num[j]=num[j-1];
- num[l]=num[0];
- }
- }
- void main()
- {
- int num[MAX];
- input(num);
- printf("sort before.../n");
- output(num);
- sort(num, 1, MAX-1);
- printf("sort after.../n");
- output(num);
- }
執行結果:
=======================================================
3、 2-路插入排序
2-路插入排序:是在折半插入排序的基礎上再次改進,其目的是減少排序過程中記錄移動的次數
測試環境:VC 6.0 (C)
[cpp] view plain copy print ?- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #define MAX 11
- int num2[MAX];
- void input(int num[])
- {
- int i;
- srand((unsigned)time(NULL));
- for(i=1; i<MAX; i++)
- num[i]=rand()%100;
- }
- void output(int num[])
- {
- int i;
- for(i=1; i<MAX; i++)
- {
- printf("%5d", num[i]);
- if(0 == i%10)
- printf("/n");
- }
- printf("/n");
- }
- void bi_insertsort(int num[], int len)
- {
- int i, j, pos, head, tail;
- head=tail=1;
- num2[1]=num[1];
- for(i=2; i<=len; i++)
- {
- if(num[i]>num2[1]) /* larger, save to tail */
- {
- for(j=tail; j>1; j--)
- {
- if(num[i]<num2[j])
- num2[j+1]=num2[j];
- else
- break;
- }
- num2[j+1]=num[i];
- tail++;
- }
- else /* smaller, save to head */
- {
- if(head==1) /* first to end, then to head... */
- {
- num2[len]=num[i];
- head=len;
- }
- else
- {
- for(j=head; j<=len; j++)
- {
- if(num[i]>num2[j])
- num2[j-1]=num2[j];
- else
- break;
- }
- num2[j-1]=num[i];
- head--;
- }
- }
- }
- pos=1;
- for(i=1; i<=len; i++) /* move back data from num2[] to num[] */
- {
- if(head<=len)
- num[i]=num2[head++];
- else if(pos<=tail)
- num[i]=num2[pos++];
- }
- }
- int main()
- {
- int num[MAX]; /* 1 - len is num, 0->null */
- input(num);
- printf("sort before.../n");
- output(num);
- bi_insertsort(num, MAX-1);
- printf("sort after.../n");
- output(num);
- return 0;
- }
執行結果:
=======================================================
4、合併插入排序(陣列實現)
將兩個有序陣列A、B合併成另一個有序的大陣列C
測試環境:VC 6.0 (C)
[cpp] view plain copy print ?- #include <stdio.h>
- void input_num1(int num[], int n1)
- {
- int i;
- for(i=1; i<=n1; i++)
- num[i]=3*(i-1);
- printf("/nnum 1.../n");
- for(i=1; i<=n1; i++)
- {
- printf("%5d", num[i]);
- if(0 == i%10)
- printf("/n");
- }
- }
- void input_num2(int num[], int n2)
- {
- int i;
- for(i=1; i<=n2; i++)
- num[i]=i;
- printf("/nnum 2.../n");
- for(i=1; i<=n2; i++)
- {
- printf("%5d", num[i]);
- if(0 == i%10)
- printf("/n");
- }
- }
- void output_num3(int num1[], int n1, int num2[], int n2, int num3[], int n3)
- {
- int pos1, pos2, pos3;
- pos3=pos2=pos1=1;
- &