[排序]六种基本排序算法 原创

页内跳转链接

冒泡排序
插入排序
归并排序
快速排序
选择排序
堆排序

冒泡排序

思路

有n个数,乱序。
第一次,从左往右相邻之间的数字逐格比较大小,如果a[i]<a[i+1],则交换a[i]和a[i+1]的数值,此时队尾数值必定为数列最大值,因此在下一次比对中我们可以不考虑队尾数值。
第二次,从左往右相邻之间的数字逐格比较大小,如果a[i]<a[i+1],则交换a[i]和a[i+1]的数值,此时队尾-1数值必定为数列第二最大值,因此在下一次比对中我们可以不考虑该数值。

直到所有数值都被逆序清除完毕,表明找到了第一最大值,第二最大值,大三最大值…完成。

时间复杂度

o(n^2)

核心代码

方式一
void BubbleSort(int a[],int end)//a[]数组,end队尾(长度)
{
    if(end==0)return;//直到所有数值都被逆序清除完毕,表明找到了第一最大值,第二最大值,大三最大值...完成。
    
    for(int i=0;i<end;i++)
        if(a[i]>a[i+1])swap(a[i],a[i+1]);//从左往右相邻之间的数字逐格比较大小,如果a[i]<a[i+1],则交换a[i]和a[i+1]的数值
    
    BubbleSort(a,end-1);//在下一次比对中我们可以不考虑队尾数值,清除队尾
}
方式三
void BubbleSort(int a[],int n)
{
    for(int i=0;i<n;i++)
        for(int j=0;j<n-i;j++)//根据思路我们比对一次循环之后第n个必为最大值,因此我们只需比对n次循环即可完成。
            if(a[j]>a[j+1])
                swap(&a[j],&a[j+1]);
}
方式二
void BubbleSort(int a[],int n)
{
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)//与方式二并无差别,只是更换为了ij比较,实际也是a[i]比a[i+1],执行n次循环
            if(a[i]>a[j])
                swap(&a[i],&a[j]);
}

方便拿的完整代码

#include<iostream>

using namespace std;

void swap(int *a,int *b){int t=*a;*a=*b;*b=t;}

void BubbleSort(int a[],int end)
{
    if(end==0)return;
    
    for(int i=0;i<end;i++)
        if(a[i]>a[i+1])swap(a[i],a[i+1]);
    
    BubbleSort(a,end-1);
}

int main()
{
    int a[1000];
    int n;
    
	cin >> n;

	for (int i = 0; i < n; i++)cin >> a[i];


	BubbleSort(a,n-1);
	for (int i = 0; i < n; i++)cout<< a[i]<<" ";

	return 0;
}

测试

