常见的排序算法
3 #include <stdio.h> 4 #include <time.h> 5 void Swap(int &a, int &b) 6 { 7 int t = a; 8 a = b; 9 b = t; 10 } 11 12 13 //选择排序:交换移动次数少,O(n2) 14 void SelectSort(int a[],int n)//或者int *a 15 { 16 printf("选择排序\n"); 17 for (size_t i = 0; i < n - 1; i++) 18 { 19 int minInt = a[i]; 20 int index = i; 21 for (size_t j = i + 1; j < n; j++) //j从i+1开始 22 { 23 if (a[j] < minInt) 24 { 25 minInt = a[j]; 26 index = j; 27 } 28 } 29 Swap(a[i], a[index]); // //这里一开始错写成了Swap(a[i], minInt);这就不是数组里面的交换了.所以要用个index. 30 for (int k = 0; k < n; k++) 31 { 32 printf("%d ", a[k]); 33 } 34 printf("\n"); 35 } 36 } 37 38 //插入排序: 39 void InsertSort(int a[], int n) //按照宝典编的.(有交换的机制) 40 { 41 printf("插入排序\n"); 42 int i, j; 43 for (i = 1; i < n; i++) 44 { 45 int temp = a[i]; 46 47 //(1)写法1 48 /* 49 // for (j = i-1; j >= 0; j--) //因为temp的前一个不一定是它应该去的位置,所以要和前面的多个进行比较(所以j >= 0; j--) 50 // { 51 // if (temp < a[j]) 52 // { 53 // a[j + 1] = a[j]; 54 // } 55 // else 56 // { 57 // break; //当temp不小于紧贴的前一个a[j]时,就代表它不用调整位置,因为前面的顺序都是调整好的. 58 // } //这里的break是必须的,否则j会一直自减. 59 // } 60 // a[j + 1] = temp; //因为for循环j--.即使没有执行循环体,但是j = i-1是一定执行过了.所以无论执行循环体,都能妥善处理. 61 */ 62 63 64 //(2)写法2(较简便) 65 for (j = i - 1; j >= 0 && temp < a[j]; j--) 66 { 67 a[j + 1] = a[j]; //大于temp的要往后挪,留出插入的空间. 68 } 69 a[j + 1] = temp; ////因为for循环j--.即使没有执行循环体,但是j = i-1是一定执行过了.所以无论执行循环体,都能妥善处理.可以拿排好的顺序验证. 70 } 71 } 72 73 //冒泡排序 74 void BubbleSort(int a[], int n) 75 { 76 printf("冒泡排序\n"); 77 int i, j; 78 79 /* 80 // (1)下沉形式 81 for (i = 0; i < n-1; i++) //i控制需要沉下去几个,沉下去n-1个就能确定最后的顺序. 82 { 83 for (j = 0; j < n - 1 - i; j++) //j代表矩阵内需要比较几次 84 { 85 if (a[j] > a[j+1]) 86 { 87 Swap(a[j], a[j + 1]); 88 } 89 } 90 } 91 */ 92 93 //(2)冒泡形式 94 for (i = 0; i < n - 1; i++) 95 { 96 for (j = n - 1; j > i ; j--) 97 { 98 if (a[j] < a[j - 1]) 99 { 100 Swap(a[j], a[j - 1]); 101 } 102 } 103 } 104 } 105 106 //希尔排序 107 void ShellSort(int a[], int n) 108 { 109 printf("希尔排序\n"); 110 int i, j, h; //h:增量 111 int temp; 112 for (h = n / 2; h > 0; h /= 2) 113 { 114 for (i = h; i < n; i += h) 115 { 116 temp = a[i]; 117 for (j = i - h; j >= 0; j -= h) //j包括0. j -= h:一次跳h,找有没有比temp大的,往后挪,给temp让位. 118 { 119 if (temp < a[j]) 120 { 121 a[j + h] = a[j]; 122 } 123 else 124 break; //也可以写成插入排序的(2) 125 } 126 a[j + h] = temp; 127 } 128 } 129 } 130 131 132 //堆排序(采用Weiss的代码) 133 #define LeftChild(i) (2 * (i) + 1) 134 void PercDown(int a[], int i, int n) 135 { 136 int child; 137 int temp; 138 for (temp = a[i]; LeftChild(i) < n; i = child) 139 { 140 child = LeftChild(i); 141 if (child != n - 1 && a[child + 1] > a[child]) 142 { 143 child++; 144 } 145 if (temp < a[child]) 146 { 147 a[i] = a[child]; 148 } 149 else 150 { 151 break; 152 } 153 } 154 a[i] = temp; //此处的i是child赋值过来的 155 } 156 157 void HeapSort(int a[], int n) 158 { 159 printf("堆排序\n"); 160 int i; 161 for ( i = n / 2; i >= 0; i--) //对父结点有(i < = n/2) 这里结点序号从0开始和数组下标一致. 162 { 163 PercDown(a, i, n); // 创建大顶堆,自下而上,自右向左(思想可以参见<大话数据结构的第400页>) 164 } 165 for (i = n-1; i > 0; i--)//i > 0因为没有必要和自身交换 166 { 167 Swap(a[0], a[i]); 168 PercDown(a, 0, i); //以结点0创建大顶堆(包括所有有效的结点),因为只是把1和最后的记录交换,而其他结点都不变.其实上面的PercDown(a, i, n)是先下面创建,然后上面创建,大顶堆的元素数量越来越多. 169 } 170 } 171 172 173 //归并排序 174 175 176 int main() 177 { 178 int a[] = { 5,4,9,8,7,6,0,1,3,2 }; 179 int len = sizeof(a) / sizeof(a[0]);// 也可以写作:int len = sizeof(a) / sizeof(int);182 //SelectSort(a, len); 183 //InsertSort(a, len); 184 //BubbleSort(a, len); 185 //ShellSort(a, len); 186 HeapSort(a, len); 187 clockEnd = clock(); 188 for (int i = 0; i < len; i++) 189 { 190 printf("%d\n", a[i]); 191 } 193 return 0; 194 }
新战场:https://blog.csdn.net/Stephen___Qin