排序算法(冒泡排序,選擇排序,插入排序,快速排序)
阿新 • • 發佈:2018-04-27
str div cell dex clas 基準 exchange quick partition
數組的排序算法
選擇排序
每次選擇所要排序得數組中的最大值(由大到小排序,由小到大排序則選擇最小值)的數組元素,將這個數組元組的值與最前面沒有排序的數組元素進行交換,
第一次排序之後,最大的數字來到了第一位,再從第二個元素開始找,找到最大的元素,與第二個交換位置
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 |
#include <stdio.h>
int main( int argc, char *argv[]) {
int i,j;
int a[10];
int temp;
int index;
printf( "為數組元素賦值\n" );
for (i=0;i<10;i++){
printf( "a[%d]=" ,i);
scanf( "%d" ,&a[i]);
}
for (i=0;i<9;i++){ //外層循環0~8這9個元素
temp=a[i]; //假設最大值
index=i; // 記錄假設最大值索引
for (j=i+1;j<10;j++){ // 內層循環,排序後的元素 if (a[j]>temp){ //取最大值
temp=a[j]; //重置最大值
index=j; //重置最大值索引
}
}
// 交換元素位置
a[index]=a[i];
a[i]=temp;
}
// 輸出數組
for (i=0;i<10;i++){
printf( "%d\t" ,a[i]);
if (i==4){ //輸出換行
printf( "\n" );
}
}
return 0;
}
|
python做選擇排序
1 2 3 4 5 6 7 8 9 |
# 掃描無序區,從無序區中找出一個極端值,放入有序區
def select_sort(li): # 選擇
for i in range ( len (li) - 1 ): # i表示第幾次,有多少元素我就要掃幾-1次
# 找無序區最小值,保存最小值的位置
min_pos = i # 假設起始值最小,min_pos保存最小值的索引
for j in range (i + 1 , len (li)): # 第i趟開始時 無序區:li[i:],自己不與自己比較,所以i+1
if li[j] < li[min_pos]: # 滿足條件,我存的值比後面的值大,則把後面的值的所以設置為最小值索引
min_pos = j
li[min_pos], li[i] = li[i], li[min_pos] # 交換兩個值的位置
|
冒泡排序
每次比較相鄰的兩個數,將最小的數(從小到大排序)排在較大的數前面.
經過一次排序之後最小的數到達了最前面的位置,並將其他的數字依次向後移動,第二次排序時,將從第二個數開始最小的數移動到第二的位置,依次類推
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 |
#include <stdio.h>
int main( int argc, char *argv[])
{
int i,j;
int a[10];
int temp;
printf( "為數組元素賦值\n" );
for (i=0;i<10;i++){
printf( "a[%d]=" ,i);
scanf( "%d" ,&a[i]);
}
for (i=1;i<10;i++){ //外層循環1~9這9個元素
for (j=9;j>=i;j--){ //從後向前循環i後面的元素
if (a[j]<a[j-1]){ //前面的數大於後面的數,交換
temp=a[j-1];
a[j-1]=a[j];
a[j]=temp;
}
}
}
// 輸出數組
for (i=0;i<10;i++){
printf( "%d\t" ,a[i]);
if (i==4){ //輸出換行
printf( "\n" );
}
}
return 0;
}
|
python做冒泡排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 冒泡排序,一遍遍掃描未歸位區,比較相鄰的兩個數字,滿足條件則交換,每次使一個元素歸位
def bubble_sort(li): # 冒泡
for i in range ( len (li) - 1 ): # i表示第幾次,有多少元素我就要掃幾-1次
for j in range ( len (li) - i - 1 ): # 比較元素的位置,len(li)-1-i是未歸位區的最大索引
if li[j] > li[j + 1 ]: # 滿足條件 將兩個數值交換,這裏是前面比後面大
li[j], li[j + 1 ] = li[j + 1 ], li[j]
def bubble_sort_1(li): # 優化冒泡
for i in range ( len (li) - 1 ): # i表示第幾次,有多少元素我就要掃幾次
exchange = False # 增加了一個標誌位,如果依次循環中沒有發生交換,則順序已經是有序的了,可以直接退出
for j in range ( len (li) - i - 1 ): # 比較元素的位置,len(li)-1-i是未歸位區的最大索引
if li[j] > li[j + 1 ]:
li[j], li[j + 1 ] = li[j + 1 ], li[j]
exchange = True
if not exchange:
return
|
插入排序
插入排序就像是摸撲克,第一張算是有序區,從後面的無序區拿撲克向有序區中插
python
1 2 3 4 5 6 7 8 9 10 |
def insert_sort(li): # 插入
for i in range ( 1 , len (li)): # i是摸到的牌的下標,第一個屬於有序區,所以從第二個開始
tmp = li[i] # 手裏牌的大小
j = i - 1 # j是手裏最後一張牌的下標
# 如果tmp大於我手裏第j個元素,他就應該放在第j個位置上,如果小於就繼續向前比較
while j > = 0 and li[j] > tmp: # 兩個終止條件:j小於0表示tmp是最小的 順序不要亂
# 因為保存了i索引位置的值,所以大於tmp的數都向後移動一位,j自減
li[j + 1 ] = li[j]
j - = 1
li[j + 1 ] = tmp
|
快速排序
快排采用的遞歸的思路
是以一個數字為基準(第0個元素),將列表分為大於他的和小於他的兩部分,遞歸進行直至列表少於一個元素
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 |
def partition(li, left, right): # 歸位
# randi = random.randint(left, right)
# li[randi], li[left] = li[left], li[randi]
‘‘‘
將一個列表分成左右兩部分
:param li: 列表
:param left: 開始索引
:param right: 結束索引
:return: 返回中間索引
‘‘‘
tmp = li[left] # 取最左邊的值,作為中間值
while left < right: # 左索引一定要小於右索引,
while left < right and li[right] > = tmp:
# 從後向前找一個小於tmp的元素,找不到就將索引-1向前找
# = tmp可以使right的值是tmp左邊的索引
right - = 1
li[left] = li[right] # 找到之後放到最左邊 ,此時right位置的值有兩個,
while left < right and li[left] < = tmp:
# 在從前往後找一個比tmp大的,找不到就將索引+1向後找
# = tmp可以使right的值是tmp右邊的索引
left + = 1
li[right] = li[left] # 找到之後放到right位置,
# 當左右索引位置重合時循環結束
li[left] = tmp
return left
def _quick_sort(li, left, right): # 遞歸
if left < right: # 至少兩個元素
mid = partition(li, left, right) # 取中間索引,將兩面進行遞歸
_quick_sort(li, left, mid - 1 )
_quick_sort(li, mid + 1 , right)
|
歸位圖解
分類: 算法
排序算法(冒泡排序,選擇排序,插入排序,快速排序)