输入
500 
    218 97 78 13 7 259 14 90 86 460 72 134 458 2 245 490 126 33 355 171 166 433 16 74 436 167 5 296 350 148 146 279 230 467
    182 31 315 77 151 442 253 224 156 325 379 183 30 47 129 124 441 497 314 193 390 463 80 362 461 280 383 185 415 179 174
    234 214 1 199 244 249 398 473 136 394 349 369 63 83 356 440 363 219 484 330 425 465 176 125 269 289 312 162 451 480
    100 342 418 243 177 149 10 422 42 478 338 141 367 346 271 221 283 114 443 216 145 235 220 380 204 147 24 307 285 403
    175 256 477 305 165 416 420 255 227 211 427 370 223 195 9 69 264 35 17 38 384 56 329 300 246 178 203 39 471 55 46 
    103 263 455 231 487 445 188 268 482 58 294 257 449 391 500 392 479 261 492 96 267 88 116 494 206 43 262 71 180 120 
    142 351 29 340 130 310 57 431 226 276 6 437 187 447 270 345 66 374 210 133 348 215 242 419 469 435 37 331 84 59 28 
    117 430 426 488 222 399 452 448 273 158 150 170 40 110 217 229 232 76 303 382 241 275 108 366 409 499 26 311 302 
    486 91 347 334 94 358 491 196 107 360 401 292 191 4 297 475 378 298 236 389 22 359 233 163 212 92 53 288 472 476 
    327 153 278 99 483 115 143 407 205 344 498 316 132 8 190 181 113 160 317 410 48 60 105 127 239 250 400 70 213 377 
    154 474 319 322 495 44 397 62 313 411 393 164 496 111 51 291 429 172 470 168 54 157 225 208 20 328 417 106 324 135 
    489 240 326 64 265 404 450 318 98 444 237 308 104 352 155 438 396 152 293 25 371 68 408 432 112 301 73 11 128 354 
    251 254 87 434 247 34 332 252 192 258 323 412 341 12 385 45 65 228 357 466 281 49 194 284 137 406 372 485 454 123 
    36 169 209 41 140 353 299 375 402 320 121 459 457 138 75 421 144 274 339 93 207 197 82 61 200 287 364 102 266 50 
    260 343 373 81 456 198 202 173 388 85 282 23 290 386 333 446 424 189 462 95 468 286 335 361 295 321 368 186 413 101
    67 131 89 79 439 481 122 118 387 139 27 18 395 52 423 405 381 336 184 414 3 428 119 309 493 453 161 306 15 464 248 
    109 21 365 376 32 19 272 201 238 159 337 304 277
输入
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 
 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 
 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 
 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 
 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 
 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 
 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 
 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 
 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 
 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 
 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 
 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 
 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 
 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 
 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 
 494 495 496 497 498 499 500 

插入排序

题目简介

过程图

在这里插入图片描述

思路

插入排序的思想:
把某个位置上的的数值,插入到它最合适的位置

说老实话,给我的感官非常像冒泡排序

题目代码

#include<iostream>

using namespace std;

const int N=1e5;
int n;
int a[N];

void insertSort()
{
    for(int i=0;i<n-1;i++)
        for(int j=i+1;j;j--)
            if(a[j]<a[j-1])swap(a[j],a[j-1]);
            else break;
}

int main()
{
    cin>>n;
    
    for(int i=0;i<n;i++)cin>>a[i];
    
    insertSort();
    
    for(int i=0;i<n;i++)cout<<a[i];
    
    return 0;
}

测试数据

500 
    218 97 78 13 7 259 14 90 86 460 72 134 458 2 245 490 126 33 355 171 166 433 16 74 436 167 5 296 350 148 146 279 230 467
    182 31 315 77 151 442 253 224 156 325 379 183 30 47 129 124 441 497 314 193 390 463 80 362 461 280 383 185 415 179 174
    234 214 1 199 244 249 398 473 136 394 349 369 63 83 356 440 363 219 484 330 425 465 176 125 269 289 312 162 451 480
    100 342 418 243 177 149 10 422 42 478 338 141 367 346 271 221 283 114 443 216 145 235 220 380 204 147 24 307 285 403
    175 256 477 305 165 416 420 255 227 211 427 370 223 195 9 69 264 35 17 38 384 56 329 300 246 178 203 39 471 55 46 
    103 263 455 231 487 445 188 268 482 58 294 257 449 391 500 392 479 261 492 96 267 88 116 494 206 43 262 71 180 120 
    142 351 29 340 130 310 57 431 226 276 6 437 187 447 270 345 66 374 210 133 348 215 242 419 469 435 37 331 84 59 28 
    117 430 426 488 222 399 452 448 273 158 150 170 40 110 217 229 232 76 303 382 241 275 108 366 409 499 26 311 302 
    486 91 347 334 94 358 491 196 107 360 401 292 191 4 297 475 378 298 236 389 22 359 233 163 212 92 53 288 472 476 
    327 153 278 99 483 115 143 407 205 344 498 316 132 8 190 181 113 160 317 410 48 60 105 127 239 250 400 70 213 377 
    154 474 319 322 495 44 397 62 313 411 393 164 496 111 51 291 429 172 470 168 54 157 225 208 20 328 417 106 324 135 
    489 240 326 64 265 404 450 318 98 444 237 308 104 352 155 438 396 152 293 25 371 68 408 432 112 301 73 11 128 354 
    251 254 87 434 247 34 332 252 192 258 323 412 341 12 385 45 65 228 357 466 281 49 194 284 137 406 372 485 454 123 
    36 169 209 41 140 353 299 375 402 320 121 459 457 138 75 421 144 274 339 93 207 197 82 61 200 287 364 102 266 50 
    260 343 373 81 456 198 202 173 388 85 282 23 290 386 333 446 424 189 462 95 468 286 335 361 295 321 368 186 413 101
    67 131 89 79 439 481 122 118 387 139 27 18 395 52 423 405 381 336 184 414 3 428 119 309 493 453 161 306 15 464 248 
    109 21 365 376 32 19 272 201 238 159 337 304 277

