數據排序算法

棧的實現:
順序存儲棧:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #define STACK_INIT_SIZE 100
4 #define STACKINCREMENT 10
5 typedef struct{
6 int *base;
7 int *top;
8 int stacksize;
9 }SqStack;
10 int InitStack(SqStack *s)
11 {
12 s->base=(int *)malloc(STACK_INIT_SIZE*sizeof(int));
13 if(!s->base)
14 exit(1);
15 s->top=s->base;
16 s->stacksize=STACK_INIT_SIZE;
17 return 0;

18 }

19 int GetTop(SqStack s)
20 {
21 if(s.top==s.base) return 1;
22 return *(s.top-1);
23 }
24 int Push(SqStack *s,int e)
25 {
26 if((s->top-s->base)>=s->stacksize){
27 s->base=(int*)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(int));
28 if(!s->base) exit(1);
29 s->top=s->base+s->stacksize;
30 s->stacksize+=STACKINCREMENT;
31 }
32 *s->top++=e;
33 return 0;
34 }
35 int Pop(SqStack* s)
36 {
37 if(s->top==s->base) exit(1);
38 return *(-- s->top);

39 }
40 int main()
41 {
42 SqStack s;
43 InitStack(&s);
44 int i=0;
45 while(i++<10)
46 {
47 Push(&s,i);
48 }
49 printf("top=%d\n",Pop(&s));
50 return 0;
51 }



隊列:一種先進先出(FIFO)的線性表,只允許在隊頭刪除,在隊尾插入。
鏈式結構的隊列實現代碼:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<stdlib.h>
4 typedef struct QNode{
5 int data;
6 struct QNode *next;
7 }QNode,*QueuePtr;
8 typedef struct {
9 QueuePtr front;
10 QueuePtr rear;
11 }LinkQueue;
12 int InitQueue(LinkQueue *Q)
13 {
14 Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));
15 if(!Q->front) exit(1);
16 Q->front->next=NULL;
17 return 0;
18 }
19 int DestoryQueue(LinkQueue *Q)
20 {
21 while(Q->front)
22 {
23 Q->rear=Q->front->next;
24 free(Q->front);
25 Q->front=Q->rear;
26 }
27 return 0;
28 }
29 int EnQueue(LinkQueue *Q,int e)
30 {
31 QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
32 if(!p) exit(1);
33 p->data=e;
34 p->next=NULL;
35 Q->rear->next=p;
36 Q->rear=p;
37 return 1;
38 }
39 int DeQueue(LinkQueue *Q)
40 {
41 QueuePtr p=Q->front->next;

42 if(Q->rear==Q->front) return 1;
43 Q->front->next=p->next;
44 if(p==Q->rear) Q->rear=Q->front;
45 free(p);
46 return 0;
47 }
48
49 int main()
50 {
51 int e;
52 LinkQueue Q;
53 printf("input value:");
54 scanf("%d",&e);
55 InitQueue(&Q);
56 EnQueue(&Q,e);
57 printf("%d %d\n",Q.front->next->data,Q.rear->data);
58 return 0;
59 }


插入排序--直接插入排序:
基本思想:
將一個記錄插入到已排序好的有序表中,從而得到一個新,記錄數增 1 的有序表。即:
先將序列的第
1 個記錄看成是一個有序的子序列,然後從第 2 個記錄逐個進行插入,
直至整個序列有序爲止。
要點:設立哨兵,作爲臨時存儲和判斷數組邊界之用。
1 #include<stdio.h>
2 void InserSort(int *a,int length)
3 {
4 int j=0,i=0,tmp=0

5 for(i=1;i<length;i++)
6 {
7 if(a[i]<a[i-1])

8 {
9 tmp=a[i];
10 j=i-1;
11 for(j;tmp<a[j]&&j>=0;j--)
12 {
13 a[j+1]=a[j];
14 }
15 a[j+1]=tmp;
16 }
17 }
18
19 }
20 int
main()
21 {
22 int a[14]={56,23,23,24,42,23,24,67,23,12,5,89,24,4};
23 int i=0;
24 InserSort(a,14);
25 while(i<14)
26 {
27 printf("%d\t",a[i]);
28 i++;
29 }
30 printf("\n");
31 return 0;
32 }


