八种排序算法

研究生第一学期开了算法设计课程。马上排序算法章节要告一段落,现在将之前写完的八中排序算法列出来。

其中,归并排序、选择排序、快速排序、冒泡排序、插入排序、堆排序、希尔排序这七中使用java写的,基数排序使用C++写的

  1 package main;
2
3 import java.util.Random;
4
5 /*
6 * 随机生成100个1-500之间的整数,然后用8种方法从小到大进行排序*/
7
8 public class Sort {
9 public static final int DATA_NUMBER = 20;
10 public static final int LOOP_TIMES = 1;
11 public static int data[];
12
13 public Sort() {
14 data = new int[DATA_NUMBER];
15 for (int i = 0; i < DATA_NUMBER; i++) {
16 data[i] = 0;
17 }
18 }
19
20 public void generateData(int max) {
21 Random random = new Random();
22 for (int i = 0; i < DATA_NUMBER; i++) {
23 data[i] = random.nextInt(max) + 1;
24 }
25 }
26
27 /** 插入排序,每次将一个记录插入到有序记录中*/
28 public void insertSort() {
29 int tempData = data[0];
30 if (data[0] > data[1]) {
31 data[0] = data[1];
32 data[1] = tempData;
33 }
34 for (int i = 2; i < data.length; i++) {
35 if (data[i] < data[i - 1]) {
36 tempData = data[i];
37 data[i] = data[i - 1];
38 int j = 0;
39 for (j = i - 2; j >= 0 && data[j] > tempData; j--) {
40 data[j + 1] = data[j];
41 }
42 data[j + 1] = tempData;
43 }
44 }
45 }
46
47 /** 冒泡排序*/
48 public void bubbleSort() {
49 int tempData = data[0];
50 for (int i = 1; i < data.length; i++) {
51 for (int j = 0; j < data.length - i; j++) {
52 if (data[j] > data[j + 1]) {
53 tempData = data[j];
54 data[j] = data[j + 1];
55 data[j + 1] = tempData;
56 }
57 }
58 }
59 }
60
61 /** 快速排序 递归算法
62 * @param dataArray[] 要排序的数组 */
63 public void quickSort(int dataArray[], int low, int high) {
64 if (low < high) {
65 int pivotloc = quickPartion(dataArray, low, high);
66 quickSort(dataArray, low, pivotloc - 1);
67 quickSort(dataArray, pivotloc + 1, high);
68 }
69 }
70 /** 快速排序的一趟排序*/
71 public int quickPartion(int dataPartion[], int low, int high) {
72 int pivotkey = dataPartion[low];
73 while (low < high) {
74 while (low < high && dataPartion[high] >= pivotkey) {
75 high--;
76 }
77 dataPartion[low] = dataPartion[high];
78 while (low < high && dataPartion[low] <= pivotkey) {
79 low++;
80 }
81 dataPartion[high] = dataPartion[low];
82 }
83 dataPartion[low] = pivotkey;
84 return low;
85 }
86
87 /** 选择排序*/
88 public void selectSort() {
89 int index = 0;
90 int tempData = data[0];
91 for (int i = 0; i < data.length; i++) {
92 index = i;
93 tempData = data[i];
94 for (int j = i; j < data.length; j++) {
95 if (data[j] < data[index]) {
96 index = j;
97 }
98 }
99 data[i] = data[index];
100 data[index] = tempData;
101 }
102 }
103
104 /** 堆排序筛选
105 * @param s:顶位置 m:最后一个位置,将从s到m的元素建成大顶堆
106 * 但这个s,m是相对第一个元素下标为1来说的
107 * */
108 public void heapAjust(int dataArray[], int s, int m) {
109 int tempData = dataArray[s - 1];
110 for (int i = s * 2; i <= m; i *= 2) {
111 if (i < m && dataArray[i - 1] > dataArray[i]) {
112 i++;
113 }
114 if (dataArray[s - 1] < dataArray[i - 1]) {
115 break;
116 }
117 dataArray[s - 1] = dataArray[i - 1];
118 s = i;
119 dataArray[s - 1] = tempData;
120 }
121 }
122 public void HeapSort() {
123 int temp = 0;
124 //先把整个数据建成大顶堆
125 for (int i = data.length / 2; i > 0; i--) {
126 heapAjust(data, i, data.length);
127 }
128 for (int i = data.length; i > 1; i--) {
129 temp = data[0];
130 data[0] = data[i - 1];
131 data[i - 1] = temp;
132 heapAjust(data, 1, i - 1);
133 }
134 }
135
136 /**自然合并排序,如{4,8,3,7,1,5,6,2},先找出自然排好的序列{4,8},{3,7},{1,5,6},{2},再两两合并*/
137
138 /**2-路归并排序非递归算法*/
139 public void mergeSort(int dataArray[], int n) {
140 int tempArray[] = new int[n];
141 int s = 1;
142 while (s < n) {
143 mergePass(dataArray, tempArray, s, n);
144 s += s;
145 //mergePass函数里有条件限制,所以此处不必担心 s>n
146 mergePass(tempArray, dataArray, s, n);
147 s += s;
148 }
149 }
150 public void mergePass(int x[], int y[], int s, int n) {
151 //合并大小为s的相邻数组
152 int i = 0;
153 while (i <= n - s * 2) {
154 //合并大小为s的相邻2段子数组
155 merge(x, y, i, i + s - 1, i + s * 2 - 1);
156 i = i + s * 2;
157 }
158 //剩下的元素个数少于 2s
159 if (i + s < n) {
160 merge(x, y, i, i + s - 1, n - 1);
161 }else {
162 for (int j = i; j < n; j++) {
163 y[j] = x[j];
164 }
165 }
166 }
167 public void merge(int c[], int d[], int h, int m, int r) {
168 //将 c[h..m] 和 c[h+1..r] 合并到 d[h..r]
169 int i = h;
170 int j = m + 1;
171 int k = h;
172 while ((i <= m) && (j <= r)) {
173 if (c[i] <= c[j]) {
174 d[k++] = c[i++];
175 }else {
176 d[k++] = c[j++];
177 }
178 }
179 if (i > m) {
180 for (int q = j; q <= r; q++) {
181 d[k++] = c[q];
182 }
183 }else {
184 for (int q = i; q <= m; q++) {
185 d[k++] = c[q];
186 }
187 }
188 }
189
190 /** 希尔排序,增量排序,属于插入的改善版,
191 * 按增量dlta[0..t-1]对元素进行希尔排序*/
192 public void shellSort(int dataArray[], int dlta[], int t) {
193 //按增量dlta[0..t-1]对元素进行希尔排序
194 for (int k = 0; k < t; k++) {
195 shellInsert(dataArray, dlta[k]);
196 }
197 }
198 public void shellInsert(int a[], int dk) {
199 int tempData = a[0];
200 int j = 0;
201 for (int i = dk; i < a.length; i++) {
202 if(a[i] < a[i - dk]) {
203 tempData = a[i];
204 for (j = i - dk; j >= 0 && a[j] > tempData; j -= dk) {
205 a[j + dk] = a[j];
206 }
207 a[j + dk] = tempData;
208 }
209 }
210 }
211
212 /**打印数据*/
213 public void dispaly() {
214 for (int i = 0; i < data.length; i++) {
215 if (i % 10 == 0) {
216 System.out.println();
217 }
218 System.out.print(data[i] + "\t");
219 }
220 System.out.println();
221 }
222
223 public static void main(String args[]) {
224 Sort sort = new Sort();
225
226 long beginTime = 0;
227 long endTime = 0;
228
229 beginTime = System.currentTimeMillis();
230 for (int i = 0; i < LOOP_TIMES; i++) {
231 sort.generateData(10000);
232 }
233 endTime = System.currentTimeMillis();
234
235 int dlta[] = new int[] {5,3,1};
236 beginTime = System.currentTimeMillis();
237 for (int i = 0; i < LOOP_TIMES; i++) {
238 sort.generateData(10000);
239 sort.HeapSort();
240 }
241 endTime = System.currentTimeMillis();
242 }
243 }