输出

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646
566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
477478479480481482483484485486487488489490491492493494495496497498499500

快速排序

来源:模板题

算法标签:分治,快速排序

题目描述:785. 快速排序

给定你一个长度为n的整数数列。

请你使用快速排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。

输入格式

输入共两行,第一行包含整数 n。

第二行包含 n 个整数(所有整数均在1~109范围内),表示整个数列。

输出格式

输出共一行,包含 n 个整数,表示排好序的数列。

数据范围

1≤n≤100000

输入样例:

5
3 1 2 4 5

输出样例:

1 2 3 4 5

题目思路

1.设立中间值为标记值
2.左右两个指针往中间走,
2.1.如果左边指针走到了的值大于标记值,停止
2.2.如果右边指针走到了的值小于标记值,停止
3.交换两个值
4.知道指针重合或者越界停止
5.确保此时左半部分小于标记值,右半部分大于标记值
6.分治递归

题目代码

#include<iostream>
#include<cstring>

using namespace std;
const int N=1E5+10;

void swap(int &a,int &b){a^=b^=a^=b;}//交换

void quick_sort(int a[],int l,int r)//快排 a数组 l左指针 r右指针
{
    if(l==r)return;//退出
    
    int i=l-1,j=r+1,x=a[l+r>>1];//因为下面是dowhile所以i,j是两边的值,a[l+r>>1]取中间值为标记值
    
    while(i<j)//ij未重合
    {
        do i++;while(a[i]<x);//找到左半部分大于标记值的值
        do j--;while(a[j]>x);//找到右半部分小于标记值的值
        if(i<j)swap(a[i],a[j]);//交换
    }
    
    quick_sort(a,l,j),quick_sort(a,j+1,r);//分治递归
}

int main()
{
    int n;
    cin>>n;
    
    int a[N];
    memset(a,0,sizeof a);
    for(int i=0;i<n;i++)cin>>a[i];
    
    quick_sort(a,0,n-1);
     
    for(int i=0;i<n;i++)cout<<a[i]<<" ";
    
    return 0;
}

选择排序

思路

有n个数,乱序。
第一次,遍历找到最小数字,与第一个交换。
第二次,从第二个数字出发,遍历找到最小数字,与第二个交换。
第三次,从第三个数字出发,遍历找到最小数字,与第三个交换。

直到用来记录出发位置的数字(begin)累加到等于数组长度(n-1),完成。

时间复杂度

o(n^2)

核心代码

void selectsort(int a[],int n,int begin)//a[]数组,n数组长度,begin出发位置
{
    if(begin==n-1)return;//出发位置的数字(begin)累加到等于数组长度(n-1),完成,退出
    
    int u=begin,minn=a[begin];//记录出发位置和最小值
    
    for(int i=begin+1;i<n;i++)
        if(minn>a[i])minn=a[i],u=i;//从出发位置+1开始找最小值与最小值的位置,持续更新
    
    if(begin!=u)swap(&a[u],&a[begin]);//出发位置不等于最小值位置时,交换出发位置的数字与最小值的数字
    
    selectsort(a,n,begin+1);//递归到下一个位置开始
}