插入排序--折半插入排序
折半插入排序僅是減少關鍵字間的比較次數,而記錄的移動次數不變,最終是靠直接插入排
序實現
1 #include<stdio.h>
2 void InserSort(int *a,int length)
3 {
4 int j=0,i=0,tmp=0;
5 for(i=1;i<length;i++)
6 {
7 tmp=a[i];
8 int high=i-1,low=0,m=0;
9 while(low<=high)
10 {

11 m=(high+low)/2;
12 if(tmp<a[m])
13 {
14 high=m-1;
15 }
16 else{
17 low=m+1;
18 }
19 }
20 for(j=i-1;j>high;j--)
21 {
22 a[j+1]=a[j];
23 }
24 a[high+1]=tmp;
25
26
27
}
28
29 }
30 int
main()
31 {
32 int a[14]={56,23,23,24,42,23,24,67,23,12,5,89,24,4};
33 int i=0;
34 InserSort(a,14);
35 while(i<14)
36 {
37 printf("%d\t",a[i]);
38 i++;
39 }
40 printf("\n");
41 return 0;
42 }

插入排序--希爾排序:
希爾排序是 1959 年由 D.L.Shell 提出來的,相對直接排序有較大的改進。希爾排序又叫縮
小增量排序
基本思想:
先將整個待排序的記錄序列分割成爲若干子序列分別進行直接插入排序,待整個序列中的記
基本有序時,再對全體記錄進行依次直接插入排序。
操作方法:

選擇一個增量序列 t1t2tk,其中 ti>tjtk=1
按增量序列個數
k,對序列進行 k 趟排序;
每趟排序,根據對應的增量
ti,將待排序列分割成若干長度爲 m 的子序列,分別對各子表
進行直接插入排序。僅增量因子爲
1 時,整個序列作爲一個表來處理,表長度即爲整個序
列的長度。

實現代碼:
1 #include<stdio.h>
2 void ShellInsert(int *a,int length,int dk)
3 {
4 int i=0,j=0;
5 for(i=dk;i<length;i++)
6 {
7 if(a[i]<a[i-dk])
8 {
9 int tmp=a[i];

10 j=i-dk;
11 for(j;tmp<a[j]&&j>=0;j=j-dk)
12 {
13 a[j+dk]=a[j];
14 }
15 a[j+dk]=tmp;


16 }
17 }
18 }
19 void ShellSort(int *a,int length)
20 {
21 int dk=length/2;
22 while(dk>0)
23 {
24 ShellInsert(a,length,dk);
25 dk=dk/2;
26 }
27 }
28 int main()
29 {
30 int a[14]={56,23,23,24,42,23,24,67,23,12,5,89,24,4};
31 int i=0;
32 ShellSort(a,14);
33 while(i<14)
34 {
35 printf("%d\t",a[i]);
36 i++;
37 }
38 printf("\n");
39 return 0;
40 }


交換排序--冒泡排序:
1 #include<stdio.h>
2 void BubbleSort(int *a,int length)
3 {
4 int i=0,j=0;
5 for(i=0;i<length;i++)
6 {
7 for(j=1;j<length-i;j++)
8 {
9 if(a[j]<a[j-1])

10 {
11 int tmp=a[j];
12 a[j]=a[j-1];


13 a[j-1]=tmp;
14 }
15 }
16 }
17 }
18 int
main()
19 {
20 int a[14]={56,23,23,24,42,23,24,67,23,12,5,89,24,4};
21 int i=0;
22 BubbleSort(a,14);
23 while(i<14)
24 {
25 printf("%d\t",a[i]);
26 i++;
27 }
28 printf("\n");
29 return 0;
30 }

