來亞嵌一個多月了,感覺進步挺大,但是其他同學進步更是飛速,壓力很大,很怕他們馬上超過啊,所以這些天一直惶恐的想着提升自己,左想右想,把數據結構拿出來複習來了,看到那些排序,動手實現了一遍,看到幾個同學居然也寫了幾篇關於排序的筆記,拿我就先貼出來和大家一起分享,有些地方我感覺自己實現的效率不高,各位有想法的交流一下~~
我在linux下也的,但是我的系統發不了筆記,所以傳到windows下面來發,但是註釋全變亂碼了,各位將就一下
1.第一個自然是常用的冒泡,不說了,這個簡單
- /*-----------鏀硅繘鍐掓場鎺掑簭-----------------*/
- /*濡傛灉鏌愯稛鏈彂鐢熶氦鎹紝鍒欏彲璁や負鏁版嵁宸茬粡鏈夊簭*/
- #include<stdio.h>
- /*-----------鍐掓場鎺掑簭---------------------*/
- void sort(int array[],int n)
- {
- int i,j,flag,temp;
- for(i = 0; i < n; i++)
- {
- flag = 1;
- for(j = 0; j < n-i-1; j++)
- {
- if(array[j] > array[j+1])
- {
- /* array[j] ^= array[j+1];
- array[j+1] ^= array[j];
- array[j] ^= array[j+1];
- */ temp = array[j];
- array[j] = array[j+1];
- array[j+1] = temp;
- flag = 0;
- }
- }
- if(flag == 1) break;
- printf("%d ",i);
- }
- return;
- }
- int main(void)
- {
- int a[] = {1,34,1,3,312,65,341,423,432,312,6,53,5,323,3,36,46,74,7,47,35,1,45,14,12};
- int i;
- sort(a,25);
- printf("/n");
- for(i = 0; i < 25;i++)
- printf("%d ",a[i]);
- return 0;
- }
2.也是很簡單的,插入排序,不解釋
- /*�入��*/
- #include<stdio.h>
- /*数组方�的�入��*/
- void move(int a[], int i ,int n)
- {
- for(; n > i; n--)
- a[n] = a[n-1];
- }
- void array_insert(int a[], int n, int item)
- {
- int i;
- if(item <= a[0])
- {
- move(a, 0, n);
- a[0] = item;
- }
- else if(item >= a[n-1])
- {
- a[n] = item;
- }
- else
- {
- for(i = 0; i < n-1; i++)
- {
- if(item > a[i] && item <= a[i+1])
- {
- move(a, i+1, n);
- a[i+1] = item;
- }
- }
- }
- }
- int main(void)
- {
- int a[]={1,4,5,6,9,2,3,6,8,10};
- int i;
- for(i = 0; i < 10; i++)
- {
- array_insert(a, i, a[i]);
- }
- for(i = 0; i< 10; i++)
- printf("%d ", a[i]);
- printf("/n");
- return 0;
- }
3.還是比較簡單的,選擇排序
- /*选择��*/
- #include<stdio.h>
- void select(int a[], int n)
- {
- int i, j, min, k;
- for(i = 0; i < n; i++)
- {
- min = 0x7fffffff;
- for(j = i; j < n; j++)
- {
- if(a[j] < min)
- {
- min = a[j];
- k = j;
- }
- }
- a[k] = a[i];
- a[i] = min;
- }
- }
- int main(void)
- {
- int a[]= {0,34,313,45,123,123,12,23,4};
- int i;
- select(a, sizeof(a)/sizeof(a[0]));
- for(i = 0; i < sizeof(a)/sizeof(a[0]); i++)
- printf("%d ",a[i]);
- printf("/n");
- return 0;
- }
4.快速排序,這個說下,原理就是,用一個數作爲分割,大的放左邊,小的放右邊,這樣就分成了兩個部分,而且一部分最大的數會比另一部分小,然後遞歸!
- /*快速��的��*/
- #include<stdio.h>
- #define M 10
- #define SWAP mid = a[high]; a[high] = a[low]; a[low] = mid
- /*一趟��*/
- int partition(int a[], int low, int high)
- {
- int temp = a[low];
- int mid;
- while(low < high)
- {
- while( (low < high) && (a[high] >= temp) )
- high--;
- SWAP;
- while( (low < high) && (a[low] <= temp) )
- low++;
- SWAP;
- }
- return low;/*è¿”å›?当å‰?的临界å??æ ‡*/
- }
- /*递归对数组进行快速��*/
- void quik(int a[],int low, int high)
- {
- int temp ;
- if(low < high)
- {
- temp = partition(a, low, high);
- quik(a, low, temp - 1);
- quik(a, temp + 1, high);
- }
- }
- int main(void)
- {
- int i;
- int a[]={1,4,6,32,5,3,5,66,341,43,3};
- quik(a, 0, sizeof(a)/sizeof(int) - 1);
- for(i = 0; i < sizeof(a)/sizeof(int); i++)/*sizeof(a)是常数*/
- printf("%d ",a[i]);
- printf("/n");
- return 0;
- }
5.希爾排序,就是直接插入排序的改進版,通過增量的方式減少插入數據後數組元素移動的次數以提高效率
- /*希尔��*/
- #include<stdio.h>
- void shell(int a[], int dk,int n)
- {
- int i, j, temp;
- for(i = dk; i< n; i++)
- {
- if(a[i] < a[i-dk])
- {
- temp = a[i];
- for(j = i-dk; j>0 && temp<a[j]; j -= dk)
- a[j+dk] = a[j];
- a[j+dk] = temp;
- }
- }
- }
- void shellsort(int a[], int n, int dlta[], int t)
- {
- int i;
- for(i = 0; i < t; i++)
- shell(a, dlta[i], n);
- }
- int main(void)
- {
- int a[] = {1,42,42,46,63,33,22,3234,234,5234};
- int dlta[] = {5,3,1};
- int i;
- shellsort(a, sizeof(a)/sizeof(a[0]), dlta, sizeof(dlta)/sizeof(dlta[0]));
- for(i = 0; i < sizeof(a)/sizeof(a[0]); i++)
- printf("%d ", a[i]);
- printf("/n");
- return 0;
- }
6.歸併,效率達到理論極限,但是需要額外的空間。原理就是將原本有序的數列兩兩合併,最後合併成一個數列。時間複雜度是nlogn
- #include<stdio.h>
- #include<malloc.h>
- void merge(int a[], int p, int q, int r)
- {
- int i,j,k = 0;
- int *buf = (int *)malloc( (r-p+1) * sizeof(int) );
- i = p;
- j = q+1;
- while((i <= q) && (j <= r))
- {
- if(a[i] < a[j])
- buf[k++] = a[i++];
- else
- buf[k++] = a[j++];/*��到大��*/
- }
- if(q+1 == i)/*i==q+1时,qä»¥å†…æ— å‰©ä½™*/
- {
- for(j; j <= r; j++)
- buf[k++] = a[j];
- }
- else
- {
- for(i; i <= q; i++)
- buf[k++] = a[i];
- }
- for(i = p; i <= r; i++)
- a[i] = buf[i-p];
- free(buf);
- }
- void merge_sort(int a[], int n)
- {
- int start,end = 1,i;
- while(end < n)
- {
- start = end;
- end = 2 * start;
- i = 0;
- while((i + end) < n)
- {
- merge(a, i, i+start-1, i+end-1);
- i += end;
- }
- if((i + start) < n)/*当i+end>n&&i+start<n时,说�还有一个��的没有归并*/
- {
- merge(a, i, i+start-1, n-1);
- }
- }
- }
- int main(void)
- {
- int i;
- int a[] = {50,34,41,61,4,2,3,13,3,14,1,4,1};
- merge_sort(a, 13);
- for(i = 0; i < 13; i++)
- printf("%d ",a[i]);
- printf("/n");
- return 0;
- }
7.堆排序,以前感覺這個很神祕,但是實現了,其實也就是那麼回事,不過確實非常巧妙,時間複雜度是nlogn而且不需要額外空間,堆和歸併,應該是大型的排序裏首選的算法
- /*----------------å †--------------------------*/
- /*å †ä¸ºæœ€å¤§å †ï¼Œæ—¢æ»¡è¶³k(i)>=k(2i)&&k(i)>=k(zi+1)*/
- #include<stdio.h>
- #include<malloc.h>
- #include<math.h>
- #define M 20/*åˆ?å§‹æ•°ç»„å…ƒç´ ä¸ªæ•°*/
- #define INC 5/*æ¯?次申请内å˜å¢?é‡?*/
- #define FALSE 0
- #define TRUE 1
- /*-------------交�数�--------------*/
- void swap(int *a, int *b)
- {
- int c;
- c = *a;
- *a = *b;
- *b = c;
- }
- int * max(int *a, int *b)
- {
- if(*a > *b)
- return a;
- else
- return b;
- }
- /*----------- å †çš„ä¸Šç§»æ“?作-----------*/
- /*把hå †ä¸çš„第iä¸ªå…ƒç´ ä¸Šç§» */
- void sift_up(int h[], int i)
- {
- int done = FALSE;
- if(i > 0)
- {
- while(!done && i>0)
- {
- if(h[i] > h[i/2])
- swap(&h[i],&h[i/2]);
- else
- done = TRUE;
- i /= 2;
- }
- }
- }
- /*-----------å †çš„ä¸‹ç§»æ“?作------------------*/
- /*把hå †ä¸çš„第iä¸ªå…ƒç´ ä¸‹ç§» , n是hä¸çš„å…ƒç´ ä¸ªæ•°*/
- void sift_down(int h[], int n, int i)
- {
- int done = FALSE, j, *max_i;
- if(i < n)
- {
- while(!done && i < n)
- {
- j = 2 * i + 1;
- if(j >= n)
- break;
- if(j+1 < n)
- max_i = max(&h[j],&h[j+1]);
- else
- max_i = &h[j];
- if(h[i] < *max_i)
- {
- swap(&h[i], max_i);
- }
- else
- {
- done = TRUE;
- }
- i = j;
- }
- }
- }
- /*---------å †çš„æ?’å…¥æ“?作---------------------*/
- /*å°†å…ƒç´ xæ?’å…¥å †ä¸ */
- void insert(int h[], int *n, int x)
- {
- (*n)++;
- h[*n-1] = x;
- sift_up(h, *n-1);
- }
- /*----------å †çš„åˆ é™¤æ“?作------------------------*/
- /*å°†å †ä¸å…ƒç´ ä¸‹æ ‡ä¸ºiçš„å…ƒç´ åˆ é™¤ï¼Œä½†ä¸?ç ´å??å †çš„ç»“æ?„ */
- void delete(int h[],int *n, int i)
- {
- int temp = h[i];
- swap(&h[i], &h[*n-1]);
- (*n)--;
- /*最å??ä¸€ä¸ªå…ƒç´ ä¸?一定是最å°?的数,故è¦?判æ–是上移还是下移*/
- if(temp > h[i])
- {
- sift_down(h, *n, i);
- }
- else
- {
- sift_up(h, i);
- }
- }
- void heap_sort(int h[], int n)
- {
- while(n > 0)
- {
- delete(h, &n, 0);
- }
- }
- int main(void)
- {
- int a[M], n = 0, temp, i;
- char buf;
- while(buf != '/n')
- {
- scanf("%d%c", &temp, &buf);
- insert(a, &n, temp);
- }/* åˆ?å§‹åŒ–ä¸€ä¸ªå †*/
- for(i = 0; i < n; i++)
- printf("%d ", a[i]);
- printf("/n");
- heap_sort(a, n);
- /* delete(a, &n, 0);*/
- for(i = 0; i < n; i++)
- printf("%d ", a[i]);
- printf("/n");
- return 0;
- }
8.基數排序,時間複雜度居然是n。但是使用時一般需要知道最大的元素,這是這些算法裏唯一一個基於鏈表實現的,我感覺我這個基數排序做的不怎麼樣,效率不高,急待高手改善。
基數排序的原理:
每個數的每位數是0-9,所以我們可以申請10個鏈表,從個位開始,個位是0的放到L0,1放L1,每個數都放一遍以後作爲一趟,將這一趟的結果開始按十位再存放,依次類推,最後可以得到有序的數,假如所有的數都不超過4位,那麼循環需要的次數就是4*n,常數去掉,時間複雜度爲n,~~~~
- /*---基数����------*/
- #include<stdio.h>
- #include<malloc.h>
- #define BIT 4
- typedef struct List{
- int data;
- struct List * next;
- }L;
- /*------基数��-----------*/
- /*list 需���的链表头节点*/
- /*k:链表ä¸æ•°çš„ä½?æ•° */
- void radix_sort(L *list, int k)
- {
- L *link[10], *head = list, *lhead[10], *p;
- int i, pow = 1, bit, flag[10];
- for(i = 0; i < 10; i++)
- lhead[i] = link[i] = NULL;
- while(k--)
- {
- list = head;
- for(i = 0; i < 10; i++)
- flag[i] = 0;
- while( list != NULL )
- {
- bit = (list->data / pow) % 10;
- if(link[bit] != NULL)
- link[bit] = link[bit]->next = /
- (L*)malloc(sizeof(L));
- else
- link[bit] = (L*)malloc(sizeof(L));
- if(flag[bit] == 0)
- {
- lhead[bit] = link[bit];
- flag[bit] = 1;
- } /*第1次分�地�时记录首地�*/
- link[bit]->data = list->data;
- link[bit]->next = NULL;
- list = list->next;
- }
- for(i = 0; i < 10; i++)
- link[i] = lhead[i];/*10个链表指�头结点*/
- list = head;
- for(i = 0; i< 10; i++)
- {
- while(link[i] != NULL)
- {
- list->data = link[i]->data;
- link[i] = link[i]->next;
- list = list->next;
- }
- }
- for(i = 0; i < 10; i++)
- {
- while(lhead[i] != NULL)
- {
- p = lhead[i];
- lhead[i] = lhead[i] ->next;
- free(p);
- }
- }
- pow *= 10;
- }
- list = head;
- for(i = 0; i< 10; i++)
- {
- while(lhead[i] != NULL)
- {
- list->data = lhead[i]->data;
- lhead[i] = lhead[i]->next;
- list = list->next;
- }
- }
- }
- int main(void)
- {
- L *list, *p, *head;
- char buf;
- head = list = NULL;
- while(buf != '/n')
- {
- p =(L *)malloc(sizeof(L));
- if(list == NULL)
- {
- head = list = p;
- list->next = NULL;
- }
- else
- {
- list->next = p;
- list = list->next;
- list->next = NULL;
- }
- scanf("%d%c", &list->data, &buf);
- }
- radix_sort(head, BIT);
- while(head != NULL)
- {
- printf("%d ", head->data);
- head = head->next;
- }
- printf("/n");
- return 0;
- }