方便拿的完整代码

#include<iostream>

using namespace std;

void swap(double *p, double *q) { double t = *p; *p = *q; *q = t; }

void selectsort(int a[],int n,int begin)
{
    if(begin==n-1)return;
    
    int u=begin,minn=a[begin];
    
    for(int i=begin+1;i<n;i++)
        if(minn>a[i])minn=a[i],u=i;
    
    if(begin!=u)swap(&a[u],&a[begin]);
    
    selectsort(a,n,begin+1);
}

int main()
{
	double a[1000];
	int n;
	cin >> n;

	for (int i = 0; i < n; i++)cin >> a[i];


	selectsort(a, n, 0);
	for (int i = 0; i < n; i++)cout<< a[i]<<" ";

	return 0;
}

测试

输入
500 
    218 97 78 13 7 259 14 90 86 460 72 134 458 2 245 490 126 33 355 171 166 433 16 74 436 167 5 296 350 148 146 279 230 467
    182 31 315 77 151 442 253 224 156 325 379 183 30 47 129 124 441 497 314 193 390 463 80 362 461 280 383 185 415 179 174
    234 214 1 199 244 249 398 473 136 394 349 369 63 83 356 440 363 219 484 330 425 465 176 125 269 289 312 162 451 480
    100 342 418 243 177 149 10 422 42 478 338 141 367 346 271 221 283 114 443 216 145 235 220 380 204 147 24 307 285 403
    175 256 477 305 165 416 420 255 227 211 427 370 223 195 9 69 264 35 17 38 384 56 329 300 246 178 203 39 471 55 46 
    103 263 455 231 487 445 188 268 482 58 294 257 449 391 500 392 479 261 492 96 267 88 116 494 206 43 262 71 180 120 
    142 351 29 340 130 310 57 431 226 276 6 437 187 447 270 345 66 374 210 133 348 215 242 419 469 435 37 331 84 59 28 
    117 430 426 488 222 399 452 448 273 158 150 170 40 110 217 229 232 76 303 382 241 275 108 366 409 499 26 311 302 
    486 91 347 334 94 358 491 196 107 360 401 292 191 4 297 475 378 298 236 389 22 359 233 163 212 92 53 288 472 476 
    327 153 278 99 483 115 143 407 205 344 498 316 132 8 190 181 113 160 317 410 48 60 105 127 239 250 400 70 213 377 
    154 474 319 322 495 44 397 62 313 411 393 164 496 111 51 291 429 172 470 168 54 157 225 208 20 328 417 106 324 135 
    489 240 326 64 265 404 450 318 98 444 237 308 104 352 155 438 396 152 293 25 371 68 408 432 112 301 73 11 128 354 
    251 254 87 434 247 34 332 252 192 258 323 412 341 12 385 45 65 228 357 466 281 49 194 284 137 406 372 485 454 123 
    36 169 209 41 140 353 299 375 402 320 121 459 457 138 75 421 144 274 339 93 207 197 82 61 200 287 364 102 266 50 
    260 343 373 81 456 198 202 173 388 85 282 23 290 386 333 446 424 189 462 95 468 286 335 361 295 321 368 186 413 101
    67 131 89 79 439 481 122 118 387 139 27 18 395 52 423 405 381 336 184 414 3 428 119 309 493 453 161 306 15 464 248 
    109 21 365 376 32 19 272 201 238 159 337 304 277
输入
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 
 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 
 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 
 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 
 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 
 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 
 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 
 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 
 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 
 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 
 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 
 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 
 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 
 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 
 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 
 494 495 496 497 498 499 500 

归并排序

图示

在这里插入图片描述

时间复杂度

n(nlog2^n)

思路