冒泡排序算法的改進:
對冒泡排序常見的改進方法是加入一標誌性變量
exchange,用於標誌某一趟排序過程中是否
有數據交換,如果進行某一趟排序時並沒有進行數據交換,則說明數據已經按要求排列好,
可立即結束排序,避免不必要的比較過程。本文再提供以下兩種改進算法:
1.設置一標誌性變量 pos,用於記錄每趟排序中最後一次進行交換的位置。由於 pos 位置之
後的記錄均已交換到位
,故在進行下一趟排序時只要掃描到 pos 位置即可。
改進後算法如下
:
void Bubble_1 ( int r[], int n) {
int i= n -1; //
初始時,最後位置保持不變
while ( i> 0) {
int pos= 0; //
每趟開始時,無記錄交換
for (int j= 0; j< i; j++)
if (r[j]> r[j+1]) {
pos= j; //
記錄交換的位置
int tmp = r[j]; r[j]=r[j+1];r[j+1]=tmp;
}
i= pos; //
爲下一趟排序作準備
}
} 2
.傳統冒泡排序中每一趟排序操作只能找到一個最大值或最小值,我們考慮利用在每趟排序
中進行正向和反向兩遍冒泡的方法一次可以得到兩個最終值
(最大者和最小者) , 從而使排
序趟數幾乎減少了一半。
void Bubble_2 ( int r[], int n){
int low = 0;

int high= n -1; //設置變量的初始值
int tmp,j;
while (low < high) {
for (j= low; j< high; ++j) //
正向冒泡,找到最大者
if (r[j]> r[j+1]) {
tmp = r[j]; r[j]=r[j+1];r[j+1]=tmp;
}
--high; //修改 high , 前移一位
for ( j=high; j>low; --j) //反向冒泡,找到最小者
if (r[j]<r[j-1]) {
tmp = r[j]; r[j]=r[j-1];r[j-1]=tmp;
}

++low; //修改 low ,後移一位
}
}

交換排序--快速排序
基本思想:
1)選擇一個基準元素,通常選擇第一個元素或者最後一個元素,
2
)通過一趟排序講待排序的記錄分割成獨立的兩部分,其中一部分記錄的元素值均比基準
元素值小。另一部分記錄的 元素值比基準值大。
3)此時基準元素在其排好序後的正確位置
4)然後分別對這兩部分記錄用同樣的方法繼續進行排序,直到整個序列有序。

1 #include<stdio.h>
2 int Partition(int *a,int low,int high)
3 {
4 int tmp=a[low];
5 while(low<high)
6 {
7 while(low<high&&tmp<=a[high])
8 high--;
9 a[low]=a[high];
10 while(low<high&&tmp>=a[low])
11 low++;
12 a[high]=a[low];


13 }
14 a[low]=tmp;
15 return low;
16 }
17 void QSort(int *a,int low,int high)
18 {
19 if(low<high)
20 {
21 int tmp=Partition(a,low,high);
22 QSort(a,low,tmp-1);
23 QSort(a,tmp+1,high);
24 }
25 }
26 void QuickSort(int *a,int length)
27 {
28 QSort(a,0,length-1);
29 }
30 int main()
31 {
32 int a[14]={56,23,23,24,42,23,24,67,23,12,5,89,24,4};
33 int i=0;
34 QuickSort(a,14);
35 while(i<14)
36 {
37 printf("%d\t",a[i]);
38 i++;
39 }
40 printf("\n");
41 return 0;
42 }
選擇排序--簡單選擇排序
基本思想:
在要排序的一組數中,選出最小(或者最大)的一個數與第
1 個位置的數交換;然後在剩下
的數當中再找最小(或者最大)的與第
2 個位置的數交換,依次類推,直到第 n-1 個元素(倒
數第二個數)和第
n 個元素(最後一個數)比較爲止。
1 #include<stdio.h>
2 int SelectMinKey(int *a,int length,int i)
3 {

4 int j=i;
5 for(i=i+1;i<length;i++)
6 {
7 if(a[i]<a[j])
8 {
9 j=i;

10 }
11 }
12 return j;
13
14 }
15 void SelectSort(int *a,int length)
16 {
17 int i;
18 for(i=0;i<length;i++)
19 {
20 int j=SelectMinKey(a,length,i);
21 int tmp=a[i];
22 a[i]=a[j];
23 a[j]=tmp;
24 }
25 }
26 int main()
27 {
28 int a[14]={56,23,23,24,42,23,24,67,23,12,5,89,24,4};
29 int i=0;
30 SelectSort(a,14);
31 while(i<14)
32 {
33 printf("%d\t",a[i]);
34 i++;
35 }
36 printf("\n");
37 return 0;
38 }





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章