来亚嵌一个多月了,感觉进步挺大,但是其他同学进步更是飞速,压力很大,很怕他们马上超过啊,所以这些天一直惶恐的想着提升自己,左想右想,把数据结构拿出来复习来了,看到那些排序,动手实现了一遍,看到几个同学居然也写了几篇关于排序的笔记,拿我就先贴出来和大家一起分享,有些地方我感觉自己实现的效率不高,各位有想法的交流一下~~
我在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;
- }