持续递归将数组拆分为大小为1的块。
1.每两个大小为1的块相互比较比较数值大小,数值小的块内元素放入到临时数组TMP,循环直到某个块内元素都被循环完毕,此时另一个块内元素全部放入临时数组TMP,到此时两个块内元素都被放入临时数组TMP,TMP内为顺序递增,复制到a[]数组的l,r制定区间内部,使得a[l.r]为顺序递增,回溯到上一层。
2.每两个大小为2的块相互比较比较数值大小,数值小的块内元素放入到临时数组TMP,循环直到某个块内元素都被循环完毕,此时另一个块内元素全部放入临时数组TMP,到此时两个块内元素都被放入临时数组TMP,TMP内为顺序递增,复制到a[]数组的l,r制定区间内部,使得a[l.r]为顺序递增,回溯到上一层。
3.每两个大小为4的块相互比较比较数值大小,数值小的块内元素放入到临时数组TMP,循环直到某个块内元素都被循环完毕,此时另一个块内元素全部放入临时数组TMP,到此时两个块内元素都被放入临时数组TMP,TMP内为顺序递增,复制到a[]数组的l,r制定区间内部,使得a[l.r]为顺序递增,回溯到上一层。

直到所有元素都被检查一遍,完成

核心代码

void merge_sort(int a[],int t[],int l,int r)
{
    if(l>=r)return;//l,r指向统一个元素,或者l>r,退出条件
    
    int mid=l+r>>1;//指向了中间
    merge_sort(a,t,l,mid),merge_sort(a,t,mid+1,r);//分治递归
    
    int i=l,j=mid+1,n=0;//划分为a[l,mid],b[mid+1,r]两个部分
    while(i<=mid&&j<=r)//两个数组中同位比对,最小的数字读入到临时数组t
        if(a[i]<=a[j])t[n++]=a[i++];
        else t[n++]=a[j++];
    
    while(i<=mid)t[n++]=a[i++];//当一个数组被排完,直接读入另一个数组
    while(j<=r)t[n++]=a[j++];
    
    for(int i=0,j=l;j<=r;i++,j++)a[j]=t[i];//放入a[]数组制定的a[l,r]区域内
}

方便拿的完整代码

#include<iostream>

using namespace std;
const int N=1e5+10;
int a[N],t[N];

void merge_sort(int a[],int t[],int l,int r)
{
    if(l>=r)return;
    
    int mid=l+r>>1;
    merge_sort(a,t,l,mid),merge_sort(a,t,mid+1,r);
    
    int i=l,j=mid+1,n=0;
    while(i<=mid&&j<=r)
        if(a[i]<=a[j])t[n++]=a[i++];
        else t[n++]=a[j++];
    
    while(i<=mid)t[n++]=a[i++];
    while(j<=r)t[n++]=a[j++];
    
    for(int i=0,j=l;j<=r;i++,j++)a[j]=t[i];
}

int main()
{
    int n;
    cin>>n;
    
    for(int i=0;i<n;i++)cin>>a[i];
    
    merge_sort(a,t,0,n-1);
    
    for(int i=0;i<n;i++)cout<<a[i]<<" ";
    
    return 0;
}

测试