下面是基数排序

  1 #include <iostream>
2 #include <time.h>
3 #include <stdio.h>
4
5 using namespace std;
6
7 #define MAX_NUM_OF_KEY 8 /*关键字项数的最大值,暂定为8*/
8 #define RADIX 10 /*关键字基数[0..9],这是十进制整数的基数*/
9 #define MAXNUM 100000//排序数据个数
10
11 typedef int DataType;
12
13 typedef struct {
14 int data; //数据,如571
15 DataType keys[MAX_NUM_OF_KEY]; // 每个数据的所有关键字,如571的5,7,1
16 int next;
17 }SLCell; // 静态链表的结点类型
18
19 typedef struct {
20 SLCell *R; //静态链表的可用空间 R[0]为头结点
21 int recnum; //静态链表的当前长度
22 int keynum; // 当前数据的关键字个数
23 }SLlist,*SLList;// 静态链表类型
24
25 typedef int ArrType[RADIX];
26
27
28 void generateList(SLList &List, int boundary);
29 void displayList(SLCell *R);
30 void distribute(SLCell *R, int i, ArrType front, ArrType end);
31 void collect(SLCell *R, int i, ArrType front, ArrType end);
32
33
34
35 void generateList(SLList &List, int boundary)
36 {
37 srand(time(NULL));//每次随机种子不同
38 int key = 0;
39 for (int i = 1; i <= MAXNUM; i++)
40 {
41 List->R[i].data = rand() % boundary + 1;
42 key = List->R[i].data;
43 for(int j = 1; j <= List->keynum; j++)
44 {
45 List->R[i].keys[j] = key % 10;
46 key = key / 10;
47 }
48 List->R[i - 1].next = i;
49 }
50 List->recnum = MAXNUM;
51 List->R[List->recnum].next = 0;
52 }//generateList
53
54 void displayList(SLCell *R)
55 {
56 int p = R[0].next;
57 int numcount = 0;
58 while(p)
59 {
60 numcount++;
61 // cout<<R[p].data<<"\t";
62 printf("%d\t",R[p].data);
63 if (numcount % 10 == 0)
64 {
65 // cout<<endl;
66 printf("\n");
67 }
68 p = R[p].next;
69 }
70 // cout<<endl;
71 printf("\n");
72 }//displayList
73
74
75 void distribute(SLCell *R, int i, ArrType front, ArrType end)
76 {
77 //静态链表L的R域中记录已按(keys[0]..keys[i-1]有序)。
78 //本算法按第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同
79 //front[0..RADIX-1]和end[0..RADIX-1]分别指向各子表中第一个和最后一个记录
80 int j = 0;
81 for (; j < RADIX; j++)
82 {
83 front[j] = 0;
84 end[j] = 0;
85 }
86 for (int p = R[0].next; p; p = R[p].next)
87 {
88 j = R[p].keys[i];
89 if (!front[j])
90 {
91 front[j] = p;
92 }
93 else
94 {
95 R[end[j]].next = p;//如果front[j]已经连接过了,就把这个元素链接到上一个元素后面
96 }
97 end[j] = p;
98 }
99 }//distribute
100
101 void collect(SLCell *R, int i, ArrType front, ArrType end)
102 {
103 //本算法按keys[i]自小到大地将front[0..RADIX-1]所指各子表依次链接成为一个链表
104 int j = 0;
105 while(!front[j])
106 {
107 j++;
108 }
109 R[0].next = front[j];
110 int k = end[j];
111 while(j < RADIX)
112 {
113 for (++j; j < RADIX; j++)
114 {
115 if (front[j])
116 {
117 R[k].next = front[j];
118 k = end[j];
119 }
120 }
121 }
122 R[k].next = 0;
123 }//collect
124
125
126 int main()
127 {
128 SLList SLL;
129 SLL = (SLlist *)malloc(MAXNUM * sizeof(SLlist));
130 SLL->R = (SLCell *)malloc(MAXNUM * sizeof(SLCell));
131 SLL->recnum = 0;
132 SLL->keynum = 4;
133 ArrType front, end;
134
135 generateList(SLL, 9999);
136
137 for (int i = 1; i <= SLL->keynum; i++)
138 {
139 distribute(SLL->R, i, front, end);
140 collect(SLL->R, i, front, end);
141 }
142
143 displayList(SLL->R);
144
145 return 0;
146 }

实验结果表明,在数据量比较大的时候,归并排序还是比较理想的,而冒泡、希尔、插入、快速、选择的时间简直不敢恭维

 

 

    原文作者:lihui_yy
    原文地址: https://www.cnblogs.com/lihuiyy/articles/2193571.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