1 #include"stdio.h" 2 #include"stdlib.h" 3 #include"string.h" 4 #include"time.h" 5 6 #define LIST_INIT_SIZE 50000 7 int bj1,yd1,bj2,yd2,bj3,yd3,bj4,yd4,bj5,yd5,bj6,yd6,n;//yd,bj为记录关键字比较和移动的次数 8 9 struct ElemType 10 { 11 int key; 12 }; 13 14 struct SqList//线性表 15 { 16 ElemType *elem; 17 int length; 18 }; 19 20 21 void Createlist(SqList &L)//初始化顺序表的,确定输入数据个数n 22 { 23 int flags = 1; 24 while(flags) 25 { 26 printf("请输入数据个数:"); 27 scanf("%d",&n); 28 if(n>50000) 29 { 30 printf("超出范围重新输入!!! "); 31 }else flags = 0;//跳出循环 32 } 33 L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));//分配内存 34 if(!L.elem)exit(0); 35 } 36 37 void Random(SqList &L)//随机数产生程序 38 { 39 L.length=0;//数据初始为0 40 srand(time(0));//使输入相同个数时每次产生的随机数不同 41 42 for(int i=1;i<n+1;i++) 43 { 44 L.elem[i].key=rand();//产生随机数 45 while(L.elem[i].key>50000)L.elem[i].key=rand();//保证数据早50000以内 46 L.length++;//数据个数+1 47 } 48 } 49 50 void Memory(SqList &M,SqList &L)//记录L,使每个排序算法都用一组相同的随机数 51 { 52 int i = 1 ; 53 M.length=0;//顺序表M初始长度为0 54 while(i<=L.length)//顺序表L中的元素赋给顺序表M中 55 { 56 M.elem[i].key=L.elem[i].key; 57 M.length++; 58 i++; 59 } 60 } 61 62 void BubbleSort(SqList &L)//冒泡排序 63 { 64 int i,j; 65 for(i=1;i<L.length;i++) 66 { 67 for(j=1;j<L.length-i+1;j++) 68 { 69 bj1++;//比较次数+1 70 if(L.elem[j].key>L.elem[j+1].key)//关键字交换 71 { 72 L.elem[0].key=L.elem[j].key; 73 L.elem[j].key=L.elem[j+1].key; 74 L.elem[j+1].key=L.elem[0].key; 75 yd1+=3;//关键字交换次数+3 76 } 77 } 78 } 79 } 80 81 void InsertSort(SqList &L)//直接插入排序 82 { 83 int i,j; 84 for(i=2;i<=L.length;i++) 85 { 86 if(L.elem[i].key<L.elem[i-1].key) 87 { 88 L.elem[0].key=L.elem[i].key; 89 yd2++;//比较次数+1 90 j=i-1; 91 bj2++;//交换次数+1 92 while(L.elem[0].key<L.elem[j].key) 93 { 94 L.elem[j+1].key=L.elem[j].key; 95 j--; 96 yd2++;//比较次数+1 97 bj2++;//交换次数+1 98 } 99 L.elem[j+1].key=L.elem[0].key; 100 yd2++;//比较次数+1 101 } 102 } 103 } 104 105 106 107 void SelectSort(SqList &L)//选择排序 108 { 109 int i,j,k; 110 for(i=1;i<L.length;i++) 111 { 112 k=i; 113 for(j=i+1;j<=L.length;j++) 114 { 115 bj3++;//比较次数+1 116 if(L.elem[j].key<L.elem[k].key)k=j; 117 } 118 if(i!=k) 119 { 120 L.elem[0].key=L.elem[i].key; 121 L.elem[i].key=L.elem[k].key; 122 L.elem[k].key=L.elem[0].key; 123 yd3+=3;//交换次数+3 124 } 125 } 126 } 127 128 129 int Partition(SqList &L,int low,int high)//快速排序 130 { 131 int pivotkey; 132 L.elem[0]=L.elem[low]; 133 yd4++;//交换次数+1 134 pivotkey=L.elem[low].key; 135 while (low<high) 136 { 137 yd4++;//交换次数+1 138 while(low<high&&L.elem[high].key>=pivotkey) 139 high--; 140 L.elem[low]=L.elem[high]; 141 bj4++;//比较次数+1 142 yd4++;//交换次数+1 143 while (low<high&&L.elem[low].key<=pivotkey) 144 low++; 145 L.elem[high]=L.elem[low]; 146 bj4++;//比较次数+1 147 yd4++;//交换次数+1 148 } 149 L.elem[low]=L.elem[0]; 150 yd4++;//交换次数+1 151 return low; 152 } 153 void QSort(SqList &L,int low,int high)//对顺序表的子序列作快速排序 154 { 155 int pivotloc; 156 if(low<high) 157 { 158 pivotloc=Partition(L,low,high); 159 QSort(L,low,pivotloc-1); 160 QSort(L,pivotloc+1,high); 161 } 162 } 163 164 void QuickSort(SqList &L)//对顺序表L作快速排序 165 { 166 QSort(L,1,L.length); 167 } 168 169 170 void ShellSort(SqList &L)//希尔排序 171 { 172 int dh,i,j; 173 dh=L.length/2; 174 while(dh>=1){ 175 for( i=dh;i<=L.length;i++){ 176 L.elem[0].key=L.elem[i].key; 177 yd5+=1;//交换次数+1 178 j=i-dh; 179 while(j>=0&&L.elem[j].key>L.elem[0].key){ 180 L.elem[j+dh].key = L.elem[j].key; 181 bj5+=1;//比较次数+1 182 yd5+=1;//交换次数+1 183 j-=dh; 184 } 185 L.elem[j+dh].key = L.elem[0].key; 186 yd5+=1;//交换次数+1 187 } 188 dh/=2; 189 } 190 } 191 192 /* 193 *调整数组A中以K为根的子序列为堆,其中最大的元素下标为m 194 *假设以2k,2k+1为根的左右子树均是堆 195 */ 196 void HeapAdjust(SqList &L,int k,int m) 197 { 198 int i,j,x; 199 int finished = 0; 200 201 x =L.elem[k].key;//临时保存当前根植 202 yd6+=1;//交换次数+1 203 i = k;//指示空位 204 j = 2*i;//j先指向其左孩子结点 205 while(j<=m &&!finished)//确定i结点不是叶子节点且搜索未结束 206 { 207 if((j<m)&&(L.elem[j].key<L.elem[j+1].key)) 208 { 209 j++;//让j指向左右孩子中的最大者 210 bj6++;//比较次数+1 211 } 212 if(x>=L.elem[j].key)finished = 1;//若原根最大,置搜索和帅选结束标志 213 else{ 214 L.elem[i].key = L.elem[j].key;//大的孩子结点值上移 215 yd6+=1;//交换次数+1 216 i = j;//继续往下帅选:i指示新的空位,j相应改变 217 j*=2; 218 } 219 } 220 L.elem[i].key = x;//将原根值填充到所搜索到的当前的空位置中 221 yd6+=1;//交换次数+1 222 } 223 224 225 void HeapSort(SqList &L) 226 { 227 int i; 228 229 for(i=L.length/2;i>=1;i--) 230 { 231 HeapAdjust(L,i,n);//建初始堆 232 } 233 for(i=L.length;i>=2;i--)//控制排序过程 234 { 235 236 L.elem[0] = L.elem[1]; 237 L.elem[1] = L.elem[i]; 238 L.elem[i] = L.elem[0]; 239 yd6+=3;//交换次数+3 240 HeapAdjust(L,1,i-1);//调整子序列Array[1]~Array[i-1]为堆 241 } 242 243 } 244 245 void print(SqList &L)//输出顺序表重元素 246 { 247 int i; 248 for(i=1;i<=L.length;i++) 249 { 250 printf("%d ",L.elem[i]); 251 if(i%5==0)printf(" "); 252 } 253 printf(" "); 254 } 255 256 int main() 257 { 258 259 int a,flags = 1; 260 while(flags) 261 { 262 printf(" -------------内部排序------------------ "); 263 printf("|-------------欢迎使用------------------| "); 264 printf("|-----------(1)运行程序-----------------| "); 265 printf("|-----------(0)退出系统 ----------------| "); 266 printf("请选择:"); 267 scanf("%d",&a); 268 while(a!=0&&a!=1) 269 { 270 printf("输入有误,请输入0|1:"); 271 scanf("%d",&a); 272 } 273 switch(a) 274 { 275 case 0: 276 printf("谢谢使用! "); 277 flags = 0; 278 break; 279 case 1: 280 system("cls");//清屏 281 SqList L,M; 282 M.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType)); 283 if(!M.elem)exit(0); 284 bj1=0,yd1=0,bj2=0,yd2=0,bj3=0,yd3=0,bj4=0,yd4=0,bj5=0,yd5=0,bj6=0,yd6=0; 285 Createlist(L); 286 Random(L);//产生数据 287 288 Memory(M,L); 289 BubbleSort(M);//冒泡排序 290 291 Memory(M,L); 292 InsertSort(M);//插入排序 293 294 Memory(M,L); 295 SelectSort(M);//选择排序 296 297 Memory(M,L); 298 QuickSort(M);//快速排序 299 300 Memory(M,L); 301 ShellSort(M);//希尔排序 302 303 Memory(M,L); 304 HeapSort(M);//堆排序 305 306 printf(" 比较次数 移动次数 "); 307 printf("冒泡排序:%d %d ",bj1,yd1); 308 printf("直接插入:%d %d ",bj2,yd2); 309 printf("简单选择:%d %d ",bj3,yd3); 310 printf("快速排序:%d %d ",bj4,yd4); 311 printf("希尔排序:%d %d ",bj5,yd5); 312 printf("堆排序: %d %d ",bj6,yd6); 313 break; 314 } 315 } 316 return 0; 317 }