输入
500 
    218 97 78 13 7 259 14 90 86 460 72 134 458 2 245 490 126 33 355 171 166 433 16 74 436 167 5 296 350 148 146 279 230 467
    182 31 315 77 151 442 253 224 156 325 379 183 30 47 129 124 441 497 314 193 390 463 80 362 461 280 383 185 415 179 174
    234 214 1 199 244 249 398 473 136 394 349 369 63 83 356 440 363 219 484 330 425 465 176 125 269 289 312 162 451 480
    100 342 418 243 177 149 10 422 42 478 338 141 367 346 271 221 283 114 443 216 145 235 220 380 204 147 24 307 285 403
    175 256 477 305 165 416 420 255 227 211 427 370 223 195 9 69 264 35 17 38 384 56 329 300 246 178 203 39 471 55 46 
    103 263 455 231 487 445 188 268 482 58 294 257 449 391 500 392 479 261 492 96 267 88 116 494 206 43 262 71 180 120 
    142 351 29 340 130 310 57 431 226 276 6 437 187 447 270 345 66 374 210 133 348 215 242 419 469 435 37 331 84 59 28 
    117 430 426 488 222 399 452 448 273 158 150 170 40 110 217 229 232 76 303 382 241 275 108 366 409 499 26 311 302 
    486 91 347 334 94 358 491 196 107 360 401 292 191 4 297 475 378 298 236 389 22 359 233 163 212 92 53 288 472 476 
    327 153 278 99 483 115 143 407 205 344 498 316 132 8 190 181 113 160 317 410 48 60 105 127 239 250 400 70 213 377 
    154 474 319 322 495 44 397 62 313 411 393 164 496 111 51 291 429 172 470 168 54 157 225 208 20 328 417 106 324 135 
    489 240 326 64 265 404 450 318 98 444 237 308 104 352 155 438 396 152 293 25 371 68 408 432 112 301 73 11 128 354 
    251 254 87 434 247 34 332 252 192 258 323 412 341 12 385 45 65 228 357 466 281 49 194 284 137 406 372 485 454 123 
    36 169 209 41 140 353 299 375 402 320 121 459 457 138 75 421 144 274 339 93 207 197 82 61 200 287 364 102 266 50 
    260 343 373 81 456 198 202 173 388 85 282 23 290 386 333 446 424 189 462 95 468 286 335 361 295 321 368 186 413 101
    67 131 89 79 439 481 122 118 387 139 27 18 395 52 423 405 381 336 184 414 3 428 119 309 493 453 161 306 15 464 248 
    109 21 365 376 32 19 272 201 238 159 337 304 277
输入
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 
 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 
 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 
 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 
 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 
 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 
 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 
 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 
 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 
 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 
 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 
 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 
 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 
 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 
 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 
 494 495 496 497 498 499 500 

堆排序

来源: 模板题
算法标签:堆排序,堆
题目描述

输入一个长度为n的整数数列,从小到大输出前m小的数。

输入格式

第一行包含整数n和m。

第二行包含n个整数,表示整数数列。

输出格式

共一行,包含m个整数,表示整数数列中前m小的数。

数据范围

1≤m≤n≤105,
1≤数列中元素≤109

输入样例:

5 3
4 5 1 3 2

输出样例:

1 2 3

堆的基本操作
1.插入一个数字
2.求集合中最小值
3.删除最小值
4.删除任意一个元素
5.修改任意一个元素

思路

我们先理解堆的思路
形如叶子节点不可不满的完全二叉树
如图:
在这里插入图片描述

现在我们来针对这道题书写一下思路
如图:
在这里插入图片描述
1.建堆
2.利用小根堆和down操作m次输出a[1] (堆最小值)

AC代码

#include<iostream>

using namespace std;

const int N=1e5+10;
int a[N];
int n,m;

void down(int u)
{
    int t=u;//新指针,指向子节点
    if(2*u<=n&&a[2*u]<a[t])t=2*u;//左子节点判断
    if(2*u+1<=n&&a[2*u+1]<a[t])t=2*u+1;//右子节点判断 这里不直接交换的原因是 左右两次指向判断直接将t指向了左右子节点中最小的值
    if(t!=u)swap(a[u],a[t]),down(t);//如果确实小于,就交换位子,并递归子节点
}
int main()
{
    cin>>n>>m;
    
    for(int i=1;i<=n;i++)cin>>a[i];
    
    for(int i=n/2;i;i--)down(i);//将所有子节点的节点放导合适位子
    
    while(m--)
    {
        cout<<a[1]<<" ";//输出a[1]
        a[1]=a[n--];//因为a[1]输出过了,此时我们要删除a[1],a[1]被a[n]覆盖,a长度--
        down(1);//将放导a[1]的原a[n]排序到合适位子
    }
    
    return 0;
}
posted @   俺叫西西弗斯  阅读(0